diff options
1079 files changed, 59464 insertions, 29898 deletions
diff --git a/.clang-format b/.clang-format index f7527b8927..1df6c35bfb 100644 --- a/.clang-format +++ b/.clang-format @@ -19,7 +19,7 @@ AllowAllParametersOfDeclarationOnNextLine: false # AllowShortEnumsOnASingleLine: true # AllowShortBlocksOnASingleLine: Never # AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: Inline +# AllowShortFunctionsOnASingleLine: All # AllowShortLambdasOnASingleLine: All # AllowShortIfStatementsOnASingleLine: Never # AllowShortLoopsOnASingleLine: false diff --git a/.gitattributes b/.gitattributes index 45ea6c25e8..8d2fb108ba 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,6 +7,8 @@ thirdparty/* linguist-vendored * text=auto eol=lf # Except for bat files, which are Windows only files *.bat eol=crlf +# And some test files where the EOL matters +*.test.txt -text # The above only works properly for Git 2.10+, so for older versions # we need to manually list the binary files we don't want modified. diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 56c41aa749..0a0160326c 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -19,30 +19,15 @@ jobs: fail-fast: false matrix: include: -# Temporarily disabled until Mono is fixed -# -# - name: Editor w Mono (target=release_debug, tools=yes, tests=yes) -# cache-name: linux-editor-mono -# target: release_debug -# tools: true -# tests: false # Disabled due freeze caused by mix Mono build and CI -# sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no -# doc-test: true -# bin: "./bin/godot.linuxbsd.opt.tools.64.mono" -# build-mono: true -# proj-conv: true -# artifact: true - -# Temporary replacement: - - - name: Editor w/o Mono (target=release_debug, tools=yes, tests=yes) + - name: Editor w Mono (target=release_debug, tools=yes, tests=yes) cache-name: linux-editor-mono target: release_debug tools: true tests: false # Disabled due freeze caused by mix Mono build and CI + sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no doc-test: true - bin: "./bin/godot.linuxbsd.opt.tools.64" - build-mono: false + bin: "./bin/godot.linuxbsd.opt.tools.64.mono" + build-mono: true proj-conv: true artifact: true @@ -72,24 +57,12 @@ jobs: # Skip 2GiB artifact speeding up action. artifact: false -# Temporarily disabled: -# -# - name: Template w/ Mono (target=release, tools=no) -# cache-name: linux-template-mono -# target: release -# tools: false -# tests: false -# sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no debug_symbols=no -# build-mono: false -# artifact: true - -# Temporary replacement: - - - name: Template w/o Mono (target=release, tools=no) + - name: Template w/ Mono (target=release, tools=no) cache-name: linux-template-mono target: release tools: false tests: false + sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no debug_symbols=no build-mono: false artifact: true @@ -115,7 +88,7 @@ jobs: sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \ libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev \ libdbus-1-dev libudev-dev libxi-dev libxrandr-dev yasm xvfb wget unzip \ - llvm libspeechd-dev speech-dispatcher + llvm libspeechd-dev speech-dispatcher fontconfig libfontconfig-dev - name: Setup Godot build cache uses: ./.github/actions/godot-cache @@ -197,12 +170,18 @@ jobs: mv "regression-test-project-4.0" "test_project" # Editor is quite complicated piece of software, so it is easy to introduce bug here - - name: Open and close editor + - name: Open and close editor (Vulkan) if: ${{ matrix.proj-test }} run: | VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --audio-driver Dummy --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true misc/scripts/check_ci_log.py sanitizers_log.txt + - name: Open and close editor (GLES3) + if: ${{ matrix.proj-test }} + run: | + DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --audio-driver Dummy --rendering-driver opengl3 --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true + misc/scripts/check_ci_log.py sanitizers_log.txt + # Run test project - name: Run project if: ${{ matrix.proj-test }} @@ -246,6 +225,7 @@ jobs: if: ${{ matrix.artifact }} run: | strip bin/godot.* + chmod +x bin/godot.* - name: Upload artifact uses: ./.github/actions/upload-artifact diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index 0cb037bfae..0ad0995bb7 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -5,7 +5,7 @@ on: [push, pull_request] env: # Only used for the cache key. Increment version to force clean build. GODOT_BASE_BRANCH: master-v3 - SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes use_volk=yes + SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes concurrency: group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-macos @@ -45,6 +45,10 @@ jobs: - name: Setup python and scons uses: ./.github/actions/godot-deps + - name: Setup Vulkan SDK + run: | + sh misc/scripts/install_vulkan_sdk_macos.sh + - name: Compilation uses: ./.github/actions/godot-build with: @@ -65,6 +69,7 @@ jobs: - name: Prepare artifact run: | strip bin/godot.* + chmod +x bin/godot.* - name: Upload artifact uses: ./.github/actions/upload-artifact diff --git a/SConstruct b/SConstruct index 0fd9326e1c..d0d03bd8dc 100644 --- a/SConstruct +++ b/SConstruct @@ -138,6 +138,7 @@ env_base.__class__.CommandNoCache = methods.CommandNoCache env_base.__class__.Run = methods.Run env_base.__class__.disable_warnings = methods.disable_warnings env_base.__class__.force_optimization_on_debug = methods.force_optimization_on_debug +env_base.__class__.module_add_dependencies = methods.module_add_dependencies env_base.__class__.module_check_dependencies = methods.module_check_dependencies env_base["x86_libtheora_opt_gcc"] = False @@ -337,21 +338,27 @@ for path in module_search_paths: # Add module options. for name, path in modules_detected.items(): + sys.path.insert(0, path) + import config + if env_base["modules_enabled_by_default"]: enabled = True - - sys.path.insert(0, path) - import config - try: enabled = config.is_enabled() except AttributeError: pass - sys.path.remove(path) - sys.modules.pop("config") else: enabled = False + # Add module-specific options. + try: + for opt in config.get_opts(selected_platform): + opts.Add(opt) + except AttributeError: + pass + + sys.path.remove(path) + sys.modules.pop("config") opts.Add(BoolVariable("module_" + name + "_enabled", "Enable module '%s'" % (name,), enabled)) methods.write_modules(modules_detected) @@ -699,6 +706,7 @@ if selected_platform in platform_list: sys.modules.pop("detect") modules_enabled = OrderedDict() + env.module_dependencies = {} env.module_icons_paths = [] env.doc_class_path = {} @@ -710,6 +718,10 @@ if selected_platform in platform_list: import config if config.can_build(env, selected_platform): + # Disable it if a required dependency is missing. + if not env.module_check_dependencies(name): + continue + config.configure(env) # Get doc classes paths (if present) try: @@ -732,6 +744,7 @@ if selected_platform in platform_list: sys.modules.pop("config") env.module_list = modules_enabled + methods.sort_module_list(env) methods.update_version(env.module_version_string) @@ -794,15 +807,6 @@ if selected_platform in platform_list: if env["minizip"]: env.Append(CPPDEFINES=["MINIZIP_ENABLED"]) - editor_module_list = [] - if env["tools"] and not env.module_check_dependencies("tools", editor_module_list): - print( - "Build option 'module_" - + x - + "_enabled=no' cannot be used with 'tools=yes' (editor), only with 'tools=no' (export template)." - ) - Exit(255) - if not env["verbose"]: methods.no_verbose(sys, env) diff --git a/core/SCsub b/core/SCsub index 97080b8710..d4462fa546 100644 --- a/core/SCsub +++ b/core/SCsub @@ -188,7 +188,6 @@ SConscript("os/SCsub") SConscript("math/SCsub") SConscript("crypto/SCsub") SConscript("io/SCsub") -SConscript("multiplayer/SCsub") SConscript("debugger/SCsub") SConscript("input/SCsub") SConscript("variant/SCsub") diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 782d369ae6..1a6093869f 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -194,11 +194,11 @@ bool Engine::is_validation_layers_enabled() const { } void Engine::set_print_error_messages(bool p_enabled) { - _print_error_enabled = p_enabled; + CoreGlobals::print_error_enabled = p_enabled; } bool Engine::is_printing_error_messages() const { - return _print_error_enabled; + return CoreGlobals::print_error_enabled; } void Engine::add_singleton(const Singleton &p_singleton) { @@ -246,6 +246,14 @@ void Engine::get_singletons(List<Singleton> *p_singletons) { } } +String Engine::get_write_movie_path() const { + return write_movie_path; +} + +void Engine::set_write_movie_path(const String &p_path) { + write_movie_path = p_path; +} + void Engine::set_shader_cache_path(const String &p_path) { shader_cache_path = p_path; } diff --git a/core/config/engine.h b/core/config/engine.h index 82e3ee5487..68562643e7 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -76,6 +76,7 @@ private: static Engine *singleton; + String write_movie_path; String shader_cache_path; public: @@ -138,6 +139,9 @@ public: Dictionary get_license_info() const; String get_license_text() const; + void set_write_movie_path(const String &p_path); + String get_write_movie_path() const; + void set_shader_cache_path(const String &p_path); String get_shader_cache_path() const; diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 38db7f9190..5c4bcc687a 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1198,6 +1198,9 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("display/window/size/window_height_override", 0); custom_prop_info["display/window/size/window_height_override"] = PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"); // 8K resolution + GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true); + GLOBAL_DEF("display/window/energy_saving/keep_screen_on.editor", false); + GLOBAL_DEF_BASIC("audio/buses/default_bus_layout", "res://default_bus_layout.tres"); custom_prop_info["audio/buses/default_bus_layout"] = PropertyInfo(Variant::STRING, "audio/buses/default_bus_layout", PROPERTY_HINT_FILE, "*.tres"); GLOBAL_DEF_RST("audio/general/2d_panning_strength", 1.0f); diff --git a/core/core_bind.cpp b/core/core_bind.cpp index cb57cd7057..56130134a0 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -46,8 +46,8 @@ namespace core_bind { 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); +Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, CacheMode p_cache_mode) { + return ::ResourceLoader::load_threaded_request(p_path, p_type_hint, p_use_sub_threads, ResourceFormatLoader::CacheMode(p_cache_mode)); } ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const String &p_path, Array r_progress) { @@ -121,7 +121,7 @@ ResourceUID::ID ResourceLoader::get_resource_uid(const String &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_request", "path", "type_hint", "use_sub_threads", "cache_mode"), &ResourceLoader::load_threaded_request, DEFVAL(""), DEFVAL(false), DEFVAL(CACHE_MODE_REUSE)); 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); @@ -147,9 +147,9 @@ void ResourceLoader::_bind_methods() { ////// ResourceSaver ////// -Error ResourceSaver::save(const String &p_path, const Ref<Resource> &p_resource, BitField<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); +Error ResourceSaver::save(const Ref<Resource> &p_resource, const String &p_path, BitField<SaverFlags> p_flags) { + ERR_FAIL_COND_V_MSG(p_resource.is_null(), ERR_INVALID_PARAMETER, "Can't save empty resource to path '" + p_path + "'."); + return ::ResourceSaver::save(p_resource, p_path, p_flags); } Vector<String> ResourceSaver::get_recognized_extensions(const Ref<Resource> &p_resource) { @@ -174,7 +174,7 @@ void ResourceSaver::remove_resource_format_saver(Ref<ResourceFormatSaver> p_form ResourceSaver *ResourceSaver::singleton = nullptr; void ResourceSaver::_bind_methods() { - ClassDB::bind_method(D_METHOD("save", "path", "resource", "flags"), &ResourceSaver::save, DEFVAL((uint32_t)FLAG_NONE)); + ClassDB::bind_method(D_METHOD("save", "resource", "path", "flags"), &ResourceSaver::save, DEFVAL(""), DEFVAL((uint32_t)FLAG_NONE)); ClassDB::bind_method(D_METHOD("get_recognized_extensions", "type"), &ResourceSaver::get_recognized_extensions); ClassDB::bind_method(D_METHOD("add_resource_format_saver", "format_saver", "at_front"), &ResourceSaver::add_resource_format_saver, DEFVAL(false)); ClassDB::bind_method(D_METHOD("remove_resource_format_saver", "format_saver"), &ResourceSaver::remove_resource_format_saver); @@ -231,6 +231,14 @@ void OS::crash(const String &p_message) { CRASH_NOW_MSG(p_message); } +Vector<String> OS::get_system_fonts() const { + return ::OS::get_singleton()->get_system_fonts(); +} + +String OS::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { + return ::OS::get_singleton()->get_system_font_path(p_font_name, p_bold, p_italic); +} + String OS::get_executable_path() const { return ::OS::get_singleton()->get_executable_path(); } @@ -323,6 +331,39 @@ Vector<String> OS::get_cmdline_args() { return cmdlinev; } +Vector<String> OS::get_cmdline_user_args() { + List<String> cmdline = ::OS::get_singleton()->get_cmdline_user_args(); + Vector<String> cmdlinev; + for (const String &E : cmdline) { + cmdlinev.push_back(E); + } + + return cmdlinev; +} + +void OS::set_restart_on_exit(bool p_restart, const Vector<String> &p_restart_arguments) { + List<String> args_list; + for (const String &restart_argument : p_restart_arguments) { + args_list.push_back(restart_argument); + } + + ::OS::get_singleton()->set_restart_on_exit(p_restart, args_list); +} + +bool OS::is_restart_on_exit_set() const { + return ::OS::get_singleton()->is_restart_on_exit_set(); +} + +Vector<String> OS::get_restart_on_exit_arguments() const { + List<String> args = ::OS::get_singleton()->get_restart_on_exit_arguments(); + Vector<String> args_vector; + for (List<String>::Element *E = args.front(); E; E = E->next()) { + args_vector.push_back(E->get()); + } + + return args_vector; +} + String OS::get_locale() const { return ::OS::get_singleton()->get_locale(); } @@ -589,6 +630,8 @@ void OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_processor_count"), &OS::get_processor_count); ClassDB::bind_method(D_METHOD("get_processor_name"), &OS::get_processor_name); + ClassDB::bind_method(D_METHOD("get_system_fonts"), &OS::get_system_fonts); + ClassDB::bind_method(D_METHOD("get_system_font_path", "font_name", "bold", "italic"), &OS::get_system_font_path, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_executable_path"), &OS::get_executable_path); ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr", "open_console"), &OS::execute, DEFVAL(Array()), DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("create_process", "path", "arguments", "open_console"), &OS::create_process, DEFVAL(false)); @@ -604,6 +647,11 @@ void OS::_bind_methods() { 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_cmdline_user_args"), &OS::get_cmdline_user_args); + + ClassDB::bind_method(D_METHOD("set_restart_on_exit", "restart", "arguments"), &OS::set_restart_on_exit, DEFVAL(Vector<String>())); + ClassDB::bind_method(D_METHOD("is_restart_on_exit_set"), &OS::is_restart_on_exit_set); + ClassDB::bind_method(D_METHOD("get_restart_on_exit_arguments"), &OS::get_restart_on_exit_arguments); ClassDB::bind_method(D_METHOD("delay_usec", "usec"), &OS::delay_usec); ClassDB::bind_method(D_METHOD("delay_msec", "msec"), &OS::delay_msec); @@ -885,6 +933,7 @@ Dictionary Geometry2D::make_atlas(const Vector<Size2> &p_rects) { 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_circle", "segment_from", "segment_to", "circle_position", "circle_radius"), &Geometry2D::segment_intersects_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); @@ -1217,13 +1266,13 @@ Vector<uint8_t> File::get_buffer(int64_t p_length) const { return data; } -String File::get_as_text() const { +String File::get_as_text(bool p_skip_cr) const { ERR_FAIL_COND_V_MSG(f.is_null(), String(), "File must be opened before use, or is lacking read-write permission."); uint64_t original_pos = f->get_position(); const_cast<FileAccess *>(*f)->seek(0); - String text = f->get_as_utf8_string(); + String text = f->get_as_utf8_string(p_skip_cr); const_cast<FileAccess *>(*f)->seek(original_pos); @@ -1420,7 +1469,7 @@ void File::_bind_methods() { 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_as_text", "skip_cr"), &File::get_as_text, DEFVAL(false)); 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); @@ -1838,7 +1887,7 @@ void Thread::_start_func(void *ud) { ::Thread::set_name(func_name); Callable::CallError ce; - t->target_callable.call(nullptr, 0, t->ret, ce); + t->target_callable.callp(nullptr, 0, t->ret, ce); if (ce.error != Callable::CallError::CALL_OK) { t->running.clear(); ERR_FAIL_MSG("Could not call function '" + func_name + "' to start thread " + t->get_id() + ": " + Variant::get_callable_error_text(t->target_callable, nullptr, 0, ce) + "."); @@ -2280,6 +2329,10 @@ bool Engine::is_editor_hint() const { return ::Engine::get_singleton()->is_editor_hint(); } +String Engine::get_write_movie_path() const { + return ::Engine::get_singleton()->get_write_movie_path(); +} + void Engine::set_print_error_messages(bool p_enabled) { ::Engine::get_singleton()->set_print_error_messages(p_enabled); } @@ -2329,6 +2382,8 @@ void Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("is_editor_hint"), &Engine::is_editor_hint); + ClassDB::bind_method(D_METHOD("get_write_movie_path"), &Engine::get_write_movie_path); + 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); @@ -2412,7 +2467,7 @@ Error EngineDebugger::call_capture(void *p_user, const String &p_cmd, const Arra const Variant *args[2] = { &cmd, &data }; Variant retval; Callable::CallError err; - capture.call(args, 2, retval, err); + capture.callp(args, 2, retval, err); ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, FAILED, "Error calling 'capture' to callable: " + Variant::get_callable_error_text(capture, args, 2, err)); ERR_FAIL_COND_V_MSG(retval.get_type() != Variant::BOOL, FAILED, "Error calling 'capture' to callable: " + String(capture) + ". Return type is not bool."); r_captured = retval; diff --git a/core/core_bind.h b/core/core_bind.h index c116ac4986..98bf34e07d 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -71,7 +71,7 @@ public: 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); + Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false, CacheMode p_cache_mode = CACHE_MODE_REUSE); ThreadLoadStatus load_threaded_get_status(const String &p_path, Array r_progress = Array()); Ref<Resource> load_threaded_get(const String &p_path); @@ -109,7 +109,7 @@ public: static ResourceSaver *get_singleton() { return singleton; } - Error save(const String &p_path, const Ref<Resource> &p_resource, BitField<SaverFlags> p_flags); + Error save(const Ref<Resource> &p_resource, const String &p_path, BitField<SaverFlags> p_flags); Vector<String> get_recognized_extensions(const Ref<Resource> &p_resource); void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front); void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver); @@ -170,6 +170,8 @@ public: void alert(const String &p_alert, const String &p_title = "ALERT!"); void crash(const String &p_message); + Vector<String> get_system_fonts() const; + String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const; String get_executable_path() const; int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false, bool p_open_console = false); int create_process(const String &p_path, const Vector<String> &p_arguments, bool p_open_console = false); @@ -180,12 +182,17 @@ public: bool is_process_running(int p_pid) const; int get_process_id() const; + void set_restart_on_exit(bool p_restart, const Vector<String> &p_restart_arguments = Vector<String>()); + bool is_restart_on_exit_set() const; + Vector<String> get_restart_on_exit_arguments() const; + bool has_environment(const String &p_var) const; String get_environment(const String &p_var) const; bool set_environment(const String &p_var, const String &p_value) const; String get_name() const; Vector<String> get_cmdline_args(); + Vector<String> get_cmdline_user_args(); String get_locale() const; String get_locale_language() const; @@ -409,7 +416,7 @@ public: Vector<uint8_t> get_buffer(int64_t p_length) const; // Get an array of bytes. String get_line() const; Vector<String> get_csv_line(const String &p_delim = ",") const; - String get_as_text() const; + String get_as_text(bool p_skip_cr = false) const; String get_md5(const String &p_path) const; String get_sha256(const String &p_path) const; @@ -674,6 +681,9 @@ public: void set_editor_hint(bool p_enabled); bool is_editor_hint() const; + // `set_write_movie_path()` is not exposed to the scripting API as changing it at run-time has no effect. + String get_write_movie_path() const; + void set_print_error_messages(bool p_enabled); bool is_printing_error_messages() const; diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 4a2d09d2a0..dc0ab72a86 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -31,7 +31,6 @@ #include "core_constants.h" #include "core/input/input_event.h" -#include "core/multiplayer/multiplayer.h" #include "core/object/class_db.h" #include "core/os/keyboard.h" #include "core/variant/variant.h" @@ -660,15 +659,6 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_OBJECT_CORE); BIND_CORE_ENUM_CONSTANT(METHOD_FLAGS_DEFAULT); - // rpc - BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_DISABLED", Multiplayer::RPC_MODE_DISABLED); - BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_ANY_PEER", Multiplayer::RPC_MODE_ANY_PEER); - BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_AUTHORITY", Multiplayer::RPC_MODE_AUTHORITY); - - BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_UNRELIABLE", Multiplayer::TRANSFER_MODE_UNRELIABLE); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_UNRELIABLE_ORDERED", Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_RELIABLE", Multiplayer::TRANSFER_MODE_RELIABLE); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BOOL", Variant::BOOL); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT", Variant::INT); diff --git a/core/core_globals.cpp b/core/core_globals.cpp new file mode 100644 index 0000000000..45297b459f --- /dev/null +++ b/core/core_globals.cpp @@ -0,0 +1,35 @@ +/*************************************************************************/ +/* core_globals.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "core_globals.h" + +bool CoreGlobals::leak_reporting_enabled = true; +bool CoreGlobals::print_line_enabled = true; +bool CoreGlobals::print_error_enabled = true; diff --git a/core/core_globals.h b/core/core_globals.h new file mode 100644 index 0000000000..c5e614dc0a --- /dev/null +++ b/core/core_globals.h @@ -0,0 +1,44 @@ +/*************************************************************************/ +/* core_globals.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef CORE_GLOBALS_H +#define CORE_GLOBALS_H + +// Home for state needed from global functions +// that cannot be stored in Engine or OS due to e.g. circular includes + +class CoreGlobals { +public: + static bool leak_reporting_enabled; + static bool print_line_enabled; + static bool print_error_enabled; +}; + +#endif // CORE_GLOBALS_H diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index d0fd4feaa5..a164eb7a57 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -185,7 +185,7 @@ String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const return ""; } -Error ResourceFormatSaverCrypto::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverCrypto::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { Error err; Ref<X509Certificate> cert = p_resource; Ref<CryptoKey> key = p_resource; diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index fb4f7dd88f..10c9564ad9 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -125,7 +125,7 @@ public: class ResourceFormatSaverCrypto : public ResourceFormatSaver { public: - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; virtual bool recognize(const Ref<Resource> &p_resource) const; }; diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt index d751f6c9b8..f5874a3dec 100644 --- a/core/input/gamecontrollerdb.txt +++ b/core/input/gamecontrollerdb.txt @@ -11,7 +11,7 @@ 03000000d0160000600a000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows, 03000000c82d00000031000000000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000531000000000000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, -03000000c82d00000951000000000000,8BitDo Dogbone Modkit,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows, +03000000c82d00000951000000000000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightx:a3,righty:a5,start:b11,platform:Windows, 03000000008000000210000000000000,8BitDo F30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 030000003512000011ab000000000000,8BitDo F30 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000c82d00001028000000000000,8BitDo F30 Arcade Joystick,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, @@ -19,14 +19,15 @@ 03000000801000000900000000000000,8BitDo F30 Arcade Stick,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00001038000000000000,8BitDo F30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00001151000000000000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000151000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00005106000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,guide:b2,leftshoulder:b8,lefttrigger:b9,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows, -03000000c82d00000151000000000000,8BitDo M30 Modkit,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000310000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, +03000000c82d00000451000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightx:a3,righty:a5,start:b11,platform:Windows, 03000000c82d00002028000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00008010000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d0000e002000000000000,8BitDo N30,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b6,platform:Windows, -03000000c82d00000451000000000000,8BitDo N30 Modkit,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,start:b11,platform:Windows, 03000000c82d00000190000000000000,8BitDo N30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, @@ -37,7 +38,8 @@ 03000000022000000090000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000203800000900000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00002038000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, -03000000c82d00000751000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Windows, +03000000c82d00000751000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows, +03000000c82d00000851000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000360000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000361000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000660000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, @@ -45,7 +47,7 @@ 03000000c82d00000231000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000331000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000431000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, -03000000c82d00002867000000000000,8BitDo S30 Modkit,a:b0,b:b1,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b8,lefttrigger:b9,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows, +03000000c82d00002867000000000000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a2,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b10,x:b3,y:b4,platform:Windows, 03000000c82d00000130000000000000,8BitDo SF30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000060000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000061000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, @@ -54,11 +56,11 @@ 03000000c82d00003028000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 030000003512000020ab000000000000,8BitDo SN30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000351000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a2,rightshoulder:b7,rightx:a3,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001290000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d000020ab000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00004028000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00006228000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, -03000000c82d00000351000000000000,8BitDo SN30 Modkit,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000021000000000000,8BitDo SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, @@ -120,6 +122,7 @@ 030000006b1400000103000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, 03000000120c0000200e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000210e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000120c0000f10e000000000000,Brook PS2 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000310c000000000000,Brook Super Converter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows, 03000000d81d00000b00000000000000,Buffalo BSGP1601 Series,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows, 030000005b1c00002400000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows, @@ -234,14 +237,14 @@ 030000000d0f00005100000000000000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00008600000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f0000ba00000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000000d0f00008800000000000000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, +030000000d0f00008700000000000000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00001000000000000000,Hori Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00003200000000000000,Hori Fightstick 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000c000000000000000,Hori Fightstick 4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f00000d00000000000000,Hori Fightstick EX2,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 030000000d0f00003701000000000000,Hori Fightstick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Windows, 030000000d0f00004000000000000000,Hori Fightstick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00008700000000000000,Hori Fightstick Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00008800000000000000,Hori Fightstick Mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, 030000000d0f00002100000000000000,Hori Fightstick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00002700000000000000,Hori Fightstick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000a000000000000000,Hori Grip TAC4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b13,x:b0,y:b3,platform:Windows, @@ -439,7 +442,7 @@ 03000000d9040000160f000000000000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 030000004c0500003713000000000000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -0300000062060000d570000000000000,PowerA PS3 Contoller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +0300000062060000d570000000000000,PowerA PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000d620000013a7000000000000,PowerA Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d04000084ca000000000000,Precision,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000d62000009557000000000000,Pro Elite PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, @@ -482,7 +485,6 @@ 03000000120c00001e0e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000a957000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000aa57000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -03000000120c0000f10e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000f21c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000f31c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000f41c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, @@ -538,7 +540,6 @@ 03000000321500000910000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000011000000000000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, -03000000632500008005000000010000,Redgear,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,guide:b12,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X, 03000000921200004547000000000000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b6,x:b3,y:b4,platform:Windows, 03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, 03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows, @@ -741,11 +742,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000008f0e00000300000009010000,2 In 1 Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X, 03000000c82d00000031000001000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00000531000000020000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Mac OS X, 03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00001151000000020000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000a30c00002400000006020000,8BitDo M30,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,guide:b9,leftshoulder:b6,lefttrigger:b5,rightshoulder:b4,righttrigger:b7,start:b8,x:b3,y:b0,platform:Mac OS X, +03000000c82d00000151000000010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00005106000000010000,8BitDo M30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b2,leftshoulder:b6,lefttrigger:a5,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Mac OS X, 03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 030000003512000012ab000001000000,8BitDo NES30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, @@ -754,13 +761,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000022000000090000001000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000190000001000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000660000000020000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000131000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000231000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000331000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000431000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Mac OS X, 03000000102800000900000000000000,8BitDo SFC30 Joystick,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00000351000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00001290000001000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00004028000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, @@ -786,6 +797,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X, 03000000a306000022f6000001030000,Cyborg V3 Rumble Pad PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000791d00000103000009010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X, +030000006e0500000720000010020000,Elecom JC-W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Mac OS X, 030000006f0e00008401000003010000,Faceoff Premiere Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, 03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Mac OS X, @@ -804,6 +816,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000000d0f00005e00000000010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000000d0f00008400000000010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000000d0f00008500000000010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00008800000000010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00008700000000010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, 030000000d0f00004d00000000000000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000000d0f00003801000008010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Mac OS X, 030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, @@ -883,6 +897,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X, 030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X, 0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +03000000632500008005000000010000,Redgear,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X, 030000000d0f0000c100000072050000,Retro Bit Sega Genesis 6B Controller,a:b2,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b8,rightshoulder:b6,righttrigger:b7,start:b9,x:b3,y:b0,platform:Mac OS X, 03000000921200004547000000020000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b2,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,lefttrigger:b14,rightshoulder:b10,righttrigger:b4,start:b12,x:b6,y:b8,platform:Mac OS X, 03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Mac OS X, @@ -954,11 +969,16 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, # Linux 030000005e0400008e02000020010000,8BitDo Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, 03000000021000000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000151000000010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00000650000011010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Linux, 05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, 03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, @@ -968,12 +988,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000131000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000231000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000331000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000431000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Linux, 05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 030000003512000012ab000010010000,8BitDo SFC30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux, @@ -981,6 +1004,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 05000000102800000900000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00003028000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000351000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, @@ -1075,9 +1099,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000000d0f00005001000009040000,Hori Fighting Commander OCTA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000000d0f00008500000010010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00008600000002010000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00008800000011010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00008700000011010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,rightstick:b11,righttrigger:a4,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00001000000011010000,Hori Fightstick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 03000000ad1b000003f5000033050000,Hori Fightstick VX,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b8,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, -030000000d0f00004d00000011010000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00004d00000011010000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux, 030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, @@ -1092,7 +1118,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000000d0f0000ee00000011010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00006700000001010000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, -050000000d0f0000f600000001000000,HORIPAD Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000000d0f0000f600000001000000,Horipad Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, 030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux, 03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -1203,8 +1229,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b16,b:b15,back:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,platform:Linux, 03000000d620000013a7000011010000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, -030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, -050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux, 05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, @@ -1243,14 +1269,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, +03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400001a53000000010000,PowerA Mini Pro Ex,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000c62400001a58000001010000,PowerA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d62000000220000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, 03000000d62000000228000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, +03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, @@ -1434,6 +1460,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000005e040000130b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000005e040000120b000007050000,Xbox Series X Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,misc1:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, 050000005e040000130b000007050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux, @@ -1449,18 +1476,30 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 61393962646434393836356631636132,8BitDo Arcade Stick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b19,y:b2,platform:Android, 64323139346131306233636562663738,8BitDo Arcade Stick,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android, 64643565386136613265663236636564,8BitDo Arcade Stick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b19,y:b2,platform:Android, +33313433353539306634656436353432,8BitDo Dogbone,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +38426974446f20446f67626f6e65204d,8BitDo Dogbone,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b6,platform:Android, 34343439373236623466343934376233,8BitDo FC30 Pro,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b28,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b29,righttrigger:b7,start:b5,x:b30,y:b2,platform:Android, +38393936616436383062666232653338,8BitDo Lite SE,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, +38426974446f2038426974446f204c69,8BitDo Lite SE,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, +39356430616562366466646636643435,8BitDo Lite SE,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 05000000c82d000006500000ffff3f00,8BitDo M30,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b17,leftshoulder:b9,lefttrigger:a5,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,platform:Android, 05000000c82d000051060000ffff3f00,8BitDo M30,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b17,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,start:b6,x:b3,y:b2,platform:Android, +32323161363037623637326438643634,8BitDo M30,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b10,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 33656266353630643966653238646264,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:a5,start:b10,x:b19,y:b2,platform:Android, +38426974446f204d3330204d6f646b69,8BitDo M30,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b10,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 39366630663062373237616566353437,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b18,start:b6,x:b2,y:b3,platform:Android, 64653533313537373934323436343563,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a4,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b10,start:b6,x:b2,y:b3,platform:Android, 66356438346136366337386437653934,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,start:b18,x:b19,y:b2,platform:Android, 66393064393162303732356665666366,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,platform:Android, +33663431326134333366393233616633,8BitDo N30,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b6,platform:Android, +38426974446f204e3330204d6f646b69,8BitDo N30,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b6,platform:Android, 05000000c82d000015900000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 05000000c82d000065280000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 050000000220000000900000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 050000002038000009000000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, +38313433643131656262306631373166,8BitDo P30,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +38326536643339353865323063616339,8BitDo P30,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +38426974446f2050333020636c617373,8BitDo P30,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 35376664343164386333616535333434,8BitDo Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b17,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b18,righttrigger:a5,rightx:a3,start:b10,x:b19,y:b2,platform:Android, 38426974446f2038426974446f205072,8BitDo Pro 2,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 38426974446f2050726f203200000000,8BitDo Pro 2,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, @@ -1468,12 +1507,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 38386464613034326435626130396565,8BitDo Receiver,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b19,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 38426974446f2038426974446f205265,8BitDo Receiver,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b19,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 66303230343038613365623964393766,8BitDo Receiver,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b19,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, +38426974446f20533330204d6f646b69,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a4,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b10,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +66316462353561376330346462316137,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a4,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b10,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 05000000c82d000000600000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 05000000c82d000000610000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 38426974646f20534633302050726f00,8BitDo SF30 Pro,a:b1,b:b0,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b17,platform:Android, 61623334636338643233383735326439,8BitDo SFC30,a:b0,b:b1,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b3,rightshoulder:b31,start:b5,x:b30,y:b2,platform:Android, 05000000c82d000012900000ffff3f00,8BitDo SN30,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android, 05000000c82d000062280000ffff3f00,8BitDo SN30,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android, +38316230613931613964356666353839,8BitDo SN30,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, +38426974446f20534e3330204d6f646b,8BitDo SN30,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, +65323563303231646531383162646335,8BitDo SN30,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 35383531346263653330306238353131,8BitDo SN30 PP,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 05000000c82d000001600000ffff3f00,8BitDo SN30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 36653638656632326235346264663661,8BitDo SN30 Pro Plus,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android, @@ -1497,6 +1541,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 417374726f2063697479206d696e6920,Astro City Mini,a:b23,b:b22,back:b29,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b25,righttrigger:b26,start:b30,x:b24,y:b21,platform:Android, 32303165626138343962363666346165,Brook Mars PS4 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android, 38383337343564366131323064613561,Brook Mars PS4 Controller,a:b1,b:b19,back:b17,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android, +34313430343161653665353737323365,Elecom JC-W01U,a:b23,b:b24,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b21,y:b22,platform:Android, +4875694a6961204a432d573031550000,Elecom JC-W01U,a:b23,b:b24,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b21,y:b22,platform:Android, 30363230653635633863366338623265,Evo VR,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,x:b2,y:b3,platform:Android, 05000000b404000011240000dfff3f00,Flydigi Vader 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, @@ -1535,6 +1581,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 6d6179666c617368206c696d69746564,Mayflash GameCube Adapter,a:b22,b:b21,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a5,righty:a2,start:b30,x:b23,y:b24,platform:Android, 436f6e74726f6c6c6572000000000000,Mayflash N64 Adapter,a:b1,b:b19,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a2,righty:a3,start:b18,platform:Android, 65666330633838383061313633326461,Mayflash N64 Adapter,a:b1,b:b19,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a2,righty:a3,start:b18,platform:Android, +535a4d792d706f776572204c54442043,Mayflash Wii Classic Adapter,a:b23,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b31,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a2,righty:a3,start:b30,x:b24,y:b21,platform:Android, +30653962643666303631376438373532,Mayflash Wii DolphinBar,a:b23,b:b24,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b21,y:b22,platform:Android, +484a5a204d6179666c61736820576969,Mayflash Wii DolphinBar,a:b23,b:b24,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b21,y:b22,platform:Android, 31323564663862633234646330373138,Mega Drive,a:b23,b:b22,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b25,righttrigger:b26,start:b30,x:b24,y:b21,platform:Android, 37333564393261653735306132613061,Mega Drive,a:b21,b:b22,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,lefttrigger:b28,rightshoulder:b27,righttrigger:b23,start:b30,x:b24,y:b25,platform:Android, 64363363336633363736393038313464,Mega Drive,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Android, @@ -1589,10 +1638,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 65366465656364636137653363376531,PS4 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android, 66613532303965383534396638613230,PS4 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android, 050000004c050000e60c0000fffe3f00,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, +32346465346533616263386539323932,PS5 Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 32633532643734376632656664383733,PS5 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android, 37363764353731323963323639666565,PS5 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android, 61303162353165316365336436343139,PS5 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android, -32346465346533616263386539323932,PS5 Controller,a:b0,b:b1,x:b2,y:b3,leftshoulder:b9,rightshoulder:b10,lefttrigger:a4,righttrigger:a5,guide:b5,start:b6,leftstick:b7,rightstick:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,back:b15,platform:Android, 64336263393933626535303339616332,Qanba 4RAF,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b20,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b9,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android, 36626666353861663864336130363137,Razer Junglecat,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 62653861643333663663383332396665,Razer Kishi,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, @@ -1669,6 +1718,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, 4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS, 4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS, +050000007e050000062000004f060000,Nintendo Switch Joy-Con (L),+leftx:h0.1,+lefty:h0.2,-leftx:h0.4,-lefty:h0.8,dpdown:b2,dpleft:b0,dpright:b3,dpup:b1,leftshoulder:b4,misc1:b6,rightshoulder:b5,platform:iOS, +050000007e0500000e200000df070000,Nintendo Switch Joy-Con (L/R),a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:iOS, +050000007e050000072000004f060000,Nintendo Switch Joy-Con (R),+rightx:h0.4,+righty:h0.8,-rightx:h0.1,-righty:h0.2,a:b1,b:b0,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b3,y:b2,platform:iOS, +050000007e05000009200000ff870000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, 050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, 050000004c050000cc090000df870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, 050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, diff --git a/core/input/input.cpp b/core/input/input.cpp index da0c6cb62a..e08647f5ea 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -1187,7 +1187,7 @@ Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, J return event; } -void Input::_get_mapped_hat_events(const JoyDeviceMapping &mapping, HatDir p_hat, JoyEvent r_events[]) { +void Input::_get_mapped_hat_events(const JoyDeviceMapping &mapping, HatDir p_hat, JoyEvent r_events[(size_t)HatDir::MAX]) { for (int i = 0; i < mapping.bindings.size(); i++) { const JoyBinding binding = mapping.bindings[i]; if (binding.inputType == TYPE_HAT && binding.input.hat.hat == p_hat) { diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 3c104c2c86..8ad2193fca 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -816,7 +816,7 @@ String InputEventMouseMotion::to_string() { // Work around the fact vformat can only take 5 substitutions but 7 need to be passed. String mask_and_position_and_relative = vformat("button_mask=%s, position=(%s), relative=(%s)", button_mask_string, String(get_position()), String(get_relative())); - return vformat("InputEventMouseMotion: %s, velocity=(%s), pressure=%.2f, tilt=(%s), pen_inverted=(%d)", mask_and_position_and_relative, String(get_velocity()), get_pressure(), String(get_tilt()), get_pen_inverted()); + return vformat("InputEventMouseMotion: %s, velocity=(%s), pressure=%.2f, tilt=(%s), pen_inverted=(%s)", mask_and_position_and_relative, String(get_velocity()), get_pressure(), String(get_tilt()), get_pen_inverted()); } bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) { diff --git a/core/io/dir_access.h b/core/io/dir_access.h index 22017efaa3..d5318dfb45 100644 --- a/core/io/dir_access.h +++ b/core/io/dir_access.h @@ -108,6 +108,8 @@ public: if (da->remove(p_path) != OK) { ERR_FAIL_MSG("Cannot remove file or directory: " + p_path); } + } else { + ERR_FAIL_MSG("Cannot remove non-existent file or directory: " + p_path); } } diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index da25f23917..8ed3d40c22 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -377,7 +377,7 @@ uint64_t FileAccess::get_buffer(uint8_t *p_dst, uint64_t p_length) const { return i; } -String FileAccess::get_as_utf8_string() const { +String FileAccess::get_as_utf8_string(bool p_skip_cr) const { Vector<uint8_t> sourcef; uint64_t len = get_length(); sourcef.resize(len + 1); @@ -388,7 +388,7 @@ String FileAccess::get_as_utf8_string() const { w[len] = 0; String s; - s.parse_utf8((const char *)w); + s.parse_utf8((const char *)w, -1, p_skip_cr); return s; } diff --git a/core/io/file_access.h b/core/io/file_access.h index e2c11142d7..3386800686 100644 --- a/core/io/file_access.h +++ b/core/io/file_access.h @@ -113,7 +113,7 @@ public: virtual String get_line() const; virtual String get_token() const; virtual Vector<String> get_csv_line(const String &p_delim = ",") const; - virtual String get_as_utf8_string() const; + virtual String get_as_utf8_string(bool p_skip_cr = false) const; /** * Use this for files WRITTEN in _big_ endian machines (ie, amiga/mac) diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index b8382e61d9..e41491a92c 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -70,29 +70,29 @@ public: Error open_after_magic(Ref<FileAccess> p_base); - virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file - virtual bool is_open() const; ///< true when file is open + virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file + virtual bool is_open() const override; ///< true when file is open - virtual void seek(uint64_t p_position); ///< seek to a given position - virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_length() const; ///< get size of the file + virtual void seek(uint64_t p_position) override; ///< seek to a given position + virtual void seek_end(int64_t p_position = 0) override; ///< seek from the end of file + virtual uint64_t get_position() const override; ///< get position in the file + virtual uint64_t get_length() const override; ///< get size of the file - virtual bool eof_reached() const; ///< reading passed EOF + virtual bool eof_reached() const override; ///< reading passed EOF - virtual uint8_t get_8() const; ///< get a byte - virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; + virtual uint8_t get_8() const override; ///< get a byte + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override; - virtual Error get_error() const; ///< get last error + virtual Error get_error() const override; ///< get last error - virtual void flush(); - virtual void store_8(uint8_t p_dest); ///< store a byte + virtual void flush() override; + virtual void store_8(uint8_t p_dest) override; ///< store a byte - virtual bool file_exists(const String &p_name); ///< return true if a file exists + virtual bool file_exists(const String &p_name) override; ///< return true if a file exists - virtual uint64_t _get_modified_time(const String &p_file); - virtual uint32_t _get_unix_permissions(const String &p_file); - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions); + virtual uint64_t _get_modified_time(const String &p_file) override; + virtual uint32_t _get_unix_permissions(const String &p_file) override; + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override; FileAccessCompressed() {} virtual ~FileAccessCompressed(); diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index 0d1ee6a4d8..6200f87a7a 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -60,33 +60,33 @@ public: Error open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true); Error open_and_parse_password(Ref<FileAccess> p_base, const String &p_key, Mode p_mode); - virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file - virtual bool is_open() const; ///< true when file is open + virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file + virtual bool is_open() const override; ///< true when file is open - virtual String get_path() const; /// returns the path for the current open file - virtual String get_path_absolute() const; /// returns the absolute path for the current open file + virtual String get_path() const override; /// returns the path for the current open file + virtual String get_path_absolute() const override; /// returns the absolute path for the current open file - virtual void seek(uint64_t p_position); ///< seek to a given position - virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_length() const; ///< get size of the file + virtual void seek(uint64_t p_position) override; ///< seek to a given position + virtual void seek_end(int64_t p_position = 0) override; ///< seek from the end of file + virtual uint64_t get_position() const override; ///< get position in the file + virtual uint64_t get_length() const override; ///< get size of the file - virtual bool eof_reached() const; ///< reading passed EOF + virtual bool eof_reached() const override; ///< reading passed EOF - virtual uint8_t get_8() const; ///< get a byte - virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; + virtual uint8_t get_8() const override; ///< get a byte + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override; - virtual Error get_error() const; ///< get last error + virtual Error get_error() const override; ///< get last error - virtual void flush(); - virtual void store_8(uint8_t p_dest); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes + virtual void flush() override; + virtual void store_8(uint8_t p_dest) override; ///< store a byte + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes - virtual bool file_exists(const String &p_name); ///< return true if a file exists + virtual bool file_exists(const String &p_name) override; ///< return true if a file exists - virtual uint64_t _get_modified_time(const String &p_file); - virtual uint32_t _get_unix_permissions(const String &p_file); - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions); + virtual uint64_t _get_modified_time(const String &p_file) override; + virtual uint32_t _get_unix_permissions(const String &p_file) override; + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override; FileAccessEncrypted() {} ~FileAccessEncrypted(); diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index 868b8ed481..f2bd2aa832 100644 --- a/core/io/file_access_memory.h +++ b/core/io/file_access_memory.h @@ -45,31 +45,31 @@ public: static void cleanup(); virtual Error open_custom(const uint8_t *p_data, uint64_t p_len); ///< open a file - virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file - virtual bool is_open() const; ///< true when file is open + virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file + virtual bool is_open() const override; ///< true when file is open - virtual void seek(uint64_t p_position); ///< seek to a given position - virtual void seek_end(int64_t p_position); ///< seek from the end of file - virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_length() const; ///< get size of the file + virtual void seek(uint64_t p_position) override; ///< seek to a given position + virtual void seek_end(int64_t p_position) override; ///< seek from the end of file + virtual uint64_t get_position() const override; ///< get position in the file + virtual uint64_t get_length() const override; ///< get size of the file - virtual bool eof_reached() const; ///< reading passed EOF + virtual bool eof_reached() const override; ///< reading passed EOF - virtual uint8_t get_8() const; ///< get a byte + virtual uint8_t get_8() const override; ///< get a byte - virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; ///< get an array of bytes + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override; ///< get an array of bytes - virtual Error get_error() const; ///< get last error + virtual Error get_error() const override; ///< get last error - virtual void flush(); - virtual void store_8(uint8_t p_byte); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes + virtual void flush() override; + virtual void store_8(uint8_t p_byte) override; ///< store a byte + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes - virtual bool file_exists(const String &p_name); ///< return true if a file exists + virtual bool file_exists(const String &p_name) override; ///< return true if a file exists - virtual uint64_t _get_modified_time(const String &p_file) { return 0; } - virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; } - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; } + virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } + virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; } + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; } FileAccessMemory() {} }; diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index c7431752c0..ceadc715a1 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -132,29 +132,29 @@ public: RESPONSE_GET_MODTIME, }; - virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file - virtual bool is_open() const; ///< true when file is open + virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file + virtual bool is_open() const override; ///< true when file is open - virtual void seek(uint64_t p_position); ///< seek to a given position - virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_length() const; ///< get size of the file + virtual void seek(uint64_t p_position) override; ///< seek to a given position + virtual void seek_end(int64_t p_position = 0) override; ///< seek from the end of file + virtual uint64_t get_position() const override; ///< get position in the file + virtual uint64_t get_length() const override; ///< get size of the file - virtual bool eof_reached() const; ///< reading passed EOF + virtual bool eof_reached() const override; ///< reading passed EOF - virtual uint8_t get_8() const; ///< get a byte - virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; + virtual uint8_t get_8() const override; ///< get a byte + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override; - virtual Error get_error() const; ///< get last error + virtual Error get_error() const override; ///< get last error - virtual void flush(); - virtual void store_8(uint8_t p_dest); ///< store a byte + virtual void flush() override; + virtual void store_8(uint8_t p_dest) override; ///< store a byte - virtual bool file_exists(const String &p_path); ///< return true if a file exists + virtual bool file_exists(const String &p_path) override; ///< return true if a file exists - virtual uint64_t _get_modified_time(const String &p_file); - virtual uint32_t _get_unix_permissions(const String &p_file); - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions); + virtual uint64_t _get_modified_time(const String &p_file) override; + virtual uint32_t _get_unix_permissions(const String &p_file) override; + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override; static void configure(); diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index e656f6b885..023758ac0f 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -148,35 +148,35 @@ class FileAccessPack : public FileAccess { uint64_t off; Ref<FileAccess> f; - virtual Error _open(const String &p_path, int p_mode_flags); - virtual uint64_t _get_modified_time(const String &p_file) { return 0; } - virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; } - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; } + virtual Error _open(const String &p_path, int p_mode_flags) override; + virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } + virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; } + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; } public: - virtual bool is_open() const; + virtual bool is_open() const override; - virtual void seek(uint64_t p_position); - virtual void seek_end(int64_t p_position = 0); - virtual uint64_t get_position() const; - virtual uint64_t get_length() const; + virtual void seek(uint64_t p_position) override; + virtual void seek_end(int64_t p_position = 0) override; + virtual uint64_t get_position() const override; + virtual uint64_t get_length() const override; - virtual bool eof_reached() const; + virtual bool eof_reached() const override; - virtual uint8_t get_8() const; + virtual uint8_t get_8() const override; - virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override; - virtual void set_big_endian(bool p_big_endian); + virtual void set_big_endian(bool p_big_endian) override; - virtual Error get_error() const; + virtual Error get_error() const override; - virtual void flush(); - virtual void store_8(uint8_t p_dest); + virtual void flush() override; + virtual void store_8(uint8_t p_dest) override; - virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; - virtual bool file_exists(const String &p_name); + virtual bool file_exists(const String &p_name) override; FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file); }; @@ -217,33 +217,33 @@ class DirAccessPack : public DirAccess { PackedData::PackedDir *_find_dir(String p_dir); public: - virtual Error list_dir_begin(); - virtual String get_next(); - virtual bool current_is_dir() const; - virtual bool current_is_hidden() const; - virtual void list_dir_end(); + virtual Error list_dir_begin() override; + virtual String get_next() override; + virtual bool current_is_dir() const override; + virtual bool current_is_hidden() const override; + virtual void list_dir_end() override; - virtual int get_drive_count(); - virtual String get_drive(int p_drive); + virtual int get_drive_count() override; + virtual String get_drive(int p_drive) override; - virtual Error change_dir(String p_dir); - virtual String get_current_dir(bool p_include_drive = true) const; + virtual Error change_dir(String p_dir) override; + virtual String get_current_dir(bool p_include_drive = true) const override; - virtual bool file_exists(String p_file); - virtual bool dir_exists(String p_dir); + virtual bool file_exists(String p_file) override; + virtual bool dir_exists(String p_dir) override; - virtual Error make_dir(String p_dir); + virtual Error make_dir(String p_dir) override; - virtual Error rename(String p_from, String p_to); - virtual Error remove(String p_name); + virtual Error rename(String p_from, String p_to) override; + virtual Error remove(String p_name) override; - uint64_t get_space_left(); + uint64_t get_space_left() override; - virtual bool is_link(String p_file) { return false; } - virtual String read_link(String p_file) { return p_file; } - virtual Error create_link(String p_source, String p_target) { return FAILED; } + virtual bool is_link(String p_file) override { return false; } + virtual String read_link(String p_file) override { return p_file; } + virtual Error create_link(String p_source, String p_target) override { return FAILED; } - virtual String get_filesystem_type() const; + virtual String get_filesystem_type() const override; DirAccessPack(); }; diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index 6ea603546a..74a48192f3 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -85,29 +85,29 @@ class FileAccessZip : public FileAccess { void _close(); public: - virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file - virtual bool is_open() const; ///< true when file is open + virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file + virtual bool is_open() const override; ///< true when file is open - virtual void seek(uint64_t p_position); ///< seek to a given position - virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_length() const; ///< get size of the file + virtual void seek(uint64_t p_position) override; ///< seek to a given position + virtual void seek_end(int64_t p_position = 0) override; ///< seek from the end of file + virtual uint64_t get_position() const override; ///< get position in the file + virtual uint64_t get_length() const override; ///< get size of the file - virtual bool eof_reached() const; ///< reading passed EOF + virtual bool eof_reached() const override; ///< reading passed EOF - virtual uint8_t get_8() const; ///< get a byte - virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; + virtual uint8_t get_8() const override; ///< get a byte + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override; - virtual Error get_error() const; ///< get last error + virtual Error get_error() const override; ///< get last error - virtual void flush(); - virtual void store_8(uint8_t p_dest); ///< store a byte + virtual void flush() override; + virtual void store_8(uint8_t p_dest) override; ///< store a byte - virtual bool file_exists(const String &p_name); ///< return true if a file exists + virtual bool file_exists(const String &p_name) override; ///< return true if a file exists - virtual uint64_t _get_modified_time(const String &p_file) { return 0; } // todo - virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; } - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; } + virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } // todo + virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; } + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; } FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file); ~FileAccessZip(); diff --git a/core/io/image.cpp b/core/io/image.cpp index 0f20aabd7e..2d87523ca4 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -416,8 +416,8 @@ int Image::get_height() const { return height; } -Vector2 Image::get_size() const { - return Vector2(width, height); +Vector2i Image::get_size() const { + return Vector2i(width, height); } bool Image::has_mipmaps() const { diff --git a/core/io/image.h b/core/io/image.h index 46820a4c08..9d415423be 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -209,7 +209,7 @@ private: public: int get_width() const; ///< Get image width int get_height() const; ///< Get image height - Vector2 get_size() const; + Vector2i get_size() const; bool has_mipmaps() const; int get_mipmap_count() const; diff --git a/core/io/logger.cpp b/core/io/logger.cpp index 5820ec0c09..b0f74f8db5 100644 --- a/core/io/logger.cpp +++ b/core/io/logger.cpp @@ -31,6 +31,7 @@ #include "logger.h" #include "core/config/project_settings.h" +#include "core/core_globals.h" #include "core/io/dir_access.h" #include "core/os/os.h" #include "core/os/time.h" @@ -41,7 +42,7 @@ #endif bool Logger::should_log(bool p_err) { - return (!p_err || _print_error_enabled) && (p_err || _print_line_enabled); + return (!p_err || CoreGlobals::print_error_enabled) && (p_err || CoreGlobals::print_line_enabled); } bool Logger::_flush_stdout_on_print = true; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 016302c653..b731608b4f 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1267,7 +1267,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons Ref<Resource> res = loader.get_resource(); ERR_FAIL_COND_V(!res.is_valid(), ERR_FILE_CORRUPT); - return ResourceFormatSaverBinary::singleton->save(p_path, res); + return ResourceFormatSaverBinary::singleton->save(res, p_path); } if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { @@ -2204,7 +2204,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re return OK; } -Error ResourceFormatSaverBinary::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverBinary::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { String local_path = ProjectSettings::get_singleton()->localize_path(p_path); ResourceFormatSaverBinaryInstance saver; return saver.save(local_path, p_resource, p_flags); diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 2b043302fd..c891a61e99 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -176,7 +176,7 @@ public: class ResourceFormatSaverBinary : public ResourceFormatSaver { public: static ResourceFormatSaverBinary *singleton; - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual bool recognize(const Ref<Resource> &p_resource) const; virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index fc4177004b..3e595557f9 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -819,6 +819,12 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem if (r_translation_remapped) { *r_translation_remapped = true; } + + // Fallback to p_path if new_path does not exist. + if (!FileAccess::exists(new_path)) { + WARN_PRINT(vformat("Translation remap '%s' does not exist. Falling back to '%s'.", new_path, p_path)); + new_path = p_path; + } } if (path_remaps.has(new_path)) { diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index 2f5c5b54dd..274316f058 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -41,9 +41,9 @@ bool ResourceSaver::timestamp_on_save = false; ResourceSavedCallback ResourceSaver::save_callback = nullptr; ResourceSaverGetResourceIDForPath ResourceSaver::save_get_id_for_path = nullptr; -Error ResourceFormatSaver::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceFormatSaver::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { int64_t res; - if (GDVIRTUAL_CALL(_save, p_path, p_resource, p_flags, res)) { + if (GDVIRTUAL_CALL(_save, p_resource, p_path, p_flags, res)) { return (Error)res; } @@ -75,8 +75,14 @@ void ResourceFormatSaver::_bind_methods() { GDVIRTUAL_BIND(_get_recognized_extensions, "resource"); } -Error ResourceSaver::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { - String extension = p_path.get_extension(); +Error ResourceSaver::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { + String path = p_path; + if (path.is_empty()) { + path = p_resource->get_path(); + } + ERR_FAIL_COND_V_MSG(path.is_empty(), ERR_INVALID_PARAMETER, "Can't save resource to empty path. Provide non-empty path or a Resource with non-empty resource_path."); + + String extension = path.get_extension(); Error err = ERR_FILE_UNRECOGNIZED; for (int i = 0; i < saver_count; i++) { @@ -100,21 +106,21 @@ Error ResourceSaver::save(const String &p_path, const Ref<Resource> &p_resource, String old_path = p_resource->get_path(); - String local_path = ProjectSettings::get_singleton()->localize_path(p_path); + String local_path = ProjectSettings::get_singleton()->localize_path(path); Ref<Resource> rwcopy = p_resource; if (p_flags & FLAG_CHANGE_PATH) { rwcopy->set_path(local_path); } - err = saver[i]->save(p_path, p_resource, p_flags); + err = saver[i]->save(p_resource, path, p_flags); if (err == OK) { #ifdef TOOLS_ENABLED ((Resource *)p_resource.ptr())->set_edited(false); if (timestamp_on_save) { - uint64_t mt = FileAccess::get_modified_time(p_path); + uint64_t mt = FileAccess::get_modified_time(path); ((Resource *)p_resource.ptr())->set_last_modified_time(mt); } @@ -124,8 +130,8 @@ Error ResourceSaver::save(const String &p_path, const Ref<Resource> &p_resource, rwcopy->set_path(old_path); } - if (save_callback && p_path.begins_with("res://")) { - save_callback(p_resource, p_path); + if (save_callback && path.begins_with("res://")) { + save_callback(p_resource, path); } return OK; diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index 088317bfbe..4fee2bcfd1 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -41,12 +41,12 @@ class ResourceFormatSaver : public RefCounted { protected: static void _bind_methods(); - GDVIRTUAL3R(int64_t, _save, String, Ref<Resource>, uint32_t) + GDVIRTUAL3R(int64_t, _save, Ref<Resource>, String, uint32_t) GDVIRTUAL1RC(bool, _recognize, Ref<Resource>) GDVIRTUAL1RC(Vector<String>, _get_recognized_extensions, Ref<Resource>) public: - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual bool recognize(const Ref<Resource> &p_resource) const; virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; @@ -81,7 +81,7 @@ public: FLAG_REPLACE_SUBRESOURCE_PATHS = 64, }; - static Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = (uint32_t)FLAG_NONE); + static Error save(const Ref<Resource> &p_resource, const String &p_path = "", uint32_t p_flags = (uint32_t)FLAG_NONE); static void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions); static void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front = false); static void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver); diff --git a/core/math/color.h b/core/math/color.h index 0afa6006a8..65036f74cc 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -215,12 +215,12 @@ struct _NO_DISCARD_ Color { _FORCE_INLINE_ void set_a8(int32_t a8) { a = (CLAMP(a8, 0, 255) / 255.0f); } _FORCE_INLINE_ int32_t get_a8() const { return int32_t(CLAMP(Math::round(a * 255.0f), 0.0f, 255.0f)); } - _FORCE_INLINE_ void set_h(float p_h) { set_hsv(p_h, get_s(), get_v()); } - _FORCE_INLINE_ void set_s(float p_s) { set_hsv(get_h(), p_s, get_v()); } - _FORCE_INLINE_ void set_v(float p_v) { set_hsv(get_h(), get_s(), p_v); } - _FORCE_INLINE_ void set_ok_hsl_h(float p_h) { set_ok_hsl(p_h, get_ok_hsl_s(), get_ok_hsl_l()); } - _FORCE_INLINE_ void set_ok_hsl_s(float p_s) { set_ok_hsl(get_ok_hsl_h(), p_s, get_ok_hsl_l()); } - _FORCE_INLINE_ void set_ok_hsl_l(float p_l) { set_ok_hsl(get_ok_hsl_h(), get_ok_hsl_s(), p_l); } + _FORCE_INLINE_ void set_h(float p_h) { set_hsv(p_h, get_s(), get_v(), a); } + _FORCE_INLINE_ void set_s(float p_s) { set_hsv(get_h(), p_s, get_v(), a); } + _FORCE_INLINE_ void set_v(float p_v) { set_hsv(get_h(), get_s(), p_v, a); } + _FORCE_INLINE_ void set_ok_hsl_h(float p_h) { set_ok_hsl(p_h, get_ok_hsl_s(), get_ok_hsl_l(), a); } + _FORCE_INLINE_ void set_ok_hsl_s(float p_s) { set_ok_hsl(get_ok_hsl_h(), p_s, get_ok_hsl_l(), a); } + _FORCE_INLINE_ void set_ok_hsl_l(float p_l) { set_ok_hsl(get_ok_hsl_h(), get_ok_hsl_s(), p_l, a); } _FORCE_INLINE_ Color() {} diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index 11bfcc1a6f..c681c60694 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -111,7 +111,7 @@ Quaternion Quaternion::log() const { Quaternion Quaternion::exp() const { Quaternion src = *this; Vector3 src_v = Vector3(src.x, src.y, src.z); - float theta = src_v.length(); + real_t theta = src_v.length(); if (theta < CMP_EPSILON) { return Quaternion(0, 0, 0, 1); } @@ -132,15 +132,9 @@ Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) con // adjust signs (if necessary) if (cosom < 0.0f) { cosom = -cosom; - to1.x = -p_to.x; - to1.y = -p_to.y; - to1.z = -p_to.z; - to1.w = -p_to.w; + to1 = -p_to; } else { - to1.x = p_to.x; - to1.y = p_to.y; - to1.z = p_to.z; - to1.w = p_to.w; + to1 = p_to; } // calculate coefficients @@ -189,16 +183,54 @@ Quaternion Quaternion::slerpni(const Quaternion &p_to, const real_t &p_weight) c invFactor * from.w + newFactor * p_to.w); } -Quaternion Quaternion::cubic_slerp(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const { +Quaternion Quaternion::spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const { #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized."); ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion must be normalized."); #endif - //the only way to do slerp :| - real_t t2 = (1.0f - p_weight) * p_weight * 2; - Quaternion sp = this->slerp(p_b, p_weight); - Quaternion sq = p_pre_a.slerpni(p_post_b, p_weight); - return sp.slerpni(sq, t2); + Quaternion from_q = *this; + Quaternion pre_q = p_pre_a; + Quaternion to_q = p_b; + Quaternion post_q = p_post_b; + + // Align flip phases. + from_q = Basis(from_q).get_rotation_quaternion(); + pre_q = Basis(pre_q).get_rotation_quaternion(); + to_q = Basis(to_q).get_rotation_quaternion(); + post_q = Basis(post_q).get_rotation_quaternion(); + + // Flip quaternions to shortest path if necessary. + bool flip1 = signbit(from_q.dot(pre_q)); + pre_q = flip1 ? -pre_q : pre_q; + bool flip2 = signbit(from_q.dot(to_q)); + to_q = flip2 ? -to_q : to_q; + bool flip3 = flip2 ? to_q.dot(post_q) <= 0 : signbit(to_q.dot(post_q)); + post_q = flip3 ? -post_q : post_q; + + // Calc by Expmap in from_q space. + Quaternion ln_from = Quaternion(0, 0, 0, 0); + Quaternion ln_to = (from_q.inverse() * to_q).log(); + Quaternion ln_pre = (from_q.inverse() * pre_q).log(); + Quaternion ln_post = (from_q.inverse() * post_q).log(); + Quaternion ln = Quaternion(0, 0, 0, 0); + ln.x = Math::cubic_interpolate(ln_from.x, ln_to.x, ln_pre.x, ln_post.x, p_weight); + ln.y = Math::cubic_interpolate(ln_from.y, ln_to.y, ln_pre.y, ln_post.y, p_weight); + ln.z = Math::cubic_interpolate(ln_from.z, ln_to.z, ln_pre.z, ln_post.z, p_weight); + Quaternion q1 = from_q * ln.exp(); + + // Calc by Expmap in to_q space. + ln_from = (to_q.inverse() * from_q).log(); + ln_to = Quaternion(0, 0, 0, 0); + ln_pre = (to_q.inverse() * pre_q).log(); + ln_post = (to_q.inverse() * post_q).log(); + ln = Quaternion(0, 0, 0, 0); + ln.x = Math::cubic_interpolate(ln_from.x, ln_to.x, ln_pre.x, ln_post.x, p_weight); + ln.y = Math::cubic_interpolate(ln_from.y, ln_to.y, ln_pre.y, ln_post.y, p_weight); + ln.z = Math::cubic_interpolate(ln_from.z, ln_to.z, ln_pre.z, ln_post.z, p_weight); + Quaternion q2 = to_q * ln.exp(); + + // To cancel error made by Expmap ambiguity, do blends. + return q1.slerp(q2, p_weight); } Quaternion::operator String() const { @@ -213,7 +245,7 @@ Vector3 Quaternion::get_axis() const { return Vector3(x * r, y * r, z * r); } -float Quaternion::get_angle() const { +real_t Quaternion::get_angle() const { return 2 * Math::acos(w); } diff --git a/core/math/quaternion.h b/core/math/quaternion.h index 9801746659..cb54a6f540 100644 --- a/core/math/quaternion.h +++ b/core/math/quaternion.h @@ -71,10 +71,10 @@ struct _NO_DISCARD_ Quaternion { Quaternion slerp(const Quaternion &p_to, const real_t &p_weight) const; Quaternion slerpni(const Quaternion &p_to, const real_t &p_weight) const; - Quaternion cubic_slerp(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const; + Quaternion spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const; Vector3 get_axis() const; - float get_angle() const; + real_t get_angle() const; _FORCE_INLINE_ void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { r_angle = 2 * Math::acos(w); diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index cbd2fd3fa1..226076029b 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -136,11 +136,11 @@ void Transform2D::scale_basis(const Size2 &p_scale) { columns[1][1] *= p_scale.y; } -void Transform2D::translate(const real_t p_tx, const real_t p_ty) { - translate(Vector2(p_tx, p_ty)); +void Transform2D::translate_local(const real_t p_tx, const real_t p_ty) { + translate_local(Vector2(p_tx, p_ty)); } -void Transform2D::translate(const Vector2 &p_translation) { +void Transform2D::translate_local(const Vector2 &p_translation) { columns[2] += basis_xform(p_translation); } @@ -217,18 +217,24 @@ Transform2D Transform2D::operator*(const Transform2D &p_transform) const { return t; } -Transform2D Transform2D::scaled(const Size2 &p_scale) const { +Transform2D Transform2D::basis_scaled(const Size2 &p_scale) const { Transform2D copy = *this; - copy.scale(p_scale); + copy.scale_basis(p_scale); return copy; } -Transform2D Transform2D::basis_scaled(const Size2 &p_scale) const { +Transform2D Transform2D::scaled(const Size2 &p_scale) const { + // Equivalent to left multiplication Transform2D copy = *this; - copy.scale_basis(p_scale); + copy.scale(p_scale); return copy; } +Transform2D Transform2D::scaled_local(const Size2 &p_scale) const { + // Equivalent to right multiplication + return Transform2D(columns[0] * p_scale.x, columns[1] * p_scale.y, columns[2]); +} + Transform2D Transform2D::untranslated() const { Transform2D copy = *this; copy.columns[2] = Vector2(); @@ -236,15 +242,23 @@ Transform2D Transform2D::untranslated() const { } Transform2D Transform2D::translated(const Vector2 &p_offset) const { - Transform2D copy = *this; - copy.translate(p_offset); - return copy; + // Equivalent to left multiplication + return Transform2D(columns[0], columns[1], columns[2] + p_offset); +} + +Transform2D Transform2D::translated_local(const Vector2 &p_offset) const { + // Equivalent to right multiplication + return Transform2D(columns[0], columns[1], columns[2] + basis_xform(p_offset)); } Transform2D Transform2D::rotated(const real_t p_angle) const { - Transform2D copy = *this; - copy.rotate(p_angle); - return copy; + // Equivalent to left multiplication + return Transform2D(p_angle, Vector2()) * (*this); +} + +Transform2D Transform2D::rotated_local(const real_t p_angle) const { + // Equivalent to right multiplication + return (*this) * Transform2D(p_angle, Vector2()); // Could be optimized, because origin transform can be skipped. } real_t Transform2D::basis_determinant() const { diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 72d34a5d4c..f23f32867a 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -74,8 +74,8 @@ struct _NO_DISCARD_ Transform2D { void scale(const Size2 &p_scale); void scale_basis(const Size2 &p_scale); - void translate(const real_t p_tx, const real_t p_ty); - void translate(const Vector2 &p_translation); + void translate_local(const real_t p_tx, const real_t p_ty); + void translate_local(const Vector2 &p_translation); real_t basis_determinant() const; @@ -85,10 +85,13 @@ struct _NO_DISCARD_ Transform2D { _FORCE_INLINE_ const Vector2 &get_origin() const { return columns[2]; } _FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { columns[2] = p_origin; } - Transform2D scaled(const Size2 &p_scale) const; Transform2D basis_scaled(const Size2 &p_scale) const; + Transform2D scaled(const Size2 &p_scale) const; + Transform2D scaled_local(const Size2 &p_scale) const; Transform2D translated(const Vector2 &p_offset) const; + Transform2D translated_local(const Vector2 &p_offset) const; Transform2D rotated(const real_t p_angle) const; + Transform2D rotated_local(const real_t p_angle) const; Transform2D untranslated() const; diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp index 76b31daa76..a634faca9a 100644 --- a/core/math/transform_3d.cpp +++ b/core/math/transform_3d.cpp @@ -62,7 +62,15 @@ void Transform3D::rotate(const Vector3 &p_axis, real_t p_angle) { } Transform3D Transform3D::rotated(const Vector3 &p_axis, real_t p_angle) const { - return Transform3D(Basis(p_axis, p_angle), Vector3()) * (*this); + // Equivalent to left multiplication + Basis p_basis(p_axis, p_angle); + return Transform3D(p_basis * basis, p_basis.xform(origin)); +} + +Transform3D Transform3D::rotated_local(const Vector3 &p_axis, real_t p_angle) const { + // Equivalent to right multiplication + Basis p_basis(p_axis, p_angle); + return Transform3D(basis * p_basis, origin); } void Transform3D::rotate_basis(const Vector3 &p_axis, real_t p_angle) { @@ -70,17 +78,23 @@ void Transform3D::rotate_basis(const Vector3 &p_axis, real_t p_angle) { } Transform3D Transform3D::looking_at(const Vector3 &p_target, const Vector3 &p_up) const { +#ifdef MATH_CHECKS + ERR_FAIL_COND_V_MSG(origin.is_equal_approx(p_target), Transform3D(), "The transform's origin and target can't be equal."); +#endif Transform3D t = *this; t.basis = Basis::looking_at(p_target - origin, p_up); return t; } void Transform3D::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) { +#ifdef MATH_CHECKS + ERR_FAIL_COND_MSG(p_eye.is_equal_approx(p_target), "The eye and target vectors can't be equal."); +#endif basis = Basis::looking_at(p_target - p_eye, p_up); origin = p_eye; } -Transform3D Transform3D::sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const { +Transform3D Transform3D::spherical_interpolate_with(const Transform3D &p_transform, real_t p_c) const { /* not sure if very "efficient" but good enough? */ Transform3D interp; @@ -114,29 +128,37 @@ void Transform3D::scale(const Vector3 &p_scale) { } Transform3D Transform3D::scaled(const Vector3 &p_scale) const { - Transform3D t = *this; - t.scale(p_scale); - return t; + // Equivalent to left multiplication + return Transform3D(basis.scaled(p_scale), origin * p_scale); +} + +Transform3D Transform3D::scaled_local(const Vector3 &p_scale) const { + // Equivalent to right multiplication + return Transform3D(basis.scaled_local(p_scale), origin); } void Transform3D::scale_basis(const Vector3 &p_scale) { basis.scale(p_scale); } -void Transform3D::translate(real_t p_tx, real_t p_ty, real_t p_tz) { - translate(Vector3(p_tx, p_ty, p_tz)); +void Transform3D::translate_local(real_t p_tx, real_t p_ty, real_t p_tz) { + translate_local(Vector3(p_tx, p_ty, p_tz)); } -void Transform3D::translate(const Vector3 &p_translation) { +void Transform3D::translate_local(const Vector3 &p_translation) { for (int i = 0; i < 3; i++) { origin[i] += basis[i].dot(p_translation); } } Transform3D Transform3D::translated(const Vector3 &p_translation) const { - Transform3D t = *this; - t.translate(p_translation); - return t; + // Equivalent to left multiplication + return Transform3D(basis, origin + p_translation); +} + +Transform3D Transform3D::translated_local(const Vector3 &p_translation) const { + // Equivalent to right multiplication + return Transform3D(basis, origin + basis.xform(p_translation)); } void Transform3D::orthonormalize() { diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h index 25832434cd..b572e90859 100644 --- a/core/math/transform_3d.h +++ b/core/math/transform_3d.h @@ -46,6 +46,7 @@ struct _NO_DISCARD_ Transform3D { Transform3D affine_inverse() const; Transform3D rotated(const Vector3 &p_axis, real_t p_angle) const; + Transform3D rotated_local(const Vector3 &p_axis, real_t p_angle) const; void rotate(const Vector3 &p_axis, real_t p_angle); void rotate_basis(const Vector3 &p_axis, real_t p_angle); @@ -55,10 +56,12 @@ struct _NO_DISCARD_ Transform3D { void scale(const Vector3 &p_scale); Transform3D scaled(const Vector3 &p_scale) const; + Transform3D scaled_local(const Vector3 &p_scale) const; void scale_basis(const Vector3 &p_scale); - void translate(real_t p_tx, real_t p_ty, real_t p_tz); - void translate(const Vector3 &p_translation); + void translate_local(real_t p_tx, real_t p_ty, real_t p_tz); + void translate_local(const Vector3 &p_translation); Transform3D translated(const Vector3 &p_translation) const; + Transform3D translated_local(const Vector3 &p_translation) const; const Basis &get_basis() const { return basis; } void set_basis(const Basis &p_basis) { basis = p_basis; } @@ -100,7 +103,7 @@ struct _NO_DISCARD_ Transform3D { void operator*=(const real_t p_val); Transform3D operator*(const real_t p_val) const; - Transform3D sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const; + Transform3D spherical_interpolate_with(const Transform3D &p_transform, real_t p_c) const; Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const; _FORCE_INLINE_ Transform3D inverse_xform(const Transform3D &t) const { diff --git a/core/math/vector3.h b/core/math/vector3.h index 970416234d..4ce01da60e 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -217,16 +217,25 @@ Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const { } Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const { + // This method seems more complicated than it really is, since we write out + // the internals of some methods for efficiency (mainly, checking length). real_t start_length_sq = length_squared(); real_t end_length_sq = p_to.length_squared(); if (unlikely(start_length_sq == 0.0f || end_length_sq == 0.0f)) { // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. return lerp(p_to, p_weight); } + Vector3 axis = cross(p_to); + real_t axis_length_sq = axis.length_squared(); + if (unlikely(axis_length_sq == 0.0f)) { + // Colinear vectors have no rotation axis or angle between them, so the best we can do is lerp. + return lerp(p_to, p_weight); + } + axis /= Math::sqrt(axis_length_sq); real_t start_length = Math::sqrt(start_length_sq); real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight); real_t angle = angle_to(p_to); - return rotated(cross(p_to).normalized(), angle * p_weight) * (result_length / start_length); + return rotated(axis, angle * p_weight) * (result_length / start_length); } Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const { diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp index c2a6f8ead2..4697c311b4 100644 --- a/core/math/vector4.cpp +++ b/core/math/vector4.cpp @@ -33,6 +33,40 @@ #include "core/math/basis.h" #include "core/string/print_string.h" +void Vector4::set_axis(const int p_axis, const real_t p_value) { + ERR_FAIL_INDEX(p_axis, 4); + components[p_axis] = p_value; +} + +real_t Vector4::get_axis(const int p_axis) const { + ERR_FAIL_INDEX_V(p_axis, 4, 0); + return operator[](p_axis); +} + +Vector4::Axis Vector4::min_axis_index() const { + uint32_t min_index = 0; + real_t min_value = x; + for (uint32_t i = 1; i < 4; i++) { + if (operator[](i) <= min_value) { + min_index = i; + min_value = operator[](i); + } + } + return Vector4::Axis(min_index); +} + +Vector4::Axis Vector4::max_axis_index() const { + uint32_t max_index = 0; + real_t max_value = x; + for (uint32_t i = 1; i < 4; i++) { + if (operator[](i) > max_value) { + max_index = i; + max_value = operator[](i); + } + } + return Vector4::Axis(max_index); +} + bool Vector4::is_equal_approx(const Vector4 &p_vec4) const { return Math::is_equal_approx(x, p_vec4.x) && Math::is_equal_approx(y, p_vec4.y) && Math::is_equal_approx(z, p_vec4.z) && Math::is_equal_approx(w, p_vec4.w); } @@ -50,7 +84,17 @@ Vector4 Vector4::normalized() const { } bool Vector4::is_normalized() const { - return Math::is_equal_approx(length_squared(), 1, (real_t)UNIT_EPSILON); //use less epsilon + return Math::is_equal_approx(length_squared(), 1, (real_t)UNIT_EPSILON); // Use less epsilon. +} + +real_t Vector4::distance_to(const Vector4 &p_to) const { + return (p_to - *this).length(); +} + +Vector4 Vector4::direction_to(const Vector4 &p_to) const { + Vector4 ret(p_to.x - x, p_to.y - y, p_to.z - z, p_to.w - w); + ret.normalize(); + return ret; } Vector4 Vector4::abs() const { @@ -61,32 +105,58 @@ Vector4 Vector4::sign() const { return Vector4(SIGN(x), SIGN(y), SIGN(z), SIGN(w)); } -Vector4 Vector4::inverse() const { - return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w); +Vector4 Vector4::floor() const { + return Vector4(Math::floor(x), Math::floor(y), Math::floor(z), Math::floor(w)); } -Vector4::Axis Vector4::min_axis_index() const { - uint32_t min_index = 0; - real_t min_value = x; - for (uint32_t i = 1; i < 4; i++) { - if (operator[](i) < min_value) { - min_index = i; - min_value = operator[](i); - } - } - return Vector4::Axis(min_index); +Vector4 Vector4::ceil() const { + return Vector4(Math::ceil(x), Math::ceil(y), Math::ceil(z), Math::ceil(w)); } -Vector4::Axis Vector4::max_axis_index() const { - uint32_t max_index = 0; - real_t max_value = x; - for (uint32_t i = 1; i < 4; i++) { - if (operator[](i) > max_value) { - max_index = i; - max_value = operator[](i); - } - } - return Vector4::Axis(max_index); +Vector4 Vector4::round() const { + return Vector4(Math::round(x), Math::round(y), Math::round(z), Math::round(w)); +} + +Vector4 Vector4::lerp(const Vector4 &p_to, const real_t p_weight) const { + return Vector4( + x + (p_weight * (p_to.x - x)), + y + (p_weight * (p_to.y - y)), + z + (p_weight * (p_to.z - z)), + w + (p_weight * (p_to.w - w))); +} + +Vector4 Vector4::cubic_interpolate(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, const real_t p_weight) const { + Vector4 res = *this; + res.x = Math::cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight); + res.y = Math::cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight); + res.z = Math::cubic_interpolate(res.z, p_b.z, p_pre_a.z, p_post_b.z, p_weight); + res.w = Math::cubic_interpolate(res.w, p_b.w, p_pre_a.w, p_post_b.w, p_weight); + return res; +} + +Vector4 Vector4::posmod(const real_t p_mod) const { + return Vector4(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod), Math::fposmod(z, p_mod), Math::fposmod(w, p_mod)); +} + +Vector4 Vector4::posmodv(const Vector4 &p_modv) const { + return Vector4(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y), Math::fposmod(z, p_modv.z), Math::fposmod(w, p_modv.w)); +} + +void Vector4::snap(const Vector4 &p_step) { + x = Math::snapped(x, p_step.x); + y = Math::snapped(y, p_step.y); + z = Math::snapped(z, p_step.z); + w = Math::snapped(w, p_step.w); +} + +Vector4 Vector4::snapped(const Vector4 &p_step) const { + Vector4 v = *this; + v.snap(p_step); + return v; +} + +Vector4 Vector4::inverse() const { + return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w); } Vector4 Vector4::clamp(const Vector4 &p_min, const Vector4 &p_max) const { diff --git a/core/math/vector4.h b/core/math/vector4.h index 645c51db87..373a6a1218 100644 --- a/core/math/vector4.h +++ b/core/math/vector4.h @@ -54,23 +54,45 @@ struct _NO_DISCARD_ Vector4 { real_t components[4] = { 0, 0, 0, 0 }; }; - _FORCE_INLINE_ real_t &operator[](int idx) { - return components[idx]; + _FORCE_INLINE_ real_t &operator[](const int p_axis) { + DEV_ASSERT((unsigned int)p_axis < 4); + return components[p_axis]; } - _FORCE_INLINE_ const real_t &operator[](int idx) const { - return components[idx]; + _FORCE_INLINE_ const real_t &operator[](const int p_axis) const { + DEV_ASSERT((unsigned int)p_axis < 4); + return components[p_axis]; } + + _FORCE_INLINE_ void set_all(const real_t p_value); + + void set_axis(const int p_axis, const real_t p_value); + real_t get_axis(const int p_axis) const; + + Vector4::Axis min_axis_index() const; + Vector4::Axis max_axis_index() const; + _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Vector4 &p_vec4) const; real_t length() const; void normalize(); Vector4 normalized() const; bool is_normalized() const; + + real_t distance_to(const Vector4 &p_to) const; + Vector4 direction_to(const Vector4 &p_to) const; + Vector4 abs() const; Vector4 sign() const; - - Vector4::Axis min_axis_index() const; - Vector4::Axis max_axis_index() const; + Vector4 floor() const; + Vector4 ceil() const; + Vector4 round() const; + Vector4 lerp(const Vector4 &p_to, const real_t p_weight) const; + Vector4 cubic_interpolate(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, const real_t p_weight) const; + + Vector4 posmod(const real_t p_mod) const; + Vector4 posmodv(const Vector4 &p_modv) const; + void snap(const Vector4 &p_step); + Vector4 snapped(const Vector4 &p_step) const; Vector4 clamp(const Vector4 &p_min, const Vector4 &p_max) const; Vector4 inverse() const; @@ -123,6 +145,10 @@ struct _NO_DISCARD_ Vector4 { } }; +void Vector4::set_all(const real_t p_value) { + x = y = z = p_value; +} + real_t Vector4::dot(const Vector4 &p_vec4) const { return x * p_vec4.x + y * p_vec4.y + z * p_vec4.z + w * p_vec4.w; } @@ -186,7 +212,7 @@ Vector4 Vector4::operator/(const Vector4 &p_vec4) const { } Vector4 Vector4::operator-() const { - return Vector4(x, y, z, w); + return Vector4(-x, -y, -z, -w); } Vector4 Vector4::operator*(const real_t &s) const { diff --git a/core/math/vector4i.cpp b/core/math/vector4i.cpp index 8c571b02e3..2dc5b74202 100644 --- a/core/math/vector4i.cpp +++ b/core/math/vector4i.cpp @@ -47,7 +47,7 @@ Vector4i::Axis Vector4i::min_axis_index() const { uint32_t min_index = 0; int32_t min_value = x; for (uint32_t i = 1; i < 4; i++) { - if (operator[](i) < min_value) { + if (operator[](i) <= min_value) { min_index = i; min_value = operator[](i); } diff --git a/core/multiplayer/SCsub b/core/multiplayer/SCsub deleted file mode 100644 index 19a6549225..0000000000 --- a/core/multiplayer/SCsub +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -env.add_source_files(env.core_sources, "*.cpp") diff --git a/core/multiplayer/multiplayer_api.cpp b/core/multiplayer/multiplayer_api.cpp deleted file mode 100644 index 6cce31e0d1..0000000000 --- a/core/multiplayer/multiplayer_api.cpp +++ /dev/null @@ -1,593 +0,0 @@ -/*************************************************************************/ -/* multiplayer_api.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "multiplayer_api.h" - -#include "core/debugger/engine_debugger.h" -#include "core/io/marshalls.h" - -#include <stdint.h> - -#ifdef DEBUG_ENABLED -#include "core/os/os.h" -#endif - -MultiplayerReplicationInterface *(*MultiplayerAPI::create_default_replication_interface)(MultiplayerAPI *p_multiplayer) = nullptr; -MultiplayerRPCInterface *(*MultiplayerAPI::create_default_rpc_interface)(MultiplayerAPI *p_multiplayer) = nullptr; -MultiplayerCacheInterface *(*MultiplayerAPI::create_default_cache_interface)(MultiplayerAPI *p_multiplayer) = nullptr; - -#ifdef DEBUG_ENABLED -void MultiplayerAPI::profile_bandwidth(const String &p_inout, int p_size) { - if (EngineDebugger::is_profiling("multiplayer")) { - Array values; - values.push_back(p_inout); - values.push_back(OS::get_singleton()->get_ticks_msec()); - values.push_back(p_size); - EngineDebugger::profiler_add_frame_data("multiplayer", values); - } -} -#endif - -void MultiplayerAPI::poll() { - if (!multiplayer_peer.is_valid() || multiplayer_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED) { - return; - } - - multiplayer_peer->poll(); - - if (!multiplayer_peer.is_valid()) { // It's possible that polling might have resulted in a disconnection, so check here. - return; - } - - while (multiplayer_peer->get_available_packet_count()) { - int sender = multiplayer_peer->get_packet_peer(); - const uint8_t *packet; - int len; - - Error err = multiplayer_peer->get_packet(&packet, len); - if (err != OK) { - ERR_PRINT("Error getting packet!"); - return; // Something is wrong! - } - - remote_sender_id = sender; - _process_packet(sender, packet, len); - remote_sender_id = 0; - - if (!multiplayer_peer.is_valid()) { - return; // It's also possible that a packet or RPC caused a disconnection, so also check here. - } - } - replicator->on_network_process(); -} - -void MultiplayerAPI::clear() { - connected_peers.clear(); - packet_cache.clear(); - cache->clear(); -} - -void MultiplayerAPI::set_root_path(const NodePath &p_path) { - ERR_FAIL_COND_MSG(!p_path.is_absolute() && !p_path.is_empty(), "MultiplayerAPI root path must be absolute."); - root_path = p_path; -} - -NodePath MultiplayerAPI::get_root_path() const { - return root_path; -} - -void MultiplayerAPI::set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) { - if (p_peer == multiplayer_peer) { - return; // Nothing to do - } - - ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED, - "Supplied MultiplayerPeer must be connecting or connected."); - - if (multiplayer_peer.is_valid()) { - multiplayer_peer->disconnect("peer_connected", callable_mp(this, &MultiplayerAPI::_add_peer)); - multiplayer_peer->disconnect("peer_disconnected", callable_mp(this, &MultiplayerAPI::_del_peer)); - multiplayer_peer->disconnect("connection_succeeded", callable_mp(this, &MultiplayerAPI::_connected_to_server)); - multiplayer_peer->disconnect("connection_failed", callable_mp(this, &MultiplayerAPI::_connection_failed)); - multiplayer_peer->disconnect("server_disconnected", callable_mp(this, &MultiplayerAPI::_server_disconnected)); - clear(); - } - - multiplayer_peer = p_peer; - - if (multiplayer_peer.is_valid()) { - multiplayer_peer->connect("peer_connected", callable_mp(this, &MultiplayerAPI::_add_peer)); - multiplayer_peer->connect("peer_disconnected", callable_mp(this, &MultiplayerAPI::_del_peer)); - multiplayer_peer->connect("connection_succeeded", callable_mp(this, &MultiplayerAPI::_connected_to_server)); - multiplayer_peer->connect("connection_failed", callable_mp(this, &MultiplayerAPI::_connection_failed)); - multiplayer_peer->connect("server_disconnected", callable_mp(this, &MultiplayerAPI::_server_disconnected)); - } - replicator->on_reset(); -} - -Ref<MultiplayerPeer> MultiplayerAPI::get_multiplayer_peer() const { - return multiplayer_peer; -} - -void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) { - ERR_FAIL_COND_MSG(root_path.is_empty(), "Multiplayer root was not initialized. If you are using custom multiplayer, remember to set the root path via MultiplayerAPI.set_root_path before using it."); - ERR_FAIL_COND_MSG(p_packet_len < 1, "Invalid packet received. Size too small."); - -#ifdef DEBUG_ENABLED - profile_bandwidth("in", p_packet_len); -#endif - - // Extract the `packet_type` from the LSB three bits: - uint8_t packet_type = p_packet[0] & CMD_MASK; - - switch (packet_type) { - case NETWORK_COMMAND_SIMPLIFY_PATH: { - cache->process_simplify_path(p_from, p_packet, p_packet_len); - } break; - - case NETWORK_COMMAND_CONFIRM_PATH: { - cache->process_confirm_path(p_from, p_packet, p_packet_len); - } break; - - case NETWORK_COMMAND_REMOTE_CALL: { - rpc->process_rpc(p_from, p_packet, p_packet_len); - } break; - - case NETWORK_COMMAND_RAW: { - _process_raw(p_from, p_packet, p_packet_len); - } break; - case NETWORK_COMMAND_SPAWN: { - replicator->on_spawn_receive(p_from, p_packet, p_packet_len); - } break; - case NETWORK_COMMAND_DESPAWN: { - replicator->on_despawn_receive(p_from, p_packet, p_packet_len); - } break; - case NETWORK_COMMAND_SYNC: { - replicator->on_sync_receive(p_from, p_packet, p_packet_len); - } break; - } -} - -// The variant is compressed and encoded; The first byte contains all the meta -// information and the format is: -// - The first LSB 5 bits are used for the variant type. -// - The next two bits are used to store the encoding mode. -// - The most significant is used to store the boolean value. -#define VARIANT_META_TYPE_MASK 0x1F -#define VARIANT_META_EMODE_MASK 0x60 -#define VARIANT_META_BOOL_MASK 0x80 -#define ENCODE_8 0 << 5 -#define ENCODE_16 1 << 5 -#define ENCODE_32 2 << 5 -#define ENCODE_64 3 << 5 -Error MultiplayerAPI::encode_and_compress_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_allow_object_decoding) { - // Unreachable because `VARIANT_MAX` == 27 and `ENCODE_VARIANT_MASK` == 31 - CRASH_COND(p_variant.get_type() > VARIANT_META_TYPE_MASK); - - uint8_t *buf = r_buffer; - r_len = 0; - uint8_t encode_mode = 0; - - switch (p_variant.get_type()) { - case Variant::BOOL: { - if (buf) { - // We still have 1 free bit in the meta, so let's use it. - buf[0] = (p_variant.operator bool()) ? (1 << 7) : 0; - buf[0] |= encode_mode | p_variant.get_type(); - } - r_len += 1; - } break; - case Variant::INT: { - if (buf) { - // Reserve the first byte for the meta. - buf += 1; - } - r_len += 1; - int64_t val = p_variant; - if (val <= (int64_t)INT8_MAX && val >= (int64_t)INT8_MIN) { - // Use 8 bit - encode_mode = ENCODE_8; - if (buf) { - buf[0] = val; - } - r_len += 1; - } else if (val <= (int64_t)INT16_MAX && val >= (int64_t)INT16_MIN) { - // Use 16 bit - encode_mode = ENCODE_16; - if (buf) { - encode_uint16(val, buf); - } - r_len += 2; - } else if (val <= (int64_t)INT32_MAX && val >= (int64_t)INT32_MIN) { - // Use 32 bit - encode_mode = ENCODE_32; - if (buf) { - encode_uint32(val, buf); - } - r_len += 4; - } else { - // Use 64 bit - encode_mode = ENCODE_64; - if (buf) { - encode_uint64(val, buf); - } - r_len += 8; - } - // Store the meta - if (buf) { - buf -= 1; - buf[0] = encode_mode | p_variant.get_type(); - } - } break; - default: - // Any other case is not yet compressed. - Error err = encode_variant(p_variant, r_buffer, r_len, p_allow_object_decoding); - if (err != OK) { - return err; - } - if (r_buffer) { - // The first byte is not used by the marshalling, so store the type - // so we know how to decompress and decode this variant. - r_buffer[0] = p_variant.get_type(); - } - } - - return OK; -} - -Error MultiplayerAPI::decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_object_decoding) { - const uint8_t *buf = p_buffer; - int len = p_len; - - ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA); - uint8_t type = buf[0] & VARIANT_META_TYPE_MASK; - uint8_t encode_mode = buf[0] & VARIANT_META_EMODE_MASK; - - ERR_FAIL_COND_V(type >= Variant::VARIANT_MAX, ERR_INVALID_DATA); - - switch (type) { - case Variant::BOOL: { - bool val = (buf[0] & VARIANT_META_BOOL_MASK) > 0; - r_variant = val; - if (r_len) { - *r_len = 1; - } - } break; - case Variant::INT: { - buf += 1; - len -= 1; - if (r_len) { - *r_len = 1; - } - if (encode_mode == ENCODE_8) { - // 8 bits. - ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA); - int8_t val = buf[0]; - r_variant = val; - if (r_len) { - (*r_len) += 1; - } - } else if (encode_mode == ENCODE_16) { - // 16 bits. - ERR_FAIL_COND_V(len < 2, ERR_INVALID_DATA); - int16_t val = decode_uint16(buf); - r_variant = val; - if (r_len) { - (*r_len) += 2; - } - } else if (encode_mode == ENCODE_32) { - // 32 bits. - ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); - int32_t val = decode_uint32(buf); - r_variant = val; - if (r_len) { - (*r_len) += 4; - } - } else { - // 64 bits. - ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); - int64_t val = decode_uint64(buf); - r_variant = val; - if (r_len) { - (*r_len) += 8; - } - } - } break; - default: - Error err = decode_variant(r_variant, p_buffer, p_len, r_len, p_allow_object_decoding); - if (err != OK) { - return err; - } - } - - return OK; -} - -Error MultiplayerAPI::encode_and_compress_variants(const Variant **p_variants, int p_count, uint8_t *p_buffer, int &r_len, bool *r_raw, bool p_allow_object_decoding) { - r_len = 0; - int size = 0; - - if (p_count == 0) { - if (r_raw) { - *r_raw = true; - } - return OK; - } - - // Try raw encoding optimization. - if (r_raw && p_count == 1) { - *r_raw = false; - const Variant &v = *(p_variants[0]); - if (v.get_type() == Variant::PACKED_BYTE_ARRAY) { - *r_raw = true; - const PackedByteArray pba = v; - if (p_buffer) { - memcpy(p_buffer, pba.ptr(), pba.size()); - } - r_len += pba.size(); - } else { - encode_and_compress_variant(v, p_buffer, size, p_allow_object_decoding); - r_len += size; - } - return OK; - } - - // Regular encoding. - for (int i = 0; i < p_count; i++) { - const Variant &v = *(p_variants[i]); - encode_and_compress_variant(v, p_buffer ? p_buffer + r_len : nullptr, size, p_allow_object_decoding); - r_len += size; - } - return OK; -} - -Error MultiplayerAPI::decode_and_decompress_variants(Vector<Variant> &r_variants, const uint8_t *p_buffer, int p_len, int &r_len, bool p_raw, bool p_allow_object_decoding) { - r_len = 0; - int argc = r_variants.size(); - if (argc == 0 && p_raw) { - return OK; - } - ERR_FAIL_COND_V(p_raw && argc != 1, ERR_INVALID_DATA); - if (p_raw) { - r_len = p_len; - PackedByteArray pba; - pba.resize(p_len); - memcpy(pba.ptrw(), p_buffer, p_len); - r_variants.write[0] = pba; - return OK; - } - - Vector<Variant> args; - Vector<const Variant *> argp; - args.resize(argc); - - for (int i = 0; i < argc; i++) { - ERR_FAIL_COND_V_MSG(r_len >= p_len, ERR_INVALID_DATA, "Invalid packet received. Size too small."); - - int vlen; - Error err = MultiplayerAPI::decode_and_decompress_variant(r_variants.write[i], &p_buffer[r_len], p_len - r_len, &vlen, p_allow_object_decoding); - ERR_FAIL_COND_V_MSG(err != OK, err, "Invalid packet received. Unable to decode state variable."); - r_len += vlen; - } - return OK; -} - -void MultiplayerAPI::_add_peer(int p_id) { - connected_peers.insert(p_id); - cache->on_peer_change(p_id, true); - replicator->on_peer_change(p_id, true); - emit_signal(SNAME("peer_connected"), p_id); -} - -void MultiplayerAPI::_del_peer(int p_id) { - replicator->on_peer_change(p_id, false); - cache->on_peer_change(p_id, false); - connected_peers.erase(p_id); - emit_signal(SNAME("peer_disconnected"), p_id); -} - -void MultiplayerAPI::_connected_to_server() { - emit_signal(SNAME("connected_to_server")); -} - -void MultiplayerAPI::_connection_failed() { - emit_signal(SNAME("connection_failed")); -} - -void MultiplayerAPI::_server_disconnected() { - replicator->on_reset(); - emit_signal(SNAME("server_disconnected")); -} - -Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, Multiplayer::TransferMode p_mode, int p_channel) { - ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet."); - ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no multiplayer peer is active."); - ERR_FAIL_COND_V_MSG(multiplayer_peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED, "Trying to send a raw packet via a multiplayer peer which is not connected."); - - if (packet_cache.size() < p_data.size() + 1) { - packet_cache.resize(p_data.size() + 1); - } - - const uint8_t *r = p_data.ptr(); - packet_cache.write[0] = NETWORK_COMMAND_RAW; - memcpy(&packet_cache.write[1], &r[0], p_data.size()); - - multiplayer_peer->set_target_peer(p_to); - multiplayer_peer->set_transfer_channel(p_channel); - multiplayer_peer->set_transfer_mode(p_mode); - - return multiplayer_peer->put_packet(packet_cache.ptr(), p_data.size() + 1); -} - -void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) { - ERR_FAIL_COND_MSG(p_packet_len < 2, "Invalid packet received. Size too small."); - - Vector<uint8_t> out; - int len = p_packet_len - 1; - out.resize(len); - { - uint8_t *w = out.ptrw(); - memcpy(&w[0], &p_packet[1], len); - } - emit_signal(SNAME("peer_packet"), p_from, out); -} - -bool MultiplayerAPI::is_cache_confirmed(NodePath p_path, int p_peer) { - return cache->is_cache_confirmed(p_path, p_peer); -} - -bool MultiplayerAPI::send_object_cache(Object *p_obj, int p_peer_id, int &r_id) { - return cache->send_object_cache(p_obj, p_peer_id, r_id); -} - -int MultiplayerAPI::make_object_cache(Object *p_obj) { - return cache->make_object_cache(p_obj); -} - -Object *MultiplayerAPI::get_cached_object(int p_from, uint32_t p_cache_id) { - return cache->get_cached_object(p_from, p_cache_id); -} - -int MultiplayerAPI::get_unique_id() const { - ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), 0, "No multiplayer peer is assigned. Unable to get unique ID."); - return multiplayer_peer->get_unique_id(); -} - -bool MultiplayerAPI::is_server() const { - return multiplayer_peer.is_valid() && multiplayer_peer->is_server(); -} - -void MultiplayerAPI::set_refuse_new_connections(bool p_refuse) { - ERR_FAIL_COND_MSG(!multiplayer_peer.is_valid(), "No multiplayer peer is assigned. Unable to set 'refuse_new_connections'."); - multiplayer_peer->set_refuse_new_connections(p_refuse); -} - -bool MultiplayerAPI::is_refusing_new_connections() const { - ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), false, "No multiplayer peer is assigned. Unable to get 'refuse_new_connections'."); - return multiplayer_peer->is_refusing_new_connections(); -} - -Vector<int> MultiplayerAPI::get_peer_ids() const { - ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), Vector<int>(), "No multiplayer peer is assigned. Assume no peers are connected."); - - Vector<int> ret; - for (const int &E : connected_peers) { - ret.push_back(E); - } - - return ret; -} - -void MultiplayerAPI::set_allow_object_decoding(bool p_enable) { - allow_object_decoding = p_enable; -} - -bool MultiplayerAPI::is_object_decoding_allowed() const { - return allow_object_decoding; -} - -String MultiplayerAPI::get_rpc_md5(const Object *p_obj) const { - return rpc->get_rpc_md5(p_obj); -} - -void MultiplayerAPI::rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { - rpc->rpcp(p_obj, p_peer_id, p_method, p_arg, p_argcount); -} - -Error MultiplayerAPI::spawn(Object *p_object, Variant p_config) { - return replicator->on_spawn(p_object, p_config); -} - -Error MultiplayerAPI::despawn(Object *p_object, Variant p_config) { - return replicator->on_despawn(p_object, p_config); -} - -Error MultiplayerAPI::replication_start(Object *p_object, Variant p_config) { - return replicator->on_replication_start(p_object, p_config); -} - -Error MultiplayerAPI::replication_stop(Object *p_object, Variant p_config) { - return replicator->on_replication_stop(p_object, p_config); -} - -void MultiplayerAPI::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_root_path", "path"), &MultiplayerAPI::set_root_path); - ClassDB::bind_method(D_METHOD("get_root_path"), &MultiplayerAPI::get_root_path); - ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode", "channel"), &MultiplayerAPI::send_bytes, DEFVAL(MultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(Multiplayer::TRANSFER_MODE_RELIABLE), DEFVAL(0)); - ClassDB::bind_method(D_METHOD("has_multiplayer_peer"), &MultiplayerAPI::has_multiplayer_peer); - ClassDB::bind_method(D_METHOD("get_multiplayer_peer"), &MultiplayerAPI::get_multiplayer_peer); - ClassDB::bind_method(D_METHOD("set_multiplayer_peer", "peer"), &MultiplayerAPI::set_multiplayer_peer); - ClassDB::bind_method(D_METHOD("get_unique_id"), &MultiplayerAPI::get_unique_id); - ClassDB::bind_method(D_METHOD("is_server"), &MultiplayerAPI::is_server); - ClassDB::bind_method(D_METHOD("get_remote_sender_id"), &MultiplayerAPI::get_remote_sender_id); - ClassDB::bind_method(D_METHOD("poll"), &MultiplayerAPI::poll); - ClassDB::bind_method(D_METHOD("clear"), &MultiplayerAPI::clear); - - ClassDB::bind_method(D_METHOD("get_peers"), &MultiplayerAPI::get_peer_ids); - ClassDB::bind_method(D_METHOD("set_refuse_new_connections", "refuse"), &MultiplayerAPI::set_refuse_new_connections); - ClassDB::bind_method(D_METHOD("is_refusing_new_connections"), &MultiplayerAPI::is_refusing_new_connections); - ClassDB::bind_method(D_METHOD("set_allow_object_decoding", "enable"), &MultiplayerAPI::set_allow_object_decoding); - ClassDB::bind_method(D_METHOD("is_object_decoding_allowed"), &MultiplayerAPI::is_object_decoding_allowed); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_object_decoding"), "set_allow_object_decoding", "is_object_decoding_allowed"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_connections"), "set_refuse_new_connections", "is_refusing_new_connections"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer_peer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerPeer", PROPERTY_USAGE_NONE), "set_multiplayer_peer", "get_multiplayer_peer"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_path"), "set_root_path", "get_root_path"); - ADD_PROPERTY_DEFAULT("refuse_new_connections", false); - - ADD_SIGNAL(MethodInfo("peer_connected", PropertyInfo(Variant::INT, "id"))); - ADD_SIGNAL(MethodInfo("peer_disconnected", PropertyInfo(Variant::INT, "id"))); - ADD_SIGNAL(MethodInfo("peer_packet", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::PACKED_BYTE_ARRAY, "packet"))); - ADD_SIGNAL(MethodInfo("connected_to_server")); - ADD_SIGNAL(MethodInfo("connection_failed")); - ADD_SIGNAL(MethodInfo("server_disconnected")); -} - -MultiplayerAPI::MultiplayerAPI() { - if (create_default_replication_interface) { - replicator = Ref<MultiplayerReplicationInterface>(create_default_replication_interface(this)); - } else { - replicator.instantiate(); - } - if (create_default_rpc_interface) { - rpc = Ref<MultiplayerRPCInterface>(create_default_rpc_interface(this)); - } else { - rpc.instantiate(); - } - if (create_default_cache_interface) { - cache = Ref<MultiplayerCacheInterface>(create_default_cache_interface(this)); - } else { - cache.instantiate(); - } -} - -MultiplayerAPI::~MultiplayerAPI() { - clear(); -} diff --git a/core/multiplayer/multiplayer_api.h b/core/multiplayer/multiplayer_api.h deleted file mode 100644 index 35452acb1f..0000000000 --- a/core/multiplayer/multiplayer_api.h +++ /dev/null @@ -1,196 +0,0 @@ -/*************************************************************************/ -/* multiplayer_api.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef MULTIPLAYER_API_H -#define MULTIPLAYER_API_H - -#include "core/multiplayer/multiplayer.h" -#include "core/multiplayer/multiplayer_peer.h" -#include "core/object/ref_counted.h" - -class MultiplayerAPI; - -class MultiplayerReplicationInterface : public RefCounted { - GDCLASS(MultiplayerReplicationInterface, RefCounted); - -public: - virtual void on_peer_change(int p_id, bool p_connected) {} - virtual void on_reset() {} - virtual Error on_spawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) { return ERR_UNAVAILABLE; } - virtual Error on_despawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) { return ERR_UNAVAILABLE; } - virtual Error on_sync_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) { return ERR_UNAVAILABLE; } - virtual Error on_spawn(Object *p_obj, Variant p_config) { return ERR_UNAVAILABLE; } - virtual Error on_despawn(Object *p_obj, Variant p_config) { return ERR_UNAVAILABLE; } - virtual Error on_replication_start(Object *p_obj, Variant p_config) { return ERR_UNAVAILABLE; } - virtual Error on_replication_stop(Object *p_obj, Variant p_config) { return ERR_UNAVAILABLE; } - virtual void on_network_process() {} - - MultiplayerReplicationInterface() {} -}; - -class MultiplayerRPCInterface : public RefCounted { - GDCLASS(MultiplayerRPCInterface, RefCounted); - -public: - // Called by Node.rpc - virtual void rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) {} - virtual void process_rpc(int p_from, const uint8_t *p_packet, int p_packet_len) {} - virtual String get_rpc_md5(const Object *p_obj) const { return String(); } - - MultiplayerRPCInterface() {} -}; - -class MultiplayerCacheInterface : public RefCounted { - GDCLASS(MultiplayerCacheInterface, RefCounted); - -public: - virtual void clear() {} - virtual void on_peer_change(int p_id, bool p_connected) {} - virtual void process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) {} - virtual void process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {} - - // Returns true if all peers have cached path. - virtual bool send_object_cache(Object *p_obj, int p_target, int &r_id) { return false; } - virtual int make_object_cache(Object *p_obj) { return false; } - virtual Object *get_cached_object(int p_from, uint32_t p_cache_id) { return nullptr; } - virtual bool is_cache_confirmed(NodePath p_path, int p_peer) { return false; } - - MultiplayerCacheInterface() {} -}; - -class MultiplayerAPI : public RefCounted { - GDCLASS(MultiplayerAPI, RefCounted); - -public: - enum NetworkCommands { - NETWORK_COMMAND_REMOTE_CALL = 0, - NETWORK_COMMAND_SIMPLIFY_PATH, - NETWORK_COMMAND_CONFIRM_PATH, - NETWORK_COMMAND_RAW, - NETWORK_COMMAND_SPAWN, - NETWORK_COMMAND_DESPAWN, - NETWORK_COMMAND_SYNC, - }; - - // For each command, the 4 MSB can contain custom flags, as defined by subsystems. - enum { - CMD_FLAG_0_SHIFT = 4, - CMD_FLAG_1_SHIFT = 5, - CMD_FLAG_2_SHIFT = 6, - CMD_FLAG_3_SHIFT = 7, - }; - - // This is the mask that will be used to extract the command. - enum { - CMD_MASK = 7, // 0x7 -> 0b00001111 - }; - -private: - Ref<MultiplayerPeer> multiplayer_peer; - HashSet<int> connected_peers; - int remote_sender_id = 0; - int remote_sender_override = 0; - - Vector<uint8_t> packet_cache; - - NodePath root_path; - bool allow_object_decoding = false; - - Ref<MultiplayerCacheInterface> cache; - Ref<MultiplayerReplicationInterface> replicator; - Ref<MultiplayerRPCInterface> rpc; - -protected: - static void _bind_methods(); - - void _process_packet(int p_from, const uint8_t *p_packet, int p_packet_len); - void _process_raw(int p_from, const uint8_t *p_packet, int p_packet_len); - -public: - static MultiplayerReplicationInterface *(*create_default_replication_interface)(MultiplayerAPI *p_multiplayer); - static MultiplayerRPCInterface *(*create_default_rpc_interface)(MultiplayerAPI *p_multiplayer); - static MultiplayerCacheInterface *(*create_default_cache_interface)(MultiplayerAPI *p_multiplayer); - - static Error encode_and_compress_variant(const Variant &p_variant, uint8_t *p_buffer, int &r_len, bool p_allow_object_decoding); - static Error decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_object_decoding); - static Error encode_and_compress_variants(const Variant **p_variants, int p_count, uint8_t *p_buffer, int &r_len, bool *r_raw = nullptr, bool p_allow_object_decoding = false); - static Error decode_and_decompress_variants(Vector<Variant> &r_variants, const uint8_t *p_buffer, int p_len, int &r_len, bool p_raw = false, bool p_allow_object_decoding = false); - - void poll(); - void clear(); - void set_root_path(const NodePath &p_path); - NodePath get_root_path() const; - void set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer); - Ref<MultiplayerPeer> get_multiplayer_peer() const; - - Error send_bytes(Vector<uint8_t> p_data, int p_to = MultiplayerPeer::TARGET_PEER_BROADCAST, Multiplayer::TransferMode p_mode = Multiplayer::TRANSFER_MODE_RELIABLE, int p_channel = 0); - - // RPC API - void rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount); - String get_rpc_md5(const Object *p_obj) const; - // Replication API - Error spawn(Object *p_object, Variant p_config); - Error despawn(Object *p_object, Variant p_config); - Error replication_start(Object *p_object, Variant p_config); - Error replication_stop(Object *p_object, Variant p_config); - // Cache API - bool send_object_cache(Object *p_obj, int p_target, int &r_id); - int make_object_cache(Object *p_obj); - Object *get_cached_object(int p_from, uint32_t p_cache_id); - bool is_cache_confirmed(NodePath p_path, int p_peer); - - void _add_peer(int p_id); - void _del_peer(int p_id); - void _connected_to_server(); - void _connection_failed(); - void _server_disconnected(); - - bool has_multiplayer_peer() const { return multiplayer_peer.is_valid(); } - Vector<int> get_peer_ids() const; - const HashSet<int> get_connected_peers() const { return connected_peers; } - int get_remote_sender_id() const { return remote_sender_override ? remote_sender_override : remote_sender_id; } - void set_remote_sender_override(int p_id) { remote_sender_override = p_id; } - int get_unique_id() const; - bool is_server() const; - void set_refuse_new_connections(bool p_refuse); - bool is_refusing_new_connections() const; - - void set_allow_object_decoding(bool p_enable); - bool is_object_decoding_allowed() const; - -#ifdef DEBUG_ENABLED - void profile_bandwidth(const String &p_inout, int p_size); -#endif - - MultiplayerAPI(); - ~MultiplayerAPI(); -}; - -#endif // MULTIPLAYER_API_H diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index d67315f20d..9790cc44e3 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -963,8 +963,11 @@ void ClassDB::add_linked_property(const StringName &p_class, const String &p_pro 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); + if (!type->linked_properties.has(p_property)) { + type->linked_properties.insert(p_property, List<StringName>()); + } + type->linked_properties[p_property].push_back(p_linked_property); + #endif } @@ -992,6 +995,25 @@ void ClassDB::get_property_list(const StringName &p_class, List<PropertyInfo> *p } } +void ClassDB::get_linked_properties_info(const StringName &p_class, const StringName &p_property, List<StringName> *r_properties, bool p_no_inheritance) { +#ifdef TOOLS_ENABLED + ClassInfo *check = classes.getptr(p_class); + while (check) { + if (!check->linked_properties.has(p_property)) { + return; + } + for (const StringName &E : check->linked_properties[p_property]) { + r_properties->push_back(E); + } + + if (p_no_inheritance) { + break; + } + check = check->inherits_ptr; + } +#endif +} + bool ClassDB::get_property_info(const StringName &p_class, const StringName &p_property, PropertyInfo *r_info, 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 8b6a260d86..5fba52e23e 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -120,6 +120,7 @@ public: List<MethodInfo> virtual_methods; HashMap<StringName, MethodInfo> virtual_methods_map; HashMap<StringName, Vector<Error>> method_error_values; + HashMap<StringName, List<StringName>> linked_properties; #endif HashMap<StringName, PropertySetGet> property_setget; @@ -312,6 +313,7 @@ public: 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 void get_linked_properties_info(const StringName &p_class, const StringName &p_property, List<StringName> *r_properties, bool p_no_inheritance = false); static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = nullptr); static bool get_property(Object *p_object, const StringName &p_property, Variant &r_value); static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false); diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp index fa1945cf79..13dc921c9f 100644 --- a/core/object/message_queue.cpp +++ b/core/object/message_queue.cpp @@ -226,7 +226,7 @@ void MessageQueue::_call_function(const Callable &p_callable, const Variant *p_a Callable::CallError ce; Variant ret; - p_callable.call(argptrs, p_argcount, ret, ce); + p_callable.callp(argptrs, p_argcount, ret, ce); if (p_show_error && ce.error != Callable::CallError::CALL_OK) { ERR_PRINT("Error calling deferred method: " + Variant::get_callable_error_text(p_callable, argptrs, p_argcount, ce) + "."); } diff --git a/core/object/object.cpp b/core/object/object.cpp index 5f2287c9d3..0fcd1c0e40 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -166,7 +166,6 @@ Object::Connection::operator Variant() const { d["signal"] = signal; d["callable"] = callable; d["flags"] = flags; - d["binds"] = binds; return d; } @@ -189,9 +188,6 @@ Object::Connection::Connection(const Variant &p_variant) { if (d.has("flags")) { flags = d["flags"]; } - if (d.has("binds")) { - binds = d["binds"]; - } } bool Object::_predelete() { @@ -476,7 +472,6 @@ Variant Object::get_indexed(const Vector<StringName> &p_names, bool *r_valid) co void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) const { if (script_instance && p_reversed) { - p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); script_instance->get_property_list(p_list); } @@ -507,7 +502,6 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons } if (script_instance && !p_reversed) { - p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); script_instance->get_property_list(p_list); } @@ -973,8 +967,6 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int OBJ_DEBUG_LOCK - Vector<const Variant *> bind_mem; - Error err = OK; for (int i = 0; i < ssize; i++) { @@ -989,28 +981,13 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int const Variant **args = p_args; int argc = p_argcount; - if (c.binds.size()) { - //handle binds - bind_mem.resize(p_argcount + c.binds.size()); - - for (int j = 0; j < p_argcount; j++) { - bind_mem.write[j] = p_args[j]; - } - for (int j = 0; j < c.binds.size(); j++) { - bind_mem.write[p_argcount + j] = &c.binds[j]; - } - - args = (const Variant **)bind_mem.ptr(); - argc = bind_mem.size(); - } - if (c.flags & CONNECT_DEFERRED) { MessageQueue::get_singleton()->push_callablep(c.callable, args, argc, true); } else { Callable::CallError ce; _emitting = true; Variant ret; - c.callable.call(args, argc, ret, ce); + c.callable.callp(args, argc, ret, ce); _emitting = false; if (ce.error != Callable::CallError::CALL_OK) { @@ -1196,7 +1173,7 @@ void Object::get_signals_connected_to_this(List<Connection> *p_connections) cons } } -Error Object::connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) { +Error Object::connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags) { ERR_FAIL_COND_V_MSG(p_callable.is_null(), ERR_INVALID_PARAMETER, "Cannot connect to '" + p_signal + "': the provided callable is null."); Object *target_object = p_callable.get_object(); @@ -1244,7 +1221,6 @@ Error Object::connect(const StringName &p_signal, const Callable &p_callable, co conn.callable = target; conn.signal = ::Signal(this, p_signal); conn.flags = p_flags; - conn.binds = p_binds; slot.conn = conn; slot.cE = target_object->connections.push_back(conn); if (p_flags & CONNECT_REFERENCE_COUNTED) { @@ -1492,7 +1468,7 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("get_signal_connection_list", "signal"), &Object::_get_signal_connection_list); ClassDB::bind_method(D_METHOD("get_incoming_connections"), &Object::_get_incoming_connections); - ClassDB::bind_method(D_METHOD("connect", "signal", "callable", "binds", "flags"), &Object::connect, DEFVAL(Array()), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("connect", "signal", "callable", "flags"), &Object::connect, DEFVAL(0)); ClassDB::bind_method(D_METHOD("disconnect", "signal", "callable"), &Object::disconnect); ClassDB::bind_method(D_METHOD("is_connected", "signal", "callable"), &Object::is_connected); diff --git a/core/object/object.h b/core/object/object.h index 17f75a4e1d..35d0aaaa7d 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -50,7 +50,7 @@ enum PropertyHint { PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,no_slider][,radians][,degrees][,exp][,suffix:<keyword>] range. PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc" PROPERTY_HINT_ENUM_SUGGESTION, ///< hint_text= "val1,val2,val3,etc" - PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout") + PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "positive_only" to exclude in-out and out-in. (ie: "attenuation,positive_only") PROPERTY_HINT_LINK, PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags) PROPERTY_HINT_LAYERS_2D_RENDER, @@ -154,9 +154,7 @@ struct PropertyInfo { String hint_string; uint32_t usage = PROPERTY_USAGE_DEFAULT; -#ifdef TOOLS_ENABLED - Vector<String> linked_properties; -#endif + // If you are thinking about adding another member to this class, ask the maintainer (Juan) first. _FORCE_INLINE_ PropertyInfo added_usage(uint32_t p_fl) const { PropertyInfo pi = *this; @@ -510,7 +508,6 @@ public: Callable callable; uint32_t flags = 0; - Vector<Variant> binds; bool operator<(const Connection &p_conn) const; operator Variant() const; @@ -829,7 +826,7 @@ public: int get_persistent_signal_connection_count() const; void get_signals_connected_to_this(List<Connection> *p_connections) const; - Error connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0); + Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0); void disconnect(const StringName &p_signal, const Callable &p_callable); bool is_connected(const StringName &p_signal, const Callable &p_callable) const; diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 226fd8b791..b06c2e8896 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -101,6 +101,31 @@ Dictionary Script::_get_script_constant_map() { return ret; } +#ifdef TOOLS_ENABLED + +PropertyInfo Script::get_class_category() const { + String path = get_path(); + String name; + + if (is_built_in()) { + if (get_name().is_empty()) { + name = TTR("Built-in script"); + } else { + name = vformat("%s (%s)", get_name(), TTR("Built-in")); + } + } else { + if (get_name().is_empty()) { + name = path.get_file(); + } else { + name = get_name(); + } + } + + return PropertyInfo(Variant::NIL, name, PROPERTY_HINT_NONE, path, PROPERTY_USAGE_CATEGORY); +} + +#endif // TOOLS_ENABLED + void Script::_bind_methods() { ClassDB::bind_method(D_METHOD("can_instantiate"), &Script::can_instantiate); //ClassDB::bind_method(D_METHOD("instance_create","base_object"),&Script::instance_create); diff --git a/core/object/script_language.h b/core/object/script_language.h index 686ab5b8d3..f5f052b600 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -33,7 +33,6 @@ #include "core/doc_data.h" #include "core/io/resource.h" -#include "core/multiplayer/multiplayer.h" #include "core/templates/pair.h" #include "core/templates/rb_map.h" @@ -133,6 +132,7 @@ public: #ifdef TOOLS_ENABLED virtual Vector<DocData::ClassDoc> get_documentation() const = 0; + virtual PropertyInfo get_class_category() const; #endif // TOOLS_ENABLED virtual bool has_method(const StringName &p_method) const = 0; @@ -159,7 +159,7 @@ public: virtual bool is_placeholder_fallback_enabled() const { return false; } - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const = 0; + virtual const Variant get_rpc_config() const = 0; Script() {} }; @@ -213,7 +213,7 @@ public: virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid); virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid); - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const { return get_script()->get_rpc_methods(); } + virtual const Variant get_rpc_config() const { return get_script()->get_rpc_config(); } virtual ScriptLanguage *get_language() = 0; virtual ~ScriptInstance(); @@ -469,7 +469,7 @@ public: virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid = nullptr) override; virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid = nullptr) override; - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override { return Vector<Multiplayer::RPCConfig>(); } + virtual const Variant get_rpc_config() const override { return Variant(); } PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref<Script> p_script, Object *p_owner); ~PlaceHolderScriptInstance(); diff --git a/core/object/script_language_extension.cpp b/core/object/script_language_extension.cpp index ab8dd6d1ee..9de784ea7f 100644 --- a/core/object/script_language_extension.cpp +++ b/core/object/script_language_extension.cpp @@ -74,7 +74,7 @@ void ScriptExtension::_bind_methods() { GDVIRTUAL_BIND(_get_members); GDVIRTUAL_BIND(_is_placeholder_fallback_enabled); - GDVIRTUAL_BIND(_get_rpc_methods); + GDVIRTUAL_BIND(_get_rpc_config); } void ScriptLanguageExtension::_bind_methods() { diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 2c53139ec2..2869f4ad98 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -173,28 +173,12 @@ public: EXBIND0RC(bool, is_placeholder_fallback_enabled) - GDVIRTUAL0RC(TypedArray<Dictionary>, _get_rpc_methods) + GDVIRTUAL0RC(Variant, _get_rpc_config) - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override { - TypedArray<Dictionary> ret; - GDVIRTUAL_REQUIRED_CALL(_get_rpc_methods, ret); - Vector<Multiplayer::RPCConfig> rpcret; - for (int i = 0; i < ret.size(); i++) { - Dictionary d = ret[i]; - Multiplayer::RPCConfig rpc; - ERR_CONTINUE(!d.has("name")); - rpc.name = d["name"]; - ERR_CONTINUE(!d.has("rpc_mode")); - rpc.rpc_mode = Multiplayer::RPCMode(int(d["rpc_mode"])); - ERR_CONTINUE(!d.has("call_local")); - rpc.call_local = d["call_local"]; - ERR_CONTINUE(!d.has("transfer_mode")); - rpc.transfer_mode = Multiplayer::TransferMode(int(d["transfer_mode"])); - ERR_CONTINUE(!d.has("channel")); - rpc.channel = d["channel"]; - rpcret.push_back(rpc); - } - return rpcret; + virtual const Variant get_rpc_config() const override { + Variant ret; + GDVIRTUAL_REQUIRED_CALL(_get_rpc_config, ret); + return ret; } ScriptExtension() {} @@ -679,6 +663,14 @@ public: if (native_info->get_property_list_func) { uint32_t pcount; const GDNativePropertyInfo *pinfo = native_info->get_property_list_func(instance, &pcount); + +#ifdef TOOLS_ENABLED + Ref<Script> script = get_script(); + if (script->is_valid() && pcount > 0) { + p_list->push_back(script->get_class_category()); + } +#endif // TOOLS_ENABLED + for (uint32_t i = 0; i < pcount; i++) { p_list->push_back(PropertyInfo(pinfo[i])); } diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp index 54738a673e..c770515b9e 100644 --- a/core/object/worker_thread_pool.cpp +++ b/core/object/worker_thread_pool.cpp @@ -72,7 +72,7 @@ void WorkerThreadPool::_process_task(Task *p_task) { p_task->template_userdata->callback_indexed(work_index); } else { arg = work_index; - p_task->callable.call((const Variant **)&argptr, 1, ret, ce); + p_task->callable.callp((const Variant **)&argptr, 1, ret, ce); } // This is the only way to ensure posting is done when all tasks are really complete. @@ -123,7 +123,7 @@ void WorkerThreadPool::_process_task(Task *p_task) { } else { Callable::CallError ce; Variant ret; - p_task->callable.call(nullptr, 0, ret, ce); + p_task->callable.callp(nullptr, 0, ret, ce); } p_task->completed = true; diff --git a/core/os/memory.h b/core/os/memory.h index 42ba9634e2..0e1afe027e 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -36,6 +36,7 @@ #include <stddef.h> #include <new> +#include <type_traits> #ifndef PAD_ALIGN #define PAD_ALIGN 16 //must always be greater than this at much @@ -104,7 +105,7 @@ void memdelete(T *p_class) { if (!predelete_handler(p_class)) { return; // doesn't want to be deleted } - if (!__has_trivial_destructor(T)) { + if (!std::is_trivially_destructible<T>::value) { p_class->~T(); } @@ -116,7 +117,7 @@ void memdelete_allocator(T *p_class) { if (!predelete_handler(p_class)) { return; // doesn't want to be deleted } - if (!__has_trivial_destructor(T)) { + if (!std::is_trivially_destructible<T>::value) { p_class->~T(); } @@ -146,7 +147,7 @@ T *memnew_arr_template(size_t p_elements) { ERR_FAIL_COND_V(!mem, failptr); *(mem - 1) = p_elements; - if (!__has_trivial_constructor(T)) { + if (!std::is_trivially_constructible<T>::value) { T *elems = (T *)mem; /* call operator new */ @@ -173,7 +174,7 @@ template <typename T> void memdelete_arr(T *p_class) { uint64_t *ptr = (uint64_t *)p_class; - if (!__has_trivial_destructor(T)) { + if (!std::is_trivially_destructible<T>::value) { uint64_t elem_count = *(ptr - 1); for (uint64_t i = 0; i < elem_count; i++) { diff --git a/core/os/os.cpp b/core/os/os.cpp index b9daf6fa53..1358c926d1 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -159,7 +159,7 @@ int OS::get_process_id() const { } void OS::vibrate_handheld(int p_duration_ms) { - WARN_PRINT("vibrate_handheld() only works with Android and iOS"); + WARN_PRINT("vibrate_handheld() only works with Android, iOS and HTML5"); } bool OS::is_stdout_verbose() const { @@ -362,9 +362,10 @@ String OS::get_model_name() const { return "GenericDevice"; } -void OS::set_cmdline(const char *p_execpath, const List<String> &p_args) { +void OS::set_cmdline(const char *p_execpath, const List<String> &p_args, const List<String> &p_user_args) { _execpath = String::utf8(p_execpath); _cmdline = p_args; + _user_args = p_user_args; } String OS::get_unique_id() const { diff --git a/core/os/os.h b/core/os/os.h index 0428f6df2a..9152b797ef 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -46,6 +46,7 @@ class OS { static uint64_t target_ticks; String _execpath; List<String> _cmdline; + List<String> _user_args; bool _keep_screen_on = true; // set default value to true, because this had been true before godot 2.0. bool low_processor_usage_mode = false; int low_processor_usage_mode_sleep_usec = 10000; @@ -106,7 +107,7 @@ protected: virtual void finalize() = 0; virtual void finalize_core() = 0; - virtual void set_cmdline(const char *p_execpath, const List<String> &p_args); + virtual void set_cmdline(const char *p_execpath, const List<String> &p_args, const List<String> &p_user_args); virtual bool _check_internal_feature_support(const String &p_feature) = 0; @@ -142,6 +143,8 @@ public: virtual void set_low_processor_usage_mode_sleep_usec(int p_usec); virtual int get_low_processor_usage_mode_sleep_usec() const; + virtual Vector<String> get_system_fonts() const { return Vector<String>(); }; + virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const { return String(); }; virtual String get_executable_path() const; virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false) = 0; virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) = 0; @@ -160,6 +163,7 @@ public: virtual String get_name() const = 0; virtual List<String> get_cmdline_args() const { return _cmdline; } + virtual List<String> get_cmdline_user_args() const { return _user_args; } virtual List<String> get_cmdline_platform_args() const { return List<String>(); } virtual String get_model_name() const; diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index aab4b9a580..9ad6b0ca68 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -69,8 +69,6 @@ #include "core/math/geometry_3d.h" #include "core/math/random_number_generator.h" #include "core/math/triangle_mesh.h" -#include "core/multiplayer/multiplayer_api.h" -#include "core/multiplayer/multiplayer_peer.h" #include "core/object/class_db.h" #include "core/object/script_language_extension.h" #include "core/object/undo_redo.h" @@ -212,9 +210,6 @@ void register_core_types() { resource_format_loader_crypto.instantiate(); ResourceLoader::add_resource_format_loader(resource_format_loader_crypto); - GDREGISTER_ABSTRACT_CLASS(MultiplayerPeer); - GDREGISTER_CLASS(MultiplayerPeerExtension); - GDREGISTER_CLASS(MultiplayerAPI); GDREGISTER_CLASS(MainLoop); GDREGISTER_CLASS(Translation); GDREGISTER_CLASS(OptimizedTranslation); @@ -274,6 +269,7 @@ void register_core_types() { _marshalls = memnew(core_bind::Marshalls); _engine_debugger = memnew(core_bind::EngineDebugger); + GDREGISTER_NATIVE_STRUCT(ObjectID, "uint64_t id = 0"); GDREGISTER_NATIVE_STRUCT(AudioFrame, "float left;float right"); GDREGISTER_NATIVE_STRUCT(ScriptLanguageExtensionProfilingInfo, "StringName signature;uint64_t call_count;uint64_t total_time;uint64_t self_time"); diff --git a/core/string/char_range.inc b/core/string/char_range.inc new file mode 100644 index 0000000000..c0be9016ad --- /dev/null +++ b/core/string/char_range.inc @@ -0,0 +1,1456 @@ +/*************************************************************************/ +/* char_range.inc */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef CHAR_RANGE_INC +#define CHAR_RANGE_INC + +#include "core/typedefs.h" + +struct CharRange { + char32_t start; + char32_t end; +}; + +static CharRange xid_start[] = { + { 0x41, 0x5a }, + { 0x5f, 0x5f }, + { 0x61, 0x7a }, + { 0xaa, 0xaa }, + { 0xb5, 0xb5 }, + { 0xba, 0xba }, + { 0xc0, 0xd6 }, + { 0xd8, 0xf6 }, + { 0xf8, 0x2c1 }, + { 0x2c6, 0x2d1 }, + { 0x2e0, 0x2e4 }, + { 0x2ec, 0x2ec }, + { 0x2ee, 0x2ee }, + { 0x370, 0x374 }, + { 0x376, 0x377 }, + { 0x37a, 0x37d }, + { 0x37f, 0x37f }, + { 0x386, 0x386 }, + { 0x388, 0x38a }, + { 0x38c, 0x38c }, + { 0x38e, 0x3a1 }, + { 0x3a3, 0x3f5 }, + { 0x3f7, 0x481 }, + { 0x48a, 0x52f }, + { 0x531, 0x556 }, + { 0x559, 0x559 }, + { 0x560, 0x588 }, + { 0x5d0, 0x5ea }, + { 0x5ef, 0x5f2 }, + { 0x620, 0x64a }, + { 0x66e, 0x66f }, + { 0x671, 0x6d3 }, + { 0x6d5, 0x6d5 }, + { 0x6e5, 0x6e6 }, + { 0x6ee, 0x6ef }, + { 0x6fa, 0x6fc }, + { 0x6ff, 0x6ff }, + { 0x710, 0x710 }, + { 0x712, 0x72f }, + { 0x74d, 0x7a5 }, + { 0x7b1, 0x7b1 }, + { 0x7ca, 0x7ea }, + { 0x7f4, 0x7f5 }, + { 0x7fa, 0x7fa }, + { 0x800, 0x815 }, + { 0x81a, 0x81a }, + { 0x824, 0x824 }, + { 0x828, 0x828 }, + { 0x840, 0x858 }, + { 0x860, 0x86a }, + { 0x870, 0x887 }, + { 0x889, 0x88e }, + { 0x8a0, 0x8c9 }, + { 0x904, 0x939 }, + { 0x93d, 0x93d }, + { 0x950, 0x950 }, + { 0x958, 0x961 }, + { 0x971, 0x980 }, + { 0x985, 0x98c }, + { 0x98f, 0x990 }, + { 0x993, 0x9a8 }, + { 0x9aa, 0x9b0 }, + { 0x9b2, 0x9b2 }, + { 0x9b6, 0x9b9 }, + { 0x9bd, 0x9bd }, + { 0x9ce, 0x9ce }, + { 0x9dc, 0x9dd }, + { 0x9df, 0x9e1 }, + { 0x9f0, 0x9f1 }, + { 0x9fc, 0x9fc }, + { 0xa05, 0xa0a }, + { 0xa0f, 0xa10 }, + { 0xa13, 0xa28 }, + { 0xa2a, 0xa30 }, + { 0xa32, 0xa33 }, + { 0xa35, 0xa36 }, + { 0xa38, 0xa39 }, + { 0xa59, 0xa5c }, + { 0xa5e, 0xa5e }, + { 0xa72, 0xa74 }, + { 0xa85, 0xa8d }, + { 0xa8f, 0xa91 }, + { 0xa93, 0xaa8 }, + { 0xaaa, 0xab0 }, + { 0xab2, 0xab3 }, + { 0xab5, 0xab9 }, + { 0xabd, 0xabd }, + { 0xad0, 0xad0 }, + { 0xae0, 0xae1 }, + { 0xaf9, 0xaf9 }, + { 0xb05, 0xb0c }, + { 0xb0f, 0xb10 }, + { 0xb13, 0xb28 }, + { 0xb2a, 0xb30 }, + { 0xb32, 0xb33 }, + { 0xb35, 0xb39 }, + { 0xb3d, 0xb3d }, + { 0xb5c, 0xb5d }, + { 0xb5f, 0xb61 }, + { 0xb71, 0xb71 }, + { 0xb83, 0xb83 }, + { 0xb85, 0xb8a }, + { 0xb8e, 0xb90 }, + { 0xb92, 0xb95 }, + { 0xb99, 0xb9a }, + { 0xb9c, 0xb9c }, + { 0xb9e, 0xb9f }, + { 0xba3, 0xba4 }, + { 0xba8, 0xbaa }, + { 0xbae, 0xbb9 }, + { 0xbd0, 0xbd0 }, + { 0xc05, 0xc0c }, + { 0xc0e, 0xc10 }, + { 0xc12, 0xc28 }, + { 0xc2a, 0xc39 }, + { 0xc3d, 0xc3d }, + { 0xc58, 0xc5a }, + { 0xc5d, 0xc5d }, + { 0xc60, 0xc61 }, + { 0xc80, 0xc80 }, + { 0xc85, 0xc8c }, + { 0xc8e, 0xc90 }, + { 0xc92, 0xca8 }, + { 0xcaa, 0xcb3 }, + { 0xcb5, 0xcb9 }, + { 0xcbd, 0xcbd }, + { 0xcdd, 0xcde }, + { 0xce0, 0xce1 }, + { 0xcf1, 0xcf2 }, + { 0xd04, 0xd0c }, + { 0xd0e, 0xd10 }, + { 0xd12, 0xd3a }, + { 0xd3d, 0xd3d }, + { 0xd4e, 0xd4e }, + { 0xd54, 0xd56 }, + { 0xd5f, 0xd61 }, + { 0xd7a, 0xd7f }, + { 0xd85, 0xd96 }, + { 0xd9a, 0xdb1 }, + { 0xdb3, 0xdbb }, + { 0xdbd, 0xdbd }, + { 0xdc0, 0xdc6 }, + { 0xe01, 0xe30 }, + { 0xe32, 0xe33 }, + { 0xe40, 0xe46 }, + { 0xe81, 0xe82 }, + { 0xe84, 0xe84 }, + { 0xe86, 0xe8a }, + { 0xe8c, 0xea3 }, + { 0xea5, 0xea5 }, + { 0xea7, 0xeb0 }, + { 0xeb2, 0xeb3 }, + { 0xebd, 0xebd }, + { 0xec0, 0xec4 }, + { 0xec6, 0xec6 }, + { 0xedc, 0xedf }, + { 0xf00, 0xf00 }, + { 0xf40, 0xf47 }, + { 0xf49, 0xf6c }, + { 0xf88, 0xf8c }, + { 0x1000, 0x102a }, + { 0x103f, 0x103f }, + { 0x1050, 0x1055 }, + { 0x105a, 0x105d }, + { 0x1061, 0x1061 }, + { 0x1065, 0x1066 }, + { 0x106e, 0x1070 }, + { 0x1075, 0x1081 }, + { 0x108e, 0x108e }, + { 0x10a0, 0x10c5 }, + { 0x10c7, 0x10c7 }, + { 0x10cd, 0x10cd }, + { 0x10d0, 0x10fa }, + { 0x10fc, 0x1248 }, + { 0x124a, 0x124d }, + { 0x1250, 0x1256 }, + { 0x1258, 0x1258 }, + { 0x125a, 0x125d }, + { 0x1260, 0x1288 }, + { 0x128a, 0x128d }, + { 0x1290, 0x12b0 }, + { 0x12b2, 0x12b5 }, + { 0x12b8, 0x12be }, + { 0x12c0, 0x12c0 }, + { 0x12c2, 0x12c5 }, + { 0x12c8, 0x12d6 }, + { 0x12d8, 0x1310 }, + { 0x1312, 0x1315 }, + { 0x1318, 0x135a }, + { 0x1380, 0x138f }, + { 0x13a0, 0x13f5 }, + { 0x13f8, 0x13fd }, + { 0x1401, 0x166c }, + { 0x166f, 0x167f }, + { 0x1681, 0x169a }, + { 0x16a0, 0x16ea }, + { 0x16ee, 0x16f8 }, + { 0x1700, 0x1711 }, + { 0x171f, 0x1731 }, + { 0x1740, 0x1751 }, + { 0x1760, 0x176c }, + { 0x176e, 0x1770 }, + { 0x1780, 0x17b3 }, + { 0x17d7, 0x17d7 }, + { 0x17dc, 0x17dc }, + { 0x1820, 0x1878 }, + { 0x1880, 0x1884 }, + { 0x1887, 0x18a8 }, + { 0x18aa, 0x18aa }, + { 0x18b0, 0x18f5 }, + { 0x1900, 0x191e }, + { 0x1950, 0x196d }, + { 0x1970, 0x1974 }, + { 0x1980, 0x19ab }, + { 0x19b0, 0x19c9 }, + { 0x1a00, 0x1a16 }, + { 0x1a20, 0x1a54 }, + { 0x1aa7, 0x1aa7 }, + { 0x1b05, 0x1b33 }, + { 0x1b45, 0x1b4c }, + { 0x1b83, 0x1ba0 }, + { 0x1bae, 0x1baf }, + { 0x1bba, 0x1be5 }, + { 0x1c00, 0x1c23 }, + { 0x1c4d, 0x1c4f }, + { 0x1c5a, 0x1c7d }, + { 0x1c80, 0x1c88 }, + { 0x1c90, 0x1cba }, + { 0x1cbd, 0x1cbf }, + { 0x1ce9, 0x1cec }, + { 0x1cee, 0x1cf3 }, + { 0x1cf5, 0x1cf6 }, + { 0x1cfa, 0x1cfa }, + { 0x1d00, 0x1dbf }, + { 0x1e00, 0x1f15 }, + { 0x1f18, 0x1f1d }, + { 0x1f20, 0x1f45 }, + { 0x1f48, 0x1f4d }, + { 0x1f50, 0x1f57 }, + { 0x1f59, 0x1f59 }, + { 0x1f5b, 0x1f5b }, + { 0x1f5d, 0x1f5d }, + { 0x1f5f, 0x1f7d }, + { 0x1f80, 0x1fb4 }, + { 0x1fb6, 0x1fbc }, + { 0x1fbe, 0x1fbe }, + { 0x1fc2, 0x1fc4 }, + { 0x1fc6, 0x1fcc }, + { 0x1fd0, 0x1fd3 }, + { 0x1fd6, 0x1fdb }, + { 0x1fe0, 0x1fec }, + { 0x1ff2, 0x1ff4 }, + { 0x1ff6, 0x1ffc }, + { 0x2071, 0x2071 }, + { 0x207f, 0x207f }, + { 0x2090, 0x209c }, + { 0x2102, 0x2102 }, + { 0x2107, 0x2107 }, + { 0x210a, 0x2113 }, + { 0x2115, 0x2115 }, + { 0x2118, 0x211d }, + { 0x2124, 0x2124 }, + { 0x2126, 0x2126 }, + { 0x2128, 0x2128 }, + { 0x212a, 0x2139 }, + { 0x213c, 0x213f }, + { 0x2145, 0x2149 }, + { 0x214e, 0x214e }, + { 0x2160, 0x2188 }, + { 0x2c00, 0x2ce4 }, + { 0x2ceb, 0x2cee }, + { 0x2cf2, 0x2cf3 }, + { 0x2d00, 0x2d25 }, + { 0x2d27, 0x2d27 }, + { 0x2d2d, 0x2d2d }, + { 0x2d30, 0x2d67 }, + { 0x2d6f, 0x2d6f }, + { 0x2d80, 0x2d96 }, + { 0x2da0, 0x2da6 }, + { 0x2da8, 0x2dae }, + { 0x2db0, 0x2db6 }, + { 0x2db8, 0x2dbe }, + { 0x2dc0, 0x2dc6 }, + { 0x2dc8, 0x2dce }, + { 0x2dd0, 0x2dd6 }, + { 0x2dd8, 0x2dde }, + { 0x3005, 0x3007 }, + { 0x3021, 0x3029 }, + { 0x3031, 0x3035 }, + { 0x3038, 0x303c }, + { 0x3041, 0x3096 }, + { 0x309b, 0x309f }, + { 0x30a1, 0x30fa }, + { 0x30fc, 0x30ff }, + { 0x3105, 0x312f }, + { 0x3131, 0x318e }, + { 0x31a0, 0x31bf }, + { 0x31f0, 0x31ff }, + { 0x3400, 0x4dbf }, + { 0x4e00, 0xa48c }, + { 0xa4d0, 0xa4fd }, + { 0xa500, 0xa60c }, + { 0xa610, 0xa61f }, + { 0xa62a, 0xa62b }, + { 0xa640, 0xa66e }, + { 0xa67f, 0xa69d }, + { 0xa6a0, 0xa6ef }, + { 0xa717, 0xa71f }, + { 0xa722, 0xa788 }, + { 0xa78b, 0xa7ca }, + { 0xa7d0, 0xa7d1 }, + { 0xa7d3, 0xa7d3 }, + { 0xa7d5, 0xa7d9 }, + { 0xa7f2, 0xa801 }, + { 0xa803, 0xa805 }, + { 0xa807, 0xa80a }, + { 0xa80c, 0xa822 }, + { 0xa840, 0xa873 }, + { 0xa882, 0xa8b3 }, + { 0xa8f2, 0xa8f7 }, + { 0xa8fb, 0xa8fb }, + { 0xa8fd, 0xa8fe }, + { 0xa90a, 0xa925 }, + { 0xa930, 0xa946 }, + { 0xa960, 0xa97c }, + { 0xa984, 0xa9b2 }, + { 0xa9cf, 0xa9cf }, + { 0xa9e0, 0xa9e4 }, + { 0xa9e6, 0xa9ef }, + { 0xa9fa, 0xa9fe }, + { 0xaa00, 0xaa28 }, + { 0xaa40, 0xaa42 }, + { 0xaa44, 0xaa4b }, + { 0xaa60, 0xaa76 }, + { 0xaa7a, 0xaa7a }, + { 0xaa7e, 0xaaaf }, + { 0xaab1, 0xaab1 }, + { 0xaab5, 0xaab6 }, + { 0xaab9, 0xaabd }, + { 0xaac0, 0xaac0 }, + { 0xaac2, 0xaac2 }, + { 0xaadb, 0xaadd }, + { 0xaae0, 0xaaea }, + { 0xaaf2, 0xaaf4 }, + { 0xab01, 0xab06 }, + { 0xab09, 0xab0e }, + { 0xab11, 0xab16 }, + { 0xab20, 0xab26 }, + { 0xab28, 0xab2e }, + { 0xab30, 0xab5a }, + { 0xab5c, 0xab69 }, + { 0xab70, 0xabe2 }, + { 0xac00, 0xd7a3 }, + { 0xd7b0, 0xd7c6 }, + { 0xd7cb, 0xd7fb }, + { 0xf900, 0xfa6d }, + { 0xfa70, 0xfad9 }, + { 0xfb00, 0xfb06 }, + { 0xfb13, 0xfb17 }, + { 0xfb1d, 0xfb1d }, + { 0xfb1f, 0xfb28 }, + { 0xfb2a, 0xfb36 }, + { 0xfb38, 0xfb3c }, + { 0xfb3e, 0xfb3e }, + { 0xfb40, 0xfb41 }, + { 0xfb43, 0xfb44 }, + { 0xfb46, 0xfbb1 }, + { 0xfbd3, 0xfd3d }, + { 0xfd50, 0xfd8f }, + { 0xfd92, 0xfdc7 }, + { 0xfdf0, 0xfdfb }, + { 0xfe70, 0xfe74 }, + { 0xfe76, 0xfefc }, + { 0xff21, 0xff3a }, + { 0xff41, 0xff5a }, + { 0xff66, 0xffbe }, + { 0xffc2, 0xffc7 }, + { 0xffca, 0xffcf }, + { 0xffd2, 0xffd7 }, + { 0xffda, 0xffdc }, + { 0x10000, 0x1000b }, + { 0x1000d, 0x10026 }, + { 0x10028, 0x1003a }, + { 0x1003c, 0x1003d }, + { 0x1003f, 0x1004d }, + { 0x10050, 0x1005d }, + { 0x10080, 0x100fa }, + { 0x10140, 0x10174 }, + { 0x10280, 0x1029c }, + { 0x102a0, 0x102d0 }, + { 0x10300, 0x1031f }, + { 0x1032d, 0x1034a }, + { 0x10350, 0x10375 }, + { 0x10380, 0x1039d }, + { 0x103a0, 0x103c3 }, + { 0x103c8, 0x103cf }, + { 0x103d1, 0x103d5 }, + { 0x10400, 0x1049d }, + { 0x104b0, 0x104d3 }, + { 0x104d8, 0x104fb }, + { 0x10500, 0x10527 }, + { 0x10530, 0x10563 }, + { 0x10570, 0x1057a }, + { 0x1057c, 0x1058a }, + { 0x1058c, 0x10592 }, + { 0x10594, 0x10595 }, + { 0x10597, 0x105a1 }, + { 0x105a3, 0x105b1 }, + { 0x105b3, 0x105b9 }, + { 0x105bb, 0x105bc }, + { 0x10600, 0x10736 }, + { 0x10740, 0x10755 }, + { 0x10760, 0x10767 }, + { 0x10780, 0x10785 }, + { 0x10787, 0x107b0 }, + { 0x107b2, 0x107ba }, + { 0x10800, 0x10805 }, + { 0x10808, 0x10808 }, + { 0x1080a, 0x10835 }, + { 0x10837, 0x10838 }, + { 0x1083c, 0x1083c }, + { 0x1083f, 0x10855 }, + { 0x10860, 0x10876 }, + { 0x10880, 0x1089e }, + { 0x108e0, 0x108f2 }, + { 0x108f4, 0x108f5 }, + { 0x10900, 0x10915 }, + { 0x10920, 0x10939 }, + { 0x10980, 0x109b7 }, + { 0x109be, 0x109bf }, + { 0x10a00, 0x10a00 }, + { 0x10a10, 0x10a13 }, + { 0x10a15, 0x10a17 }, + { 0x10a19, 0x10a35 }, + { 0x10a60, 0x10a7c }, + { 0x10a80, 0x10a9c }, + { 0x10ac0, 0x10ac7 }, + { 0x10ac9, 0x10ae4 }, + { 0x10b00, 0x10b35 }, + { 0x10b40, 0x10b55 }, + { 0x10b60, 0x10b72 }, + { 0x10b80, 0x10b91 }, + { 0x10c00, 0x10c48 }, + { 0x10c80, 0x10cb2 }, + { 0x10cc0, 0x10cf2 }, + { 0x10d00, 0x10d23 }, + { 0x10e80, 0x10ea9 }, + { 0x10eb0, 0x10eb1 }, + { 0x10f00, 0x10f1c }, + { 0x10f27, 0x10f27 }, + { 0x10f30, 0x10f45 }, + { 0x10f70, 0x10f81 }, + { 0x10fb0, 0x10fc4 }, + { 0x10fe0, 0x10ff6 }, + { 0x11003, 0x11037 }, + { 0x11071, 0x11072 }, + { 0x11075, 0x11075 }, + { 0x11083, 0x110af }, + { 0x110d0, 0x110e8 }, + { 0x11103, 0x11126 }, + { 0x11144, 0x11144 }, + { 0x11147, 0x11147 }, + { 0x11150, 0x11172 }, + { 0x11176, 0x11176 }, + { 0x11183, 0x111b2 }, + { 0x111c1, 0x111c4 }, + { 0x111da, 0x111da }, + { 0x111dc, 0x111dc }, + { 0x11200, 0x11211 }, + { 0x11213, 0x1122b }, + { 0x11280, 0x11286 }, + { 0x11288, 0x11288 }, + { 0x1128a, 0x1128d }, + { 0x1128f, 0x1129d }, + { 0x1129f, 0x112a8 }, + { 0x112b0, 0x112de }, + { 0x11305, 0x1130c }, + { 0x1130f, 0x11310 }, + { 0x11313, 0x11328 }, + { 0x1132a, 0x11330 }, + { 0x11332, 0x11333 }, + { 0x11335, 0x11339 }, + { 0x1133d, 0x1133d }, + { 0x11350, 0x11350 }, + { 0x1135d, 0x11361 }, + { 0x11400, 0x11434 }, + { 0x11447, 0x1144a }, + { 0x1145f, 0x11461 }, + { 0x11480, 0x114af }, + { 0x114c4, 0x114c5 }, + { 0x114c7, 0x114c7 }, + { 0x11580, 0x115ae }, + { 0x115d8, 0x115db }, + { 0x11600, 0x1162f }, + { 0x11644, 0x11644 }, + { 0x11680, 0x116aa }, + { 0x116b8, 0x116b8 }, + { 0x11700, 0x1171a }, + { 0x11740, 0x11746 }, + { 0x11800, 0x1182b }, + { 0x118a0, 0x118df }, + { 0x118ff, 0x11906 }, + { 0x11909, 0x11909 }, + { 0x1190c, 0x11913 }, + { 0x11915, 0x11916 }, + { 0x11918, 0x1192f }, + { 0x1193f, 0x1193f }, + { 0x11941, 0x11941 }, + { 0x119a0, 0x119a7 }, + { 0x119aa, 0x119d0 }, + { 0x119e1, 0x119e1 }, + { 0x119e3, 0x119e3 }, + { 0x11a00, 0x11a00 }, + { 0x11a0b, 0x11a32 }, + { 0x11a3a, 0x11a3a }, + { 0x11a50, 0x11a50 }, + { 0x11a5c, 0x11a89 }, + { 0x11a9d, 0x11a9d }, + { 0x11ab0, 0x11af8 }, + { 0x11c00, 0x11c08 }, + { 0x11c0a, 0x11c2e }, + { 0x11c40, 0x11c40 }, + { 0x11c72, 0x11c8f }, + { 0x11d00, 0x11d06 }, + { 0x11d08, 0x11d09 }, + { 0x11d0b, 0x11d30 }, + { 0x11d46, 0x11d46 }, + { 0x11d60, 0x11d65 }, + { 0x11d67, 0x11d68 }, + { 0x11d6a, 0x11d89 }, + { 0x11d98, 0x11d98 }, + { 0x11ee0, 0x11ef2 }, + { 0x11fb0, 0x11fb0 }, + { 0x12000, 0x12399 }, + { 0x12400, 0x1246e }, + { 0x12480, 0x12543 }, + { 0x12f90, 0x12ff0 }, + { 0x13000, 0x1342e }, + { 0x14400, 0x14646 }, + { 0x16800, 0x16a38 }, + { 0x16a40, 0x16a5e }, + { 0x16a70, 0x16abe }, + { 0x16ad0, 0x16aed }, + { 0x16b00, 0x16b2f }, + { 0x16b40, 0x16b43 }, + { 0x16b63, 0x16b77 }, + { 0x16b7d, 0x16b8f }, + { 0x16e40, 0x16e7f }, + { 0x16f00, 0x16f4a }, + { 0x16f50, 0x16f50 }, + { 0x16f93, 0x16f9f }, + { 0x16fe0, 0x16fe1 }, + { 0x16fe3, 0x16fe3 }, + { 0x17000, 0x187f7 }, + { 0x18800, 0x18cd5 }, + { 0x18d00, 0x18d08 }, + { 0x1aff0, 0x1aff3 }, + { 0x1aff5, 0x1affb }, + { 0x1affd, 0x1affe }, + { 0x1b000, 0x1b122 }, + { 0x1b150, 0x1b152 }, + { 0x1b164, 0x1b167 }, + { 0x1b170, 0x1b2fb }, + { 0x1bc00, 0x1bc6a }, + { 0x1bc70, 0x1bc7c }, + { 0x1bc80, 0x1bc88 }, + { 0x1bc90, 0x1bc99 }, + { 0x1d400, 0x1d454 }, + { 0x1d456, 0x1d49c }, + { 0x1d49e, 0x1d49f }, + { 0x1d4a2, 0x1d4a2 }, + { 0x1d4a5, 0x1d4a6 }, + { 0x1d4a9, 0x1d4ac }, + { 0x1d4ae, 0x1d4b9 }, + { 0x1d4bb, 0x1d4bb }, + { 0x1d4bd, 0x1d4c3 }, + { 0x1d4c5, 0x1d505 }, + { 0x1d507, 0x1d50a }, + { 0x1d50d, 0x1d514 }, + { 0x1d516, 0x1d51c }, + { 0x1d51e, 0x1d539 }, + { 0x1d53b, 0x1d53e }, + { 0x1d540, 0x1d544 }, + { 0x1d546, 0x1d546 }, + { 0x1d54a, 0x1d550 }, + { 0x1d552, 0x1d6a5 }, + { 0x1d6a8, 0x1d6c0 }, + { 0x1d6c2, 0x1d6da }, + { 0x1d6dc, 0x1d6fa }, + { 0x1d6fc, 0x1d714 }, + { 0x1d716, 0x1d734 }, + { 0x1d736, 0x1d74e }, + { 0x1d750, 0x1d76e }, + { 0x1d770, 0x1d788 }, + { 0x1d78a, 0x1d7a8 }, + { 0x1d7aa, 0x1d7c2 }, + { 0x1d7c4, 0x1d7cb }, + { 0x1df00, 0x1df1e }, + { 0x1e100, 0x1e12c }, + { 0x1e137, 0x1e13d }, + { 0x1e14e, 0x1e14e }, + { 0x1e290, 0x1e2ad }, + { 0x1e2c0, 0x1e2eb }, + { 0x1e7e0, 0x1e7e6 }, + { 0x1e7e8, 0x1e7eb }, + { 0x1e7ed, 0x1e7ee }, + { 0x1e7f0, 0x1e7fe }, + { 0x1e800, 0x1e8c4 }, + { 0x1e900, 0x1e943 }, + { 0x1e94b, 0x1e94b }, + { 0x1ee00, 0x1ee03 }, + { 0x1ee05, 0x1ee1f }, + { 0x1ee21, 0x1ee22 }, + { 0x1ee24, 0x1ee24 }, + { 0x1ee27, 0x1ee27 }, + { 0x1ee29, 0x1ee32 }, + { 0x1ee34, 0x1ee37 }, + { 0x1ee39, 0x1ee39 }, + { 0x1ee3b, 0x1ee3b }, + { 0x1ee42, 0x1ee42 }, + { 0x1ee47, 0x1ee47 }, + { 0x1ee49, 0x1ee49 }, + { 0x1ee4b, 0x1ee4b }, + { 0x1ee4d, 0x1ee4f }, + { 0x1ee51, 0x1ee52 }, + { 0x1ee54, 0x1ee54 }, + { 0x1ee57, 0x1ee57 }, + { 0x1ee59, 0x1ee59 }, + { 0x1ee5b, 0x1ee5b }, + { 0x1ee5d, 0x1ee5d }, + { 0x1ee5f, 0x1ee5f }, + { 0x1ee61, 0x1ee62 }, + { 0x1ee64, 0x1ee64 }, + { 0x1ee67, 0x1ee6a }, + { 0x1ee6c, 0x1ee72 }, + { 0x1ee74, 0x1ee77 }, + { 0x1ee79, 0x1ee7c }, + { 0x1ee7e, 0x1ee7e }, + { 0x1ee80, 0x1ee89 }, + { 0x1ee8b, 0x1ee9b }, + { 0x1eea1, 0x1eea3 }, + { 0x1eea5, 0x1eea9 }, + { 0x1eeab, 0x1eebb }, + { 0x20000, 0x2a6df }, + { 0x2a700, 0x2b738 }, + { 0x2b740, 0x2b81d }, + { 0x2b820, 0x2cea1 }, + { 0x2ceb0, 0x2ebe0 }, + { 0x2f800, 0x2fa1d }, + { 0x30000, 0x3134a }, + { 0x0, 0x0 }, +}; + +static CharRange xid_continue[] = { + { 0x30, 0x39 }, + { 0x41, 0x5a }, + { 0x5f, 0x5f }, + { 0x61, 0x7a }, + { 0xaa, 0xaa }, + { 0xb5, 0xb5 }, + { 0xb7, 0xb7 }, + { 0xba, 0xba }, + { 0xc0, 0xd6 }, + { 0xd8, 0xf6 }, + { 0xf8, 0x2c1 }, + { 0x2c6, 0x2d1 }, + { 0x2e0, 0x2e4 }, + { 0x2ec, 0x2ec }, + { 0x2ee, 0x2ee }, + { 0x300, 0x374 }, + { 0x376, 0x377 }, + { 0x37a, 0x37d }, + { 0x37f, 0x37f }, + { 0x386, 0x38a }, + { 0x38c, 0x38c }, + { 0x38e, 0x3a1 }, + { 0x3a3, 0x3f5 }, + { 0x3f7, 0x481 }, + { 0x483, 0x487 }, + { 0x48a, 0x52f }, + { 0x531, 0x556 }, + { 0x559, 0x559 }, + { 0x560, 0x588 }, + { 0x591, 0x5bd }, + { 0x5bf, 0x5bf }, + { 0x5c1, 0x5c2 }, + { 0x5c4, 0x5c5 }, + { 0x5c7, 0x5c7 }, + { 0x5d0, 0x5ea }, + { 0x5ef, 0x5f2 }, + { 0x610, 0x61a }, + { 0x620, 0x669 }, + { 0x66e, 0x6d3 }, + { 0x6d5, 0x6dc }, + { 0x6df, 0x6e8 }, + { 0x6ea, 0x6fc }, + { 0x6ff, 0x6ff }, + { 0x710, 0x74a }, + { 0x74d, 0x7b1 }, + { 0x7c0, 0x7f5 }, + { 0x7fa, 0x7fa }, + { 0x7fd, 0x7fd }, + { 0x800, 0x82d }, + { 0x840, 0x85b }, + { 0x860, 0x86a }, + { 0x870, 0x887 }, + { 0x889, 0x88e }, + { 0x898, 0x8e1 }, + { 0x8e3, 0x963 }, + { 0x966, 0x96f }, + { 0x971, 0x983 }, + { 0x985, 0x98c }, + { 0x98f, 0x990 }, + { 0x993, 0x9a8 }, + { 0x9aa, 0x9b0 }, + { 0x9b2, 0x9b2 }, + { 0x9b6, 0x9b9 }, + { 0x9bc, 0x9c4 }, + { 0x9c7, 0x9c8 }, + { 0x9cb, 0x9ce }, + { 0x9d7, 0x9d7 }, + { 0x9dc, 0x9dd }, + { 0x9df, 0x9e3 }, + { 0x9e6, 0x9f1 }, + { 0x9fc, 0x9fc }, + { 0x9fe, 0x9fe }, + { 0xa01, 0xa03 }, + { 0xa05, 0xa0a }, + { 0xa0f, 0xa10 }, + { 0xa13, 0xa28 }, + { 0xa2a, 0xa30 }, + { 0xa32, 0xa33 }, + { 0xa35, 0xa36 }, + { 0xa38, 0xa39 }, + { 0xa3c, 0xa3c }, + { 0xa3e, 0xa42 }, + { 0xa47, 0xa48 }, + { 0xa4b, 0xa4d }, + { 0xa51, 0xa51 }, + { 0xa59, 0xa5c }, + { 0xa5e, 0xa5e }, + { 0xa66, 0xa75 }, + { 0xa81, 0xa83 }, + { 0xa85, 0xa8d }, + { 0xa8f, 0xa91 }, + { 0xa93, 0xaa8 }, + { 0xaaa, 0xab0 }, + { 0xab2, 0xab3 }, + { 0xab5, 0xab9 }, + { 0xabc, 0xac5 }, + { 0xac7, 0xac9 }, + { 0xacb, 0xacd }, + { 0xad0, 0xad0 }, + { 0xae0, 0xae3 }, + { 0xae6, 0xaef }, + { 0xaf9, 0xaff }, + { 0xb01, 0xb03 }, + { 0xb05, 0xb0c }, + { 0xb0f, 0xb10 }, + { 0xb13, 0xb28 }, + { 0xb2a, 0xb30 }, + { 0xb32, 0xb33 }, + { 0xb35, 0xb39 }, + { 0xb3c, 0xb44 }, + { 0xb47, 0xb48 }, + { 0xb4b, 0xb4d }, + { 0xb55, 0xb57 }, + { 0xb5c, 0xb5d }, + { 0xb5f, 0xb63 }, + { 0xb66, 0xb6f }, + { 0xb71, 0xb71 }, + { 0xb82, 0xb83 }, + { 0xb85, 0xb8a }, + { 0xb8e, 0xb90 }, + { 0xb92, 0xb95 }, + { 0xb99, 0xb9a }, + { 0xb9c, 0xb9c }, + { 0xb9e, 0xb9f }, + { 0xba3, 0xba4 }, + { 0xba8, 0xbaa }, + { 0xbae, 0xbb9 }, + { 0xbbe, 0xbc2 }, + { 0xbc6, 0xbc8 }, + { 0xbca, 0xbcd }, + { 0xbd0, 0xbd0 }, + { 0xbd7, 0xbd7 }, + { 0xbe6, 0xbef }, + { 0xc00, 0xc0c }, + { 0xc0e, 0xc10 }, + { 0xc12, 0xc28 }, + { 0xc2a, 0xc39 }, + { 0xc3c, 0xc44 }, + { 0xc46, 0xc48 }, + { 0xc4a, 0xc4d }, + { 0xc55, 0xc56 }, + { 0xc58, 0xc5a }, + { 0xc5d, 0xc5d }, + { 0xc60, 0xc63 }, + { 0xc66, 0xc6f }, + { 0xc80, 0xc83 }, + { 0xc85, 0xc8c }, + { 0xc8e, 0xc90 }, + { 0xc92, 0xca8 }, + { 0xcaa, 0xcb3 }, + { 0xcb5, 0xcb9 }, + { 0xcbc, 0xcc4 }, + { 0xcc6, 0xcc8 }, + { 0xcca, 0xccd }, + { 0xcd5, 0xcd6 }, + { 0xcdd, 0xcde }, + { 0xce0, 0xce3 }, + { 0xce6, 0xcef }, + { 0xcf1, 0xcf2 }, + { 0xd00, 0xd0c }, + { 0xd0e, 0xd10 }, + { 0xd12, 0xd44 }, + { 0xd46, 0xd48 }, + { 0xd4a, 0xd4e }, + { 0xd54, 0xd57 }, + { 0xd5f, 0xd63 }, + { 0xd66, 0xd6f }, + { 0xd7a, 0xd7f }, + { 0xd81, 0xd83 }, + { 0xd85, 0xd96 }, + { 0xd9a, 0xdb1 }, + { 0xdb3, 0xdbb }, + { 0xdbd, 0xdbd }, + { 0xdc0, 0xdc6 }, + { 0xdca, 0xdca }, + { 0xdcf, 0xdd4 }, + { 0xdd6, 0xdd6 }, + { 0xdd8, 0xddf }, + { 0xde6, 0xdef }, + { 0xdf2, 0xdf3 }, + { 0xe01, 0xe3a }, + { 0xe40, 0xe4e }, + { 0xe50, 0xe59 }, + { 0xe81, 0xe82 }, + { 0xe84, 0xe84 }, + { 0xe86, 0xe8a }, + { 0xe8c, 0xea3 }, + { 0xea5, 0xea5 }, + { 0xea7, 0xebd }, + { 0xec0, 0xec4 }, + { 0xec6, 0xec6 }, + { 0xec8, 0xecd }, + { 0xed0, 0xed9 }, + { 0xedc, 0xedf }, + { 0xf00, 0xf00 }, + { 0xf18, 0xf19 }, + { 0xf20, 0xf29 }, + { 0xf35, 0xf35 }, + { 0xf37, 0xf37 }, + { 0xf39, 0xf39 }, + { 0xf3e, 0xf47 }, + { 0xf49, 0xf6c }, + { 0xf71, 0xf84 }, + { 0xf86, 0xf97 }, + { 0xf99, 0xfbc }, + { 0xfc6, 0xfc6 }, + { 0x1000, 0x1049 }, + { 0x1050, 0x109d }, + { 0x10a0, 0x10c5 }, + { 0x10c7, 0x10c7 }, + { 0x10cd, 0x10cd }, + { 0x10d0, 0x10fa }, + { 0x10fc, 0x1248 }, + { 0x124a, 0x124d }, + { 0x1250, 0x1256 }, + { 0x1258, 0x1258 }, + { 0x125a, 0x125d }, + { 0x1260, 0x1288 }, + { 0x128a, 0x128d }, + { 0x1290, 0x12b0 }, + { 0x12b2, 0x12b5 }, + { 0x12b8, 0x12be }, + { 0x12c0, 0x12c0 }, + { 0x12c2, 0x12c5 }, + { 0x12c8, 0x12d6 }, + { 0x12d8, 0x1310 }, + { 0x1312, 0x1315 }, + { 0x1318, 0x135a }, + { 0x135d, 0x135f }, + { 0x1369, 0x1369 }, + { 0x1371, 0x1371 }, + { 0x1380, 0x138f }, + { 0x13a0, 0x13f5 }, + { 0x13f8, 0x13fd }, + { 0x1401, 0x166c }, + { 0x166f, 0x167f }, + { 0x1681, 0x169a }, + { 0x16a0, 0x16ea }, + { 0x16ee, 0x16f8 }, + { 0x1700, 0x1715 }, + { 0x171f, 0x1734 }, + { 0x1740, 0x1753 }, + { 0x1760, 0x176c }, + { 0x176e, 0x1770 }, + { 0x1772, 0x1773 }, + { 0x1780, 0x17d3 }, + { 0x17d7, 0x17d7 }, + { 0x17dc, 0x17dd }, + { 0x17e0, 0x17e9 }, + { 0x180b, 0x180d }, + { 0x180f, 0x1819 }, + { 0x1820, 0x1878 }, + { 0x1880, 0x18aa }, + { 0x18b0, 0x18f5 }, + { 0x1900, 0x191e }, + { 0x1920, 0x192b }, + { 0x1930, 0x193b }, + { 0x1946, 0x196d }, + { 0x1970, 0x1974 }, + { 0x1980, 0x19ab }, + { 0x19b0, 0x19c9 }, + { 0x19d0, 0x19da }, + { 0x1a00, 0x1a1b }, + { 0x1a20, 0x1a5e }, + { 0x1a60, 0x1a7c }, + { 0x1a7f, 0x1a89 }, + { 0x1a90, 0x1a99 }, + { 0x1aa7, 0x1aa7 }, + { 0x1ab0, 0x1abd }, + { 0x1abf, 0x1ace }, + { 0x1b00, 0x1b4c }, + { 0x1b50, 0x1b59 }, + { 0x1b6b, 0x1b73 }, + { 0x1b80, 0x1bf3 }, + { 0x1c00, 0x1c37 }, + { 0x1c40, 0x1c49 }, + { 0x1c4d, 0x1c7d }, + { 0x1c80, 0x1c88 }, + { 0x1c90, 0x1cba }, + { 0x1cbd, 0x1cbf }, + { 0x1cd0, 0x1cd2 }, + { 0x1cd4, 0x1cfa }, + { 0x1d00, 0x1f15 }, + { 0x1f18, 0x1f1d }, + { 0x1f20, 0x1f45 }, + { 0x1f48, 0x1f4d }, + { 0x1f50, 0x1f57 }, + { 0x1f59, 0x1f59 }, + { 0x1f5b, 0x1f5b }, + { 0x1f5d, 0x1f5d }, + { 0x1f5f, 0x1f7d }, + { 0x1f80, 0x1fb4 }, + { 0x1fb6, 0x1fbc }, + { 0x1fbe, 0x1fbe }, + { 0x1fc2, 0x1fc4 }, + { 0x1fc6, 0x1fcc }, + { 0x1fd0, 0x1fd3 }, + { 0x1fd6, 0x1fdb }, + { 0x1fe0, 0x1fec }, + { 0x1ff2, 0x1ff4 }, + { 0x1ff6, 0x1ffc }, + { 0x203f, 0x2040 }, + { 0x2054, 0x2054 }, + { 0x2071, 0x2071 }, + { 0x207f, 0x207f }, + { 0x2090, 0x209c }, + { 0x20d0, 0x20dc }, + { 0x20e1, 0x20e1 }, + { 0x20e5, 0x20f0 }, + { 0x2102, 0x2102 }, + { 0x2107, 0x2107 }, + { 0x210a, 0x2113 }, + { 0x2115, 0x2115 }, + { 0x2118, 0x211d }, + { 0x2124, 0x2124 }, + { 0x2126, 0x2126 }, + { 0x2128, 0x2128 }, + { 0x212a, 0x2139 }, + { 0x213c, 0x213f }, + { 0x2145, 0x2149 }, + { 0x214e, 0x214e }, + { 0x2160, 0x2188 }, + { 0x2c00, 0x2ce4 }, + { 0x2ceb, 0x2cf3 }, + { 0x2d00, 0x2d25 }, + { 0x2d27, 0x2d27 }, + { 0x2d2d, 0x2d2d }, + { 0x2d30, 0x2d67 }, + { 0x2d6f, 0x2d6f }, + { 0x2d7f, 0x2d96 }, + { 0x2da0, 0x2da6 }, + { 0x2da8, 0x2dae }, + { 0x2db0, 0x2db6 }, + { 0x2db8, 0x2dbe }, + { 0x2dc0, 0x2dc6 }, + { 0x2dc8, 0x2dce }, + { 0x2dd0, 0x2dd6 }, + { 0x2dd8, 0x2dde }, + { 0x2de0, 0x2dff }, + { 0x3005, 0x3007 }, + { 0x3021, 0x302f }, + { 0x3031, 0x3035 }, + { 0x3038, 0x303c }, + { 0x3041, 0x3096 }, + { 0x3099, 0x309f }, + { 0x30a1, 0x30fa }, + { 0x30fc, 0x30ff }, + { 0x3105, 0x312f }, + { 0x3131, 0x318e }, + { 0x31a0, 0x31bf }, + { 0x31f0, 0x31ff }, + { 0x3400, 0x4dbf }, + { 0x4e00, 0xa48c }, + { 0xa4d0, 0xa4fd }, + { 0xa500, 0xa60c }, + { 0xa610, 0xa62b }, + { 0xa640, 0xa66f }, + { 0xa674, 0xa67d }, + { 0xa67f, 0xa6f1 }, + { 0xa717, 0xa71f }, + { 0xa722, 0xa788 }, + { 0xa78b, 0xa7ca }, + { 0xa7d0, 0xa7d1 }, + { 0xa7d3, 0xa7d3 }, + { 0xa7d5, 0xa7d9 }, + { 0xa7f2, 0xa827 }, + { 0xa82c, 0xa82c }, + { 0xa840, 0xa873 }, + { 0xa880, 0xa8c5 }, + { 0xa8d0, 0xa8d9 }, + { 0xa8e0, 0xa8f7 }, + { 0xa8fb, 0xa8fb }, + { 0xa8fd, 0xa92d }, + { 0xa930, 0xa953 }, + { 0xa960, 0xa97c }, + { 0xa980, 0xa9c0 }, + { 0xa9cf, 0xa9d9 }, + { 0xa9e0, 0xa9fe }, + { 0xaa00, 0xaa36 }, + { 0xaa40, 0xaa4d }, + { 0xaa50, 0xaa59 }, + { 0xaa60, 0xaa76 }, + { 0xaa7a, 0xaac2 }, + { 0xaadb, 0xaadd }, + { 0xaae0, 0xaaef }, + { 0xaaf2, 0xaaf6 }, + { 0xab01, 0xab06 }, + { 0xab09, 0xab0e }, + { 0xab11, 0xab16 }, + { 0xab20, 0xab26 }, + { 0xab28, 0xab2e }, + { 0xab30, 0xab5a }, + { 0xab5c, 0xab69 }, + { 0xab70, 0xabea }, + { 0xabec, 0xabed }, + { 0xabf0, 0xabf9 }, + { 0xac00, 0xd7a3 }, + { 0xd7b0, 0xd7c6 }, + { 0xd7cb, 0xd7fb }, + { 0xf900, 0xfa6d }, + { 0xfa70, 0xfad9 }, + { 0xfb00, 0xfb06 }, + { 0xfb13, 0xfb17 }, + { 0xfb1d, 0xfb28 }, + { 0xfb2a, 0xfb36 }, + { 0xfb38, 0xfb3c }, + { 0xfb3e, 0xfb3e }, + { 0xfb40, 0xfb41 }, + { 0xfb43, 0xfb44 }, + { 0xfb46, 0xfbb1 }, + { 0xfbd3, 0xfd3d }, + { 0xfd50, 0xfd8f }, + { 0xfd92, 0xfdc7 }, + { 0xfdf0, 0xfdfb }, + { 0xfe00, 0xfe0f }, + { 0xfe20, 0xfe2f }, + { 0xfe33, 0xfe34 }, + { 0xfe4d, 0xfe4f }, + { 0xfe70, 0xfe74 }, + { 0xfe76, 0xfefc }, + { 0xff10, 0xff19 }, + { 0xff21, 0xff3a }, + { 0xff3f, 0xff3f }, + { 0xff41, 0xff5a }, + { 0xff66, 0xffbe }, + { 0xffc2, 0xffc7 }, + { 0xffca, 0xffcf }, + { 0xffd2, 0xffd7 }, + { 0xffda, 0xffdc }, + { 0x10000, 0x1000b }, + { 0x1000d, 0x10026 }, + { 0x10028, 0x1003a }, + { 0x1003c, 0x1003d }, + { 0x1003f, 0x1004d }, + { 0x10050, 0x1005d }, + { 0x10080, 0x100fa }, + { 0x10140, 0x10174 }, + { 0x101fd, 0x101fd }, + { 0x10280, 0x1029c }, + { 0x102a0, 0x102d0 }, + { 0x102e0, 0x102e0 }, + { 0x10300, 0x1031f }, + { 0x1032d, 0x1034a }, + { 0x10350, 0x1037a }, + { 0x10380, 0x1039d }, + { 0x103a0, 0x103c3 }, + { 0x103c8, 0x103cf }, + { 0x103d1, 0x103d5 }, + { 0x10400, 0x1049d }, + { 0x104a0, 0x104a9 }, + { 0x104b0, 0x104d3 }, + { 0x104d8, 0x104fb }, + { 0x10500, 0x10527 }, + { 0x10530, 0x10563 }, + { 0x10570, 0x1057a }, + { 0x1057c, 0x1058a }, + { 0x1058c, 0x10592 }, + { 0x10594, 0x10595 }, + { 0x10597, 0x105a1 }, + { 0x105a3, 0x105b1 }, + { 0x105b3, 0x105b9 }, + { 0x105bb, 0x105bc }, + { 0x10600, 0x10736 }, + { 0x10740, 0x10755 }, + { 0x10760, 0x10767 }, + { 0x10780, 0x10785 }, + { 0x10787, 0x107b0 }, + { 0x107b2, 0x107ba }, + { 0x10800, 0x10805 }, + { 0x10808, 0x10808 }, + { 0x1080a, 0x10835 }, + { 0x10837, 0x10838 }, + { 0x1083c, 0x1083c }, + { 0x1083f, 0x10855 }, + { 0x10860, 0x10876 }, + { 0x10880, 0x1089e }, + { 0x108e0, 0x108f2 }, + { 0x108f4, 0x108f5 }, + { 0x10900, 0x10915 }, + { 0x10920, 0x10939 }, + { 0x10980, 0x109b7 }, + { 0x109be, 0x109bf }, + { 0x10a00, 0x10a03 }, + { 0x10a05, 0x10a06 }, + { 0x10a0c, 0x10a13 }, + { 0x10a15, 0x10a17 }, + { 0x10a19, 0x10a35 }, + { 0x10a38, 0x10a3a }, + { 0x10a3f, 0x10a3f }, + { 0x10a60, 0x10a7c }, + { 0x10a80, 0x10a9c }, + { 0x10ac0, 0x10ac7 }, + { 0x10ac9, 0x10ae6 }, + { 0x10b00, 0x10b35 }, + { 0x10b40, 0x10b55 }, + { 0x10b60, 0x10b72 }, + { 0x10b80, 0x10b91 }, + { 0x10c00, 0x10c48 }, + { 0x10c80, 0x10cb2 }, + { 0x10cc0, 0x10cf2 }, + { 0x10d00, 0x10d27 }, + { 0x10d30, 0x10d39 }, + { 0x10e80, 0x10ea9 }, + { 0x10eab, 0x10eac }, + { 0x10eb0, 0x10eb1 }, + { 0x10f00, 0x10f1c }, + { 0x10f27, 0x10f27 }, + { 0x10f30, 0x10f50 }, + { 0x10f70, 0x10f85 }, + { 0x10fb0, 0x10fc4 }, + { 0x10fe0, 0x10ff6 }, + { 0x11000, 0x11046 }, + { 0x11066, 0x11075 }, + { 0x1107f, 0x110ba }, + { 0x110c2, 0x110c2 }, + { 0x110d0, 0x110e8 }, + { 0x110f0, 0x110f9 }, + { 0x11100, 0x11134 }, + { 0x11136, 0x1113f }, + { 0x11144, 0x11147 }, + { 0x11150, 0x11173 }, + { 0x11176, 0x11176 }, + { 0x11180, 0x111c4 }, + { 0x111c9, 0x111cc }, + { 0x111ce, 0x111da }, + { 0x111dc, 0x111dc }, + { 0x11200, 0x11211 }, + { 0x11213, 0x11237 }, + { 0x1123e, 0x1123e }, + { 0x11280, 0x11286 }, + { 0x11288, 0x11288 }, + { 0x1128a, 0x1128d }, + { 0x1128f, 0x1129d }, + { 0x1129f, 0x112a8 }, + { 0x112b0, 0x112ea }, + { 0x112f0, 0x112f9 }, + { 0x11300, 0x11303 }, + { 0x11305, 0x1130c }, + { 0x1130f, 0x11310 }, + { 0x11313, 0x11328 }, + { 0x1132a, 0x11330 }, + { 0x11332, 0x11333 }, + { 0x11335, 0x11339 }, + { 0x1133b, 0x11344 }, + { 0x11347, 0x11348 }, + { 0x1134b, 0x1134d }, + { 0x11350, 0x11350 }, + { 0x11357, 0x11357 }, + { 0x1135d, 0x11363 }, + { 0x11366, 0x1136c }, + { 0x11370, 0x11374 }, + { 0x11400, 0x1144a }, + { 0x11450, 0x11459 }, + { 0x1145e, 0x11461 }, + { 0x11480, 0x114c5 }, + { 0x114c7, 0x114c7 }, + { 0x114d0, 0x114d9 }, + { 0x11580, 0x115b5 }, + { 0x115b8, 0x115c0 }, + { 0x115d8, 0x115dd }, + { 0x11600, 0x11640 }, + { 0x11644, 0x11644 }, + { 0x11650, 0x11659 }, + { 0x11680, 0x116b8 }, + { 0x116c0, 0x116c9 }, + { 0x11700, 0x1171a }, + { 0x1171d, 0x1172b }, + { 0x11730, 0x11739 }, + { 0x11740, 0x11746 }, + { 0x11800, 0x1183a }, + { 0x118a0, 0x118e9 }, + { 0x118ff, 0x11906 }, + { 0x11909, 0x11909 }, + { 0x1190c, 0x11913 }, + { 0x11915, 0x11916 }, + { 0x11918, 0x11935 }, + { 0x11937, 0x11938 }, + { 0x1193b, 0x11943 }, + { 0x11950, 0x11959 }, + { 0x119a0, 0x119a7 }, + { 0x119aa, 0x119d7 }, + { 0x119da, 0x119e1 }, + { 0x119e3, 0x119e4 }, + { 0x11a00, 0x11a3e }, + { 0x11a47, 0x11a47 }, + { 0x11a50, 0x11a99 }, + { 0x11a9d, 0x11a9d }, + { 0x11ab0, 0x11af8 }, + { 0x11c00, 0x11c08 }, + { 0x11c0a, 0x11c36 }, + { 0x11c38, 0x11c40 }, + { 0x11c50, 0x11c59 }, + { 0x11c72, 0x11c8f }, + { 0x11c92, 0x11ca7 }, + { 0x11ca9, 0x11cb6 }, + { 0x11d00, 0x11d06 }, + { 0x11d08, 0x11d09 }, + { 0x11d0b, 0x11d36 }, + { 0x11d3a, 0x11d3a }, + { 0x11d3c, 0x11d3d }, + { 0x11d3f, 0x11d47 }, + { 0x11d50, 0x11d59 }, + { 0x11d60, 0x11d65 }, + { 0x11d67, 0x11d68 }, + { 0x11d6a, 0x11d8e }, + { 0x11d90, 0x11d91 }, + { 0x11d93, 0x11d98 }, + { 0x11da0, 0x11da9 }, + { 0x11ee0, 0x11ef6 }, + { 0x11fb0, 0x11fb0 }, + { 0x12000, 0x12399 }, + { 0x12400, 0x1246e }, + { 0x12480, 0x12543 }, + { 0x12f90, 0x12ff0 }, + { 0x13000, 0x1342e }, + { 0x14400, 0x14646 }, + { 0x16800, 0x16a38 }, + { 0x16a40, 0x16a5e }, + { 0x16a60, 0x16a69 }, + { 0x16a70, 0x16abe }, + { 0x16ac0, 0x16ac9 }, + { 0x16ad0, 0x16aed }, + { 0x16af0, 0x16af4 }, + { 0x16b00, 0x16b36 }, + { 0x16b40, 0x16b43 }, + { 0x16b50, 0x16b59 }, + { 0x16b63, 0x16b77 }, + { 0x16b7d, 0x16b8f }, + { 0x16e40, 0x16e7f }, + { 0x16f00, 0x16f4a }, + { 0x16f4f, 0x16f87 }, + { 0x16f8f, 0x16f9f }, + { 0x16fe0, 0x16fe1 }, + { 0x16fe3, 0x16fe4 }, + { 0x16ff0, 0x16ff1 }, + { 0x17000, 0x187f7 }, + { 0x18800, 0x18cd5 }, + { 0x18d00, 0x18d08 }, + { 0x1aff0, 0x1aff3 }, + { 0x1aff5, 0x1affb }, + { 0x1affd, 0x1affe }, + { 0x1b000, 0x1b122 }, + { 0x1b150, 0x1b152 }, + { 0x1b164, 0x1b167 }, + { 0x1b170, 0x1b2fb }, + { 0x1bc00, 0x1bc6a }, + { 0x1bc70, 0x1bc7c }, + { 0x1bc80, 0x1bc88 }, + { 0x1bc90, 0x1bc99 }, + { 0x1bc9d, 0x1bc9e }, + { 0x1cf00, 0x1cf2d }, + { 0x1cf30, 0x1cf46 }, + { 0x1d165, 0x1d169 }, + { 0x1d16d, 0x1d172 }, + { 0x1d17b, 0x1d182 }, + { 0x1d185, 0x1d18b }, + { 0x1d1aa, 0x1d1ad }, + { 0x1d242, 0x1d244 }, + { 0x1d400, 0x1d454 }, + { 0x1d456, 0x1d49c }, + { 0x1d49e, 0x1d49f }, + { 0x1d4a2, 0x1d4a2 }, + { 0x1d4a5, 0x1d4a6 }, + { 0x1d4a9, 0x1d4ac }, + { 0x1d4ae, 0x1d4b9 }, + { 0x1d4bb, 0x1d4bb }, + { 0x1d4bd, 0x1d4c3 }, + { 0x1d4c5, 0x1d505 }, + { 0x1d507, 0x1d50a }, + { 0x1d50d, 0x1d514 }, + { 0x1d516, 0x1d51c }, + { 0x1d51e, 0x1d539 }, + { 0x1d53b, 0x1d53e }, + { 0x1d540, 0x1d544 }, + { 0x1d546, 0x1d546 }, + { 0x1d54a, 0x1d550 }, + { 0x1d552, 0x1d6a5 }, + { 0x1d6a8, 0x1d6c0 }, + { 0x1d6c2, 0x1d6da }, + { 0x1d6dc, 0x1d6fa }, + { 0x1d6fc, 0x1d714 }, + { 0x1d716, 0x1d734 }, + { 0x1d736, 0x1d74e }, + { 0x1d750, 0x1d76e }, + { 0x1d770, 0x1d788 }, + { 0x1d78a, 0x1d7a8 }, + { 0x1d7aa, 0x1d7c2 }, + { 0x1d7c4, 0x1d7cb }, + { 0x1d7ce, 0x1d7ff }, + { 0x1da00, 0x1da36 }, + { 0x1da3b, 0x1da6c }, + { 0x1da75, 0x1da75 }, + { 0x1da84, 0x1da84 }, + { 0x1da9b, 0x1da9f }, + { 0x1daa1, 0x1daaf }, + { 0x1df00, 0x1df1e }, + { 0x1e000, 0x1e006 }, + { 0x1e008, 0x1e018 }, + { 0x1e01b, 0x1e021 }, + { 0x1e023, 0x1e024 }, + { 0x1e026, 0x1e02a }, + { 0x1e100, 0x1e12c }, + { 0x1e130, 0x1e13d }, + { 0x1e140, 0x1e149 }, + { 0x1e14e, 0x1e14e }, + { 0x1e290, 0x1e2ae }, + { 0x1e2c0, 0x1e2f9 }, + { 0x1e7e0, 0x1e7e6 }, + { 0x1e7e8, 0x1e7eb }, + { 0x1e7ed, 0x1e7ee }, + { 0x1e7f0, 0x1e7fe }, + { 0x1e800, 0x1e8c4 }, + { 0x1e8d0, 0x1e8d6 }, + { 0x1e900, 0x1e94b }, + { 0x1e950, 0x1e959 }, + { 0x1ee00, 0x1ee03 }, + { 0x1ee05, 0x1ee1f }, + { 0x1ee21, 0x1ee22 }, + { 0x1ee24, 0x1ee24 }, + { 0x1ee27, 0x1ee27 }, + { 0x1ee29, 0x1ee32 }, + { 0x1ee34, 0x1ee37 }, + { 0x1ee39, 0x1ee39 }, + { 0x1ee3b, 0x1ee3b }, + { 0x1ee42, 0x1ee42 }, + { 0x1ee47, 0x1ee47 }, + { 0x1ee49, 0x1ee49 }, + { 0x1ee4b, 0x1ee4b }, + { 0x1ee4d, 0x1ee4f }, + { 0x1ee51, 0x1ee52 }, + { 0x1ee54, 0x1ee54 }, + { 0x1ee57, 0x1ee57 }, + { 0x1ee59, 0x1ee59 }, + { 0x1ee5b, 0x1ee5b }, + { 0x1ee5d, 0x1ee5d }, + { 0x1ee5f, 0x1ee5f }, + { 0x1ee61, 0x1ee62 }, + { 0x1ee64, 0x1ee64 }, + { 0x1ee67, 0x1ee6a }, + { 0x1ee6c, 0x1ee72 }, + { 0x1ee74, 0x1ee77 }, + { 0x1ee79, 0x1ee7c }, + { 0x1ee7e, 0x1ee7e }, + { 0x1ee80, 0x1ee89 }, + { 0x1ee8b, 0x1ee9b }, + { 0x1eea1, 0x1eea3 }, + { 0x1eea5, 0x1eea9 }, + { 0x1eeab, 0x1eebb }, + { 0x1fbf0, 0x1fbf9 }, + { 0x20000, 0x2a6df }, + { 0x2a700, 0x2b738 }, + { 0x2b740, 0x2b81d }, + { 0x2b820, 0x2cea1 }, + { 0x2ceb0, 0x2ebe0 }, + { 0x2f800, 0x2fa1d }, + { 0x30000, 0x3134a }, + { 0xe0100, 0xe01ef }, + { 0x0, 0x0 }, +}; + +#endif // CHAR_RANGE_INC diff --git a/core/string/char_utils.h b/core/string/char_utils.h index 0afd058f01..67147a4327 100644 --- a/core/string/char_utils.h +++ b/core/string/char_utils.h @@ -33,6 +33,26 @@ #include "core/typedefs.h" +#include "char_range.inc" + +static _FORCE_INLINE_ bool is_unicode_identifier_start(char32_t c) { + for (int i = 0; xid_start[i].start != 0; i++) { + if (c >= xid_start[i].start && c <= xid_start[i].end) { + return true; + } + } + return false; +} + +static _FORCE_INLINE_ bool is_unicode_identifier_continue(char32_t c) { + for (int i = 0; xid_continue[i].start != 0; i++) { + if (c >= xid_continue[i].start && c <= xid_continue[i].end) { + return true; + } + } + return false; +} + static _FORCE_INLINE_ bool is_ascii_upper_case(char32_t c) { return (c >= 'A' && c <= 'Z'); } diff --git a/core/string/print_string.cpp b/core/string/print_string.cpp index f58486e0a5..592da58fe7 100644 --- a/core/string/print_string.cpp +++ b/core/string/print_string.cpp @@ -30,13 +30,12 @@ #include "print_string.h" +#include "core/core_globals.h" #include "core/os/os.h" #include <stdio.h> static PrintHandlerList *print_handler_list = nullptr; -bool _print_line_enabled = true; -bool _print_error_enabled = true; void add_print_handler(PrintHandlerList *p_handler) { _global_lock(); @@ -70,7 +69,7 @@ void remove_print_handler(const PrintHandlerList *p_handler) { } void __print_line(String p_string) { - if (!_print_line_enabled) { + if (!CoreGlobals::print_line_enabled) { return; } @@ -87,7 +86,7 @@ void __print_line(String p_string) { } void __print_line_rich(String p_string) { - if (!_print_line_enabled) { + if (!CoreGlobals::print_line_enabled) { return; } @@ -178,7 +177,7 @@ void __print_line_rich(String p_string) { } void print_error(String p_string) { - if (!_print_error_enabled) { + if (!CoreGlobals::print_error_enabled) { return; } diff --git a/core/string/print_string.h b/core/string/print_string.h index 823e2c29e8..ca930a3a0f 100644 --- a/core/string/print_string.h +++ b/core/string/print_string.h @@ -56,8 +56,6 @@ String stringify_variants(Variant p_var, Args... p_args) { void add_print_handler(PrintHandlerList *p_handler); void remove_print_handler(const PrintHandlerList *p_handler); -extern bool _print_line_enabled; -extern bool _print_error_enabled; extern void __print_line(String p_string); extern void __print_line_rich(String p_string); extern void print_error(String p_string); diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index beefe54faf..e93375bff7 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1656,7 +1656,7 @@ String String::utf8(const char *p_utf8, int p_len) { return ret; } -Error String::parse_utf8(const char *p_utf8, int p_len) { +Error String::parse_utf8(const char *p_utf8, int p_len, bool p_skip_cr) { if (!p_utf8) { return ERR_INVALID_DATA; } @@ -1689,6 +1689,10 @@ Error String::parse_utf8(const char *p_utf8, int p_len) { uint8_t c = *ptrtmp >= 0 ? *ptrtmp : uint8_t(256 + *ptrtmp); if (skip == 0) { + if (p_skip_cr && c == '\r') { + ptrtmp++; + continue; + } /* Determine the number of characters in sequence */ if ((c & 0x80) == 0) { skip = 0; @@ -1753,6 +1757,10 @@ Error String::parse_utf8(const char *p_utf8, int p_len) { uint8_t c = *p_utf8 >= 0 ? *p_utf8 : uint8_t(256 + *p_utf8); if (skip == 0) { + if (p_skip_cr && c == '\r') { + p_utf8++; + continue; + } /* Determine the number of characters in sequence */ if ((c & 0x80) == 0) { *(dst++) = c; diff --git a/core/string/ustring.h b/core/string/ustring.h index 7672663964..6c3169f136 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -377,7 +377,7 @@ public: CharString ascii(bool p_allow_extended = false) const; CharString utf8() const; - Error parse_utf8(const char *p_utf8, int p_len = -1); + Error parse_utf8(const char *p_utf8, int p_len = -1, bool p_skip_cr = false); static String utf8(const char *p_utf8, int p_len = -1); Char16String utf16() const; diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h index e760fc2176..f98b2308c9 100644 --- a/core/templates/cowdata.h +++ b/core/templates/cowdata.h @@ -36,6 +36,7 @@ #include "core/templates/safe_refcount.h" #include <string.h> +#include <type_traits> template <class T> class Vector; @@ -158,6 +159,7 @@ public: return _ptr[p_index]; } + template <bool p_ensure_zero = false> Error resize(int p_size); _FORCE_INLINE_ void remove_at(int p_index) { @@ -204,7 +206,7 @@ void CowData<T>::_unref(void *p_data) { } // clean up - if (!__has_trivial_destructor(T)) { + if (!std::is_trivially_destructible<T>::value) { uint32_t *count = _get_size(); T *data = (T *)(count + 1); @@ -239,7 +241,7 @@ uint32_t CowData<T>::_copy_on_write() { T *_data = (T *)(mem_new); // initialize new elements - if (__has_trivial_copy(T)) { + if (std::is_trivially_copyable<T>::value) { memcpy(mem_new, _ptr, current_size * sizeof(T)); } else { @@ -257,6 +259,7 @@ uint32_t CowData<T>::_copy_on_write() { } template <class T> +template <bool p_ensure_zero> Error CowData<T>::resize(int p_size) { ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER); @@ -302,16 +305,18 @@ Error CowData<T>::resize(int p_size) { // construct the newly created elements - if (!__has_trivial_constructor(T)) { + if (!std::is_trivially_constructible<T>::value) { for (int i = *_get_size(); i < p_size; i++) { memnew_placement(&_ptr[i], T); } + } else if (p_ensure_zero) { + memset((void *)(_ptr + current_size), 0, (p_size - current_size) * sizeof(T)); } *_get_size() = p_size; } else if (p_size < current_size) { - if (!__has_trivial_destructor(T)) { + if (!std::is_trivially_destructible<T>::value) { // deinitialize no longer needed elements for (uint32_t i = p_size; i < *_get_size(); i++) { T *t = &_ptr[i]; diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h index 8d687effcf..49690f2373 100644 --- a/core/templates/local_vector.h +++ b/core/templates/local_vector.h @@ -37,6 +37,7 @@ #include "core/templates/vector.h" #include <initializer_list> +#include <type_traits> // If tight, it grows strictly as much as needed. // Otherwise, it grows exponentially (the default and what you want in most cases). @@ -67,7 +68,7 @@ public: CRASH_COND_MSG(!data, "Out of memory"); } - if (!__has_trivial_constructor(T) && !force_trivial) { + if (!std::is_trivially_constructible<T>::value && !force_trivial) { memnew_placement(&data[count++], T(p_elem)); } else { data[count++] = p_elem; @@ -80,7 +81,7 @@ public: for (U i = p_index; i < count; i++) { data[i] = data[i + 1]; } - if (!__has_trivial_destructor(T) && !force_trivial) { + if (!std::is_trivially_destructible<T>::value && !force_trivial) { data[count].~T(); } } @@ -93,7 +94,7 @@ public: if (count > p_index) { data[p_index] = data[count]; } - if (!__has_trivial_destructor(T) && !force_trivial) { + if (!std::is_trivially_destructible<T>::value && !force_trivial) { data[count].~T(); } } @@ -134,7 +135,7 @@ public: _FORCE_INLINE_ U size() const { return count; } void resize(U p_size) { if (p_size < count) { - if (!__has_trivial_destructor(T) && !force_trivial) { + if (!std::is_trivially_destructible<T>::value && !force_trivial) { for (U i = p_size; i < count; i++) { data[i].~T(); } @@ -151,7 +152,7 @@ public: data = (T *)memrealloc(data, capacity * sizeof(T)); CRASH_COND_MSG(!data, "Out of memory"); } - if (!__has_trivial_constructor(T) && !force_trivial) { + if (!std::is_trivially_constructible<T>::value && !force_trivial) { for (U i = count; i < p_size; i++) { memnew_placement(&data[i], T); } diff --git a/core/templates/paged_allocator.h b/core/templates/paged_allocator.h index cf5911a847..43aab052fd 100644 --- a/core/templates/paged_allocator.h +++ b/core/templates/paged_allocator.h @@ -31,11 +31,14 @@ #ifndef PAGED_ALLOCATOR_H #define PAGED_ALLOCATOR_H +#include "core/core_globals.h" #include "core/os/memory.h" #include "core/os/spin_lock.h" +#include "core/string/ustring.h" #include "core/typedefs.h" #include <type_traits> +#include <typeinfo> template <class T, bool thread_safe = false> class PagedAllocator { @@ -132,7 +135,12 @@ public: } ~PagedAllocator() { - ERR_FAIL_COND_MSG(allocs_available < pages_allocated * page_size, "Pages in use exist at exit in PagedAllocator"); + if (allocs_available < pages_allocated * page_size) { + if (CoreGlobals::leak_reporting_enabled) { + ERR_FAIL_COND_MSG(allocs_available < pages_allocated * page_size, String("Pages in use exist at exit in PagedAllocator: ") + String(typeid(T).name())); + } + return; + } reset(); } }; diff --git a/core/templates/paged_array.h b/core/templates/paged_array.h index 33d2757bec..f1ede556e6 100644 --- a/core/templates/paged_array.h +++ b/core/templates/paged_array.h @@ -35,6 +35,8 @@ #include "core/os/spin_lock.h" #include "core/typedefs.h" +#include <type_traits> + // PagedArray is used mainly for filling a very large array from multiple threads efficiently and without causing major fragmentation // PageArrayPool manages central page allocation in a thread safe matter @@ -197,7 +199,7 @@ public: uint32_t page = count >> page_size_shift; uint32_t offset = count & page_size_mask; - if (!__has_trivial_constructor(T)) { + if (!std::is_trivially_constructible<T>::value) { memnew_placement(&page_data[page][offset], T(p_value)); } else { page_data[page][offset] = p_value; @@ -209,7 +211,7 @@ public: _FORCE_INLINE_ void pop_back() { ERR_FAIL_COND(count == 0); - if (!__has_trivial_destructor(T)) { + if (!std::is_trivially_destructible<T>::value) { uint32_t page = (count - 1) >> page_size_shift; uint32_t offset = (count - 1) & page_size_mask; page_data[page][offset].~T(); @@ -226,7 +228,7 @@ public: void clear() { //destruct if needed - if (!__has_trivial_destructor(T)) { + if (!std::is_trivially_destructible<T>::value) { for (uint64_t i = 0; i < count; i++) { uint32_t page = i >> page_size_shift; uint32_t offset = i & page_size_mask; @@ -309,13 +311,13 @@ public: uint32_t to_copy = MIN(page_size - new_remainder, remainder); for (uint32_t i = 0; i < to_copy; i++) { - if (!__has_trivial_constructor(T)) { + if (!std::is_trivially_constructible<T>::value) { memnew_placement(&dst_page[i + new_remainder], T(remainder_page[i + remainder - to_copy])); } else { dst_page[i + new_remainder] = remainder_page[i + remainder - to_copy]; } - if (!__has_trivial_destructor(T)) { + if (!std::is_trivially_destructible<T>::value) { remainder_page[i + remainder - to_copy].~T(); } } diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h index 9c74b41818..320faebe98 100644 --- a/core/templates/rid_owner.h +++ b/core/templates/rid_owner.h @@ -79,7 +79,7 @@ class RID_Alloc : public RID_AllocBase { const char *description = nullptr; - SpinLock spin_lock; + mutable SpinLock spin_lock; _FORCE_INLINE_ RID _allocate_rid() { if (THREAD_SAFE) { @@ -220,7 +220,7 @@ public: memnew_placement(mem, T(p_value)); } - _FORCE_INLINE_ bool owns(const RID &p_rid) { + _FORCE_INLINE_ bool owns(const RID &p_rid) const { if (THREAD_SAFE) { spin_lock.lock(); } @@ -292,7 +292,7 @@ public: _FORCE_INLINE_ uint32_t get_rid_count() const { return alloc_count; } - void get_owned_list(List<RID> *p_owned) { + void get_owned_list(List<RID> *p_owned) const { if (THREAD_SAFE) { spin_lock.lock(); } @@ -308,7 +308,7 @@ public: } //used for fast iteration in the elements or RIDs - void fill_owned_buffer(RID *p_rid_buffer) { + void fill_owned_buffer(RID *p_rid_buffer) const { if (THREAD_SAFE) { spin_lock.lock(); } @@ -402,7 +402,7 @@ public: *ptr = p_new_ptr; } - _FORCE_INLINE_ bool owns(const RID &p_rid) { + _FORCE_INLINE_ bool owns(const RID &p_rid) const { return alloc.owns(p_rid); } @@ -414,11 +414,11 @@ public: return alloc.get_rid_count(); } - _FORCE_INLINE_ void get_owned_list(List<RID> *p_owned) { + _FORCE_INLINE_ void get_owned_list(List<RID> *p_owned) const { return alloc.get_owned_list(p_owned); } - void fill_owned_buffer(RID *p_rid_buffer) { + void fill_owned_buffer(RID *p_rid_buffer) const { alloc.fill_owned_buffer(p_rid_buffer); } @@ -458,7 +458,7 @@ public: return alloc.get_or_null(p_rid); } - _FORCE_INLINE_ bool owns(const RID &p_rid) { + _FORCE_INLINE_ bool owns(const RID &p_rid) const { return alloc.owns(p_rid); } @@ -470,10 +470,10 @@ public: return alloc.get_rid_count(); } - _FORCE_INLINE_ void get_owned_list(List<RID> *p_owned) { + _FORCE_INLINE_ void get_owned_list(List<RID> *p_owned) const { return alloc.get_owned_list(p_owned); } - void fill_owned_buffer(RID *p_rid_buffer) { + void fill_owned_buffer(RID *p_rid_buffer) const { alloc.fill_owned_buffer(p_rid_buffer); } diff --git a/core/templates/vector.h b/core/templates/vector.h index f3f5ed76a7..51595a75f5 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -89,6 +89,7 @@ public: _FORCE_INLINE_ void set(int p_index, const T &p_elem) { _cowdata.set(p_index, p_elem); } _FORCE_INLINE_ int size() const { return _cowdata.size(); } Error resize(int p_size) { return _cowdata.resize(p_size); } + Error resize_zeroed(int p_size) { return _cowdata.template resize<true>(p_size); } _FORCE_INLINE_ const T &operator[](int p_index) const { return _cowdata.get(p_index); } Error insert(int p_pos, T p_val) { return _cowdata.insert(p_pos, p_val); } int find(const T &p_val, int p_from = 0) const { return _cowdata.find(p_val, p_from); } diff --git a/core/variant/array.cpp b/core/variant/array.cpp index af166e09a3..c1bdd6a6bc 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -441,7 +441,7 @@ Array Array::filter(const Callable &p_callable) const { Variant result; Callable::CallError ce; - p_callable.call(argptrs, 1, result, ce); + p_callable.callp(argptrs, 1, result, ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(Array(), "Error calling method from 'filter': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce)); } @@ -467,7 +467,7 @@ Array Array::map(const Callable &p_callable) const { Variant result; Callable::CallError ce; - p_callable.call(argptrs, 1, result, ce); + p_callable.callp(argptrs, 1, result, ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(Array(), "Error calling method from 'map': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce)); } @@ -493,7 +493,7 @@ Variant Array::reduce(const Callable &p_callable, const Variant &p_accum) const Variant result; Callable::CallError ce; - p_callable.call(argptrs, 2, result, ce); + p_callable.callp(argptrs, 2, result, ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(Variant(), "Error calling method from 'reduce': " + Variant::get_callable_error_text(p_callable, argptrs, 2, ce)); } @@ -510,7 +510,7 @@ bool Array::any(const Callable &p_callable) const { Variant result; Callable::CallError ce; - p_callable.call(argptrs, 1, result, ce); + p_callable.callp(argptrs, 1, result, ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(false, "Error calling method from 'any': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce)); } @@ -532,7 +532,7 @@ bool Array::all(const Callable &p_callable) const { Variant result; Callable::CallError ce; - p_callable.call(argptrs, 1, result, ce); + p_callable.callp(argptrs, 1, result, ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(false, "Error calling method from 'all': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce)); } diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index f20ec4037a..28efb43fc5 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -36,11 +36,11 @@ #include "core/object/ref_counted.h" #include "core/object/script_language.h" -void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const { +void Callable::call_deferredp(const Variant **p_arguments, int p_argcount) const { MessageQueue::get_singleton()->push_callablep(*this, p_arguments, p_argcount); } -void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const { +void Callable::callp(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const { if (is_null()) { r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL; r_call_error.argument = 0; @@ -63,21 +63,23 @@ void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_retu } } -void Callable::rpc(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const { +Error Callable::rpcp(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const { if (is_null()) { r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL; r_call_error.argument = 0; r_call_error.expected = 0; + return ERR_UNCONFIGURED; } else if (!is_custom()) { r_call_error.error = CallError::CALL_ERROR_INVALID_METHOD; r_call_error.argument = 0; r_call_error.expected = 0; + return ERR_UNCONFIGURED; } else { - custom->rpc(p_id, p_arguments, p_argcount, r_call_error); + return custom->rpc(p_id, p_arguments, p_argcount, r_call_error); } } -Callable Callable::bind(const Variant **p_arguments, int p_argcount) const { +Callable Callable::bindp(const Variant **p_arguments, int p_argcount) const { Vector<Variant> args; args.resize(p_argcount); for (int i = 0; i < p_argcount; i++) { @@ -316,10 +318,11 @@ StringName CallableCustom::get_method() const { ERR_FAIL_V_MSG(StringName(), vformat("Can't get method on CallableCustom \"%s\".", get_as_text())); } -void CallableCustom::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { +Error CallableCustom::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { r_call_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; r_call_error.argument = 0; r_call_error.expected = 0; + return ERR_UNCONFIGURED; } const Callable *CallableCustom::get_base_comparator() const { @@ -387,7 +390,7 @@ Error Signal::connect(const Callable &p_callable, uint32_t p_flags) { Object *object = get_object(); ERR_FAIL_COND_V(!object, ERR_UNCONFIGURED); - return object->connect(name, p_callable, varray(), p_flags); + return object->connect(name, p_callable, p_flags); } void Signal::disconnect(const Callable &p_callable) { @@ -435,7 +438,7 @@ bool CallableComparator::operator()(const Variant &p_l, const Variant &p_r) cons const Variant *args[2] = { &p_l, &p_r }; Callable::CallError err; Variant res; - func.call(args, 2, res, err); + func.callp(args, 2, res, err); ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false, "Error calling compare method: " + Variant::get_callable_error_text(func, args, 2, err)); return res; diff --git a/core/variant/callable.h b/core/variant/callable.h index bbcf5427ba..1f1c983eb3 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -45,6 +45,7 @@ class CallableCustom; // but can be optimized or customized. // Enforce 16 bytes with `alignas` to avoid arch-specific alignment issues on x86 vs armv7. + class Callable { alignas(8) StringName method; union { @@ -68,10 +69,10 @@ public: int expected = 0; }; - void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const; - void call_deferred(const Variant **p_arguments, int p_argcount) const; + void callp(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const; + void call_deferredp(const Variant **p_arguments, int p_argcount) const; - void rpc(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const; + Error rpcp(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const; _FORCE_INLINE_ bool is_null() const { return method == StringName() && object == 0; @@ -84,7 +85,10 @@ public: } bool is_valid() const; - Callable bind(const Variant **p_arguments, int p_argcount) const; + template <typename... VarArgs> + Callable bind(VarArgs... p_args); + + Callable bindp(const Variant **p_arguments, int p_argcount) const; Callable unbind(int p_argcount) const; Object *get_object() const; @@ -129,7 +133,7 @@ public: virtual StringName get_method() const; virtual ObjectID get_object() const = 0; //must always be able to provide an object virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const = 0; - virtual void rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const; + virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const; virtual const Callable *get_base_comparator() const; CallableCustom(); diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp index 1a400b4360..d26aa2ae46 100644 --- a/core/variant/callable_bind.cpp +++ b/core/variant/callable_bind.cpp @@ -96,7 +96,7 @@ void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Varia args[i + p_argcount] = (const Variant *)&binds[i]; } - callable.call(args, p_argcount + binds.size(), r_return_value, r_call_error); + callable.callp(args, p_argcount + binds.size(), r_return_value, r_call_error); } CallableCustomBind::CallableCustomBind(const Callable &p_callable, const Vector<Variant> &p_binds) { @@ -171,7 +171,7 @@ void CallableCustomUnbind::call(const Variant **p_arguments, int p_argcount, Var r_call_error.expected = argcount; return; } - callable.call(p_arguments, p_argcount - argcount, r_return_value, r_call_error); + callable.callp(p_arguments, p_argcount - argcount, r_return_value, r_call_error); } CallableCustomUnbind::CallableCustomUnbind(const Callable &p_callable, int p_argcount) { @@ -181,28 +181,3 @@ CallableCustomUnbind::CallableCustomUnbind(const Callable &p_callable, int p_arg CallableCustomUnbind::~CallableCustomUnbind() { } - -Callable callable_bind(const Callable &p_callable, const Variant &p_arg1) { - const Variant *args[1] = { &p_arg1 }; - return p_callable.bind(args, 1); -} - -Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2) { - const Variant *args[2] = { &p_arg1, &p_arg2 }; - return p_callable.bind(args, 2); -} - -Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3) { - const Variant *args[3] = { &p_arg1, &p_arg2, &p_arg3 }; - return p_callable.bind(args, 3); -} - -Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4) { - const Variant *args[4] = { &p_arg1, &p_arg2, &p_arg3, &p_arg4 }; - return p_callable.bind(args, 4); -} - -Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5) { - const Variant *args[5] = { &p_arg1, &p_arg2, &p_arg3, &p_arg4, &p_arg5 }; - return p_callable.bind(args, 5); -} diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h index a5c830e109..f7351d29e0 100644 --- a/core/variant/callable_bind.h +++ b/core/variant/callable_bind.h @@ -84,10 +84,4 @@ public: virtual ~CallableCustomUnbind(); }; -Callable callable_bind(const Callable &p_callable, const Variant &p_arg1); -Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2); -Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3); -Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4); -Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5); - #endif // CALLABLE_BIND_H diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 6763dd66b0..a5bc6c229d 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -39,6 +39,10 @@ #include "core/string/print_string.h" #include "core/variant/variant_parser.h" +PagedAllocator<Variant::Pools::BucketSmall, true> Variant::Pools::_bucket_small; +PagedAllocator<Variant::Pools::BucketMedium, true> Variant::Pools::_bucket_medium; +PagedAllocator<Variant::Pools::BucketLarge, true> Variant::Pools::_bucket_large; + String Variant::get_type_name(Variant::Type p_type) { switch (p_type) { case NIL: { @@ -1162,7 +1166,8 @@ void Variant::reference(const Variant &p_variant) { memnew_placement(_data._mem, Rect2i(*reinterpret_cast<const Rect2i *>(p_variant._data._mem))); } break; case TRANSFORM2D: { - _data._transform2d = memnew(Transform2D(*p_variant._data._transform2d)); + _data._transform2d = (Transform2D *)Pools::_bucket_small.alloc(); + memnew_placement(_data._transform2d, Transform2D(*p_variant._data._transform2d)); } break; case VECTOR3: { memnew_placement(_data._mem, Vector3(*reinterpret_cast<const Vector3 *>(p_variant._data._mem))); @@ -1179,23 +1184,24 @@ void Variant::reference(const Variant &p_variant) { case PLANE: { memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem))); } break; - case AABB: { - _data._aabb = memnew(::AABB(*p_variant._data._aabb)); + _data._aabb = (::AABB *)Pools::_bucket_small.alloc(); + memnew_placement(_data._aabb, ::AABB(*p_variant._data._aabb)); } break; case QUATERNION: { memnew_placement(_data._mem, Quaternion(*reinterpret_cast<const Quaternion *>(p_variant._data._mem))); - } break; case BASIS: { - _data._basis = memnew(Basis(*p_variant._data._basis)); - + _data._basis = (Basis *)Pools::_bucket_medium.alloc(); + memnew_placement(_data._basis, Basis(*p_variant._data._basis)); } break; case TRANSFORM3D: { - _data._transform3d = memnew(Transform3D(*p_variant._data._transform3d)); + _data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc(); + memnew_placement(_data._transform3d, Transform3D(*p_variant._data._transform3d)); } break; case PROJECTION: { - _data._projection = memnew(Projection(*p_variant._data._projection)); + _data._projection = (Projection *)Pools::_bucket_large.alloc(); + memnew_placement(_data._projection, Projection(*p_variant._data._projection)); } break; // misc types @@ -1381,19 +1387,39 @@ void Variant::_clear_internal() { RECT2 */ case TRANSFORM2D: { - memdelete(_data._transform2d); + if (_data._transform2d) { + _data._transform2d->~Transform2D(); + Pools::_bucket_small.free((Pools::BucketSmall *)_data._transform2d); + _data._transform2d = nullptr; + } } break; case AABB: { - memdelete(_data._aabb); + if (_data._aabb) { + _data._aabb->~AABB(); + Pools::_bucket_small.free((Pools::BucketSmall *)_data._aabb); + _data._aabb = nullptr; + } } break; case BASIS: { - memdelete(_data._basis); + if (_data._basis) { + _data._basis->~Basis(); + Pools::_bucket_medium.free((Pools::BucketMedium *)_data._basis); + _data._basis = nullptr; + } } break; case TRANSFORM3D: { - memdelete(_data._transform3d); + if (_data._transform3d) { + _data._transform3d->~Transform3D(); + Pools::_bucket_medium.free((Pools::BucketMedium *)_data._transform3d); + _data._transform3d = nullptr; + } } break; case PROJECTION: { - memdelete(_data._projection); + if (_data._projection) { + _data._projection->~Projection(); + Pools::_bucket_large.free((Pools::BucketLarge *)_data._projection); + _data._projection = nullptr; + } } break; // misc types case STRING_NAME: { @@ -2609,12 +2635,14 @@ Variant::Variant(const Plane &p_plane) { Variant::Variant(const ::AABB &p_aabb) { type = AABB; - _data._aabb = memnew(::AABB(p_aabb)); + _data._aabb = (::AABB *)Pools::_bucket_small.alloc(); + memnew_placement(_data._aabb, ::AABB(p_aabb)); } Variant::Variant(const Basis &p_matrix) { type = BASIS; - _data._basis = memnew(Basis(p_matrix)); + _data._basis = (Basis *)Pools::_bucket_medium.alloc(); + memnew_placement(_data._basis, Basis(p_matrix)); } Variant::Variant(const Quaternion &p_quaternion) { @@ -2624,17 +2652,20 @@ Variant::Variant(const Quaternion &p_quaternion) { Variant::Variant(const Transform3D &p_transform) { type = TRANSFORM3D; - _data._transform3d = memnew(Transform3D(p_transform)); + _data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc(); + memnew_placement(_data._transform3d, Transform3D(p_transform)); } Variant::Variant(const Projection &pp_projection) { type = PROJECTION; - _data._projection = memnew(Projection(pp_projection)); + _data._projection = (Projection *)Pools::_bucket_large.alloc(); + memnew_placement(_data._projection, Projection(pp_projection)); } Variant::Variant(const Transform2D &p_transform) { type = TRANSFORM2D; - _data._transform2d = memnew(Transform2D(p_transform)); + _data._transform2d = (Transform2D *)Pools::_bucket_small.alloc(); + memnew_placement(_data._transform2d, Transform2D(p_transform)); } Variant::Variant(const Color &p_color) { diff --git a/core/variant/variant.h b/core/variant/variant.h index 465c31730c..212f94a9a8 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -54,6 +54,7 @@ #include "core/os/keyboard.h" #include "core/string/node_path.h" #include "core/string/ustring.h" +#include "core/templates/paged_allocator.h" #include "core/templates/rid.h" #include "core/variant/array.h" #include "core/variant/callable.h" @@ -134,6 +135,30 @@ public: }; private: + struct Pools { + union BucketSmall { + BucketSmall() {} + ~BucketSmall() {} + Transform2D _transform2d; + ::AABB _aabb; + }; + union BucketMedium { + BucketMedium() {} + ~BucketMedium() {} + Basis _basis; + Transform3D _transform3d; + }; + union BucketLarge { + BucketLarge() {} + ~BucketLarge() {} + Projection _projection; + }; + + static PagedAllocator<BucketSmall, true> _bucket_small; + static PagedAllocator<BucketMedium, true> _bucket_medium; + static PagedAllocator<BucketLarge, true> _bucket_large; + }; + friend struct _VariantCall; friend class VariantInternal; // Variant takes 20 bytes when real_t is float, and 36 if double @@ -784,4 +809,14 @@ const Variant::ObjData &Variant::_get_obj() const { String vformat(const String &p_text, const Variant &p1 = Variant(), const Variant &p2 = Variant(), const Variant &p3 = Variant(), const Variant &p4 = Variant(), const Variant &p5 = Variant()); +template <typename... VarArgs> +Callable Callable::bind(VarArgs... p_args) { + Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. + const Variant *argptrs[sizeof...(p_args) + 1]; + for (uint32_t i = 0; i < sizeof...(p_args); i++) { + argptrs[i] = &args[i]; + } + return bindp(sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); +} + #endif // VARIANT_H diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 7518d81233..5c298f9b3b 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -895,17 +895,17 @@ struct _VariantCall { static void func_Callable_call(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); - callable->call(p_args, p_argcount, r_ret, r_error); + callable->callp(p_args, p_argcount, r_ret, r_error); } static void func_Callable_call_deferred(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); - callable->call_deferred(p_args, p_argcount); + callable->call_deferredp(p_args, p_argcount); } static void func_Callable_rpc(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); - callable->rpc(0, p_args, p_argcount, r_error); + callable->rpcp(0, p_args, p_argcount, r_error); } static void func_Callable_rpc_id(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { @@ -920,13 +920,13 @@ struct _VariantCall { r_error.expected = Variant::INT; } else { Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); - callable->rpc(*p_args[0], &p_args[1], p_argcount - 1, r_error); + callable->rpcp(*p_args[0], &p_args[1], p_argcount - 1, r_error); } } static void func_Callable_bind(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); - r_ret = callable->bind(p_args, p_argcount); + r_ret = callable->bindp(p_args, p_argcount); } static void func_Signal_emit(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { @@ -1731,11 +1731,21 @@ static void _register_variant_builtin_methods() { bind_method(Vector4, max_axis_index, sarray(), varray()); bind_method(Vector4, length, sarray(), varray()); bind_method(Vector4, length_squared, sarray(), varray()); - bind_method(Vector4, sign, sarray(), varray()); bind_method(Vector4, abs, sarray(), varray()); + bind_method(Vector4, sign, sarray(), varray()); + bind_method(Vector4, floor, sarray(), varray()); + bind_method(Vector4, ceil, sarray(), varray()); + bind_method(Vector4, round, sarray(), varray()); + bind_method(Vector4, lerp, sarray("to", "weight"), varray()); + bind_method(Vector4, cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray()); + bind_method(Vector4, posmod, sarray("mod"), varray()); + bind_method(Vector4, posmodv, sarray("modv"), varray()); + bind_method(Vector4, snapped, sarray("step"), varray()); bind_method(Vector4, clamp, sarray("min", "max"), varray()); bind_method(Vector4, normalized, sarray(), varray()); bind_method(Vector4, is_normalized, sarray(), varray()); + bind_method(Vector4, direction_to, sarray("to"), varray()); + bind_method(Vector4, distance_to, sarray("to"), varray()); bind_method(Vector4, dot, sarray("with"), varray()); bind_method(Vector4, inverse, sarray(), varray()); bind_method(Vector4, is_equal_approx, sarray("with"), varray()); @@ -1777,7 +1787,7 @@ static void _register_variant_builtin_methods() { bind_method(Quaternion, dot, sarray("with"), varray()); bind_method(Quaternion, slerp, sarray("to", "weight"), varray()); bind_method(Quaternion, slerpni, sarray("to", "weight"), varray()); - bind_method(Quaternion, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray()); + bind_method(Quaternion, spherical_cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray()); bind_method(Quaternion, get_euler, sarray(), varray()); bind_method(Quaternion, get_axis, sarray(), varray()); bind_method(Quaternion, get_angle, sarray(), varray()); @@ -1878,8 +1888,11 @@ static void _register_variant_builtin_methods() { bind_method(Transform2D, get_skew, sarray(), varray()); bind_method(Transform2D, orthonormalized, sarray(), varray()); bind_method(Transform2D, rotated, sarray("angle"), varray()); + bind_method(Transform2D, rotated_local, sarray("angle"), varray()); bind_method(Transform2D, scaled, sarray("scale"), varray()); + bind_method(Transform2D, scaled_local, sarray("scale"), varray()); bind_method(Transform2D, translated, sarray("offset"), varray()); + bind_method(Transform2D, translated_local, sarray("offset"), varray()); bind_method(Transform2D, basis_xform, sarray("v"), varray()); bind_method(Transform2D, basis_xform_inv, sarray("v"), varray()); bind_method(Transform2D, interpolate_with, sarray("xform", "weight"), varray()); @@ -1943,10 +1956,13 @@ static void _register_variant_builtin_methods() { bind_method(Transform3D, affine_inverse, sarray(), varray()); bind_method(Transform3D, orthonormalized, sarray(), varray()); bind_method(Transform3D, rotated, sarray("axis", "angle"), varray()); + bind_method(Transform3D, rotated_local, sarray("axis", "angle"), varray()); bind_method(Transform3D, scaled, sarray("scale"), varray()); + bind_method(Transform3D, scaled_local, sarray("scale"), varray()); bind_method(Transform3D, translated, sarray("offset"), varray()); + bind_method(Transform3D, translated_local, sarray("offset"), varray()); bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); - bind_method(Transform3D, sphere_interpolate_with, sarray("xform", "weight"), varray()); + bind_method(Transform3D, spherical_interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform3D, interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform3D, is_equal_approx, sarray("xform"), varray()); @@ -2050,7 +2066,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedByteArray, remove_at, sarray("index"), varray()); bind_method(PackedByteArray, insert, sarray("at_index", "value"), varray()); bind_method(PackedByteArray, fill, sarray("value"), varray()); - bind_method(PackedByteArray, resize, sarray("new_size"), varray()); + bind_methodv(PackedByteArray, resize, &PackedByteArray::resize_zeroed, sarray("new_size"), varray()); bind_method(PackedByteArray, has, sarray("value"), varray()); bind_method(PackedByteArray, reverse, sarray(), varray()); bind_method(PackedByteArray, slice, sarray("begin", "end"), varray(INT_MAX)); @@ -2114,7 +2130,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt32Array, remove_at, sarray("index"), varray()); bind_method(PackedInt32Array, insert, sarray("at_index", "value"), varray()); bind_method(PackedInt32Array, fill, sarray("value"), varray()); - bind_method(PackedInt32Array, resize, sarray("new_size"), varray()); + bind_methodv(PackedInt32Array, resize, &PackedInt32Array::resize_zeroed, sarray("new_size"), varray()); bind_method(PackedInt32Array, has, sarray("value"), varray()); bind_method(PackedInt32Array, reverse, sarray(), varray()); bind_method(PackedInt32Array, slice, sarray("begin", "end"), varray(INT_MAX)); @@ -2137,7 +2153,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt64Array, remove_at, sarray("index"), varray()); bind_method(PackedInt64Array, insert, sarray("at_index", "value"), varray()); bind_method(PackedInt64Array, fill, sarray("value"), varray()); - bind_method(PackedInt64Array, resize, sarray("new_size"), varray()); + bind_methodv(PackedInt64Array, resize, &PackedInt64Array::resize_zeroed, sarray("new_size"), varray()); bind_method(PackedInt64Array, has, sarray("value"), varray()); bind_method(PackedInt64Array, reverse, sarray(), varray()); bind_method(PackedInt64Array, slice, sarray("begin", "end"), varray(INT_MAX)); @@ -2160,7 +2176,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat32Array, remove_at, sarray("index"), varray()); bind_method(PackedFloat32Array, insert, sarray("at_index", "value"), varray()); bind_method(PackedFloat32Array, fill, sarray("value"), varray()); - bind_method(PackedFloat32Array, resize, sarray("new_size"), varray()); + bind_methodv(PackedFloat32Array, resize, &PackedFloat32Array::resize_zeroed, sarray("new_size"), varray()); bind_method(PackedFloat32Array, has, sarray("value"), varray()); bind_method(PackedFloat32Array, reverse, sarray(), varray()); bind_method(PackedFloat32Array, slice, sarray("begin", "end"), varray(INT_MAX)); @@ -2183,7 +2199,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat64Array, remove_at, sarray("index"), varray()); bind_method(PackedFloat64Array, insert, sarray("at_index", "value"), varray()); bind_method(PackedFloat64Array, fill, sarray("value"), varray()); - bind_method(PackedFloat64Array, resize, sarray("new_size"), varray()); + bind_methodv(PackedFloat64Array, resize, &PackedFloat64Array::resize_zeroed, sarray("new_size"), varray()); bind_method(PackedFloat64Array, has, sarray("value"), varray()); bind_method(PackedFloat64Array, reverse, sarray(), varray()); bind_method(PackedFloat64Array, slice, sarray("begin", "end"), varray(INT_MAX)); diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index 961c0f3a51..874a183d29 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -36,6 +36,8 @@ // For use when you want to access the internal pointer of a Variant directly. // Use with caution. You need to be sure that the type is correct. class VariantInternal { + friend class Variant; + public: // Set type. _FORCE_INLINE_ static void initialize(Variant *v, Variant::Type p_type) { @@ -215,23 +217,28 @@ public: } _FORCE_INLINE_ static void init_transform2d(Variant *v) { - v->_data._transform2d = memnew(Transform2D); + v->_data._transform2d = (Transform2D *)Variant::Pools::_bucket_small.alloc(); + memnew_placement(v->_data._transform2d, Transform2D); v->type = Variant::TRANSFORM2D; } _FORCE_INLINE_ static void init_aabb(Variant *v) { - v->_data._aabb = memnew(AABB); + v->_data._aabb = (AABB *)Variant::Pools::_bucket_small.alloc(); + memnew_placement(v->_data._aabb, AABB); v->type = Variant::AABB; } _FORCE_INLINE_ static void init_basis(Variant *v) { - v->_data._basis = memnew(Basis); + v->_data._basis = (Basis *)Variant::Pools::_bucket_medium.alloc(); + memnew_placement(v->_data._basis, Basis); v->type = Variant::BASIS; } _FORCE_INLINE_ static void init_transform(Variant *v) { - v->_data._transform3d = memnew(Transform3D); + v->_data._transform3d = (Transform3D *)Variant::Pools::_bucket_medium.alloc(); + memnew_placement(v->_data._transform3d, Transform3D); v->type = Variant::TRANSFORM3D; } _FORCE_INLINE_ static void init_projection(Variant *v) { - v->_data._projection = memnew(Projection); + v->_data._projection = (Projection *)Variant::Pools::_bucket_large.alloc(); + memnew_placement(v->_data._projection, Projection); v->type = Variant::PROJECTION; } _FORCE_INLINE_ static void init_string_name(Variant *v) { diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index 669e18b5f7..6cca7955ae 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -341,6 +341,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Transform3D>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::TRANSFORM3D); register_op<OperatorEvaluatorXForm<::AABB, Transform3D, ::AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::AABB); register_op<OperatorEvaluatorXFormInv<::AABB, ::AABB, Transform3D>>(Variant::OP_MULTIPLY, Variant::AABB, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorXForm<Plane, Transform3D, Plane>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::PLANE); + register_op<OperatorEvaluatorXFormInv<Plane, Plane, Transform3D>>(Variant::OP_MULTIPLY, Variant::PLANE, Variant::TRANSFORM3D); register_op<OperatorEvaluatorXForm<Vector<Vector3>, Transform3D, Vector<Vector3>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::PACKED_VECTOR3_ARRAY); register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform3D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM3D); diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 1df5fa969e..34653310b1 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -1575,11 +1575,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::VECTOR4: { Vector4 v = p_variant; - p_store_string_func(p_store_string_ud, "Vector4(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ", " + rtos_fix(v.z) + ")"); + p_store_string_func(p_store_string_ud, "Vector4(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ", " + rtos_fix(v.z) + ", " + rtos_fix(v.w) + ")"); } break; case Variant::VECTOR4I: { Vector4i v = p_variant; - p_store_string_func(p_store_string_ud, "Vector4i(" + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + ")"); + p_store_string_func(p_store_string_ud, "Vector4i(" + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + ", " + itos(v.w) + ")"); } break; case Variant::PLANE: { Plane p = p_variant; diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 92dbf45f2a..57b953f7f0 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -819,6 +819,8 @@ INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2, double, real_t, 2) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2i, int64_t, int32_t, 2) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3, double, real_t, 3) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3i, int64_t, int32_t, 3) +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector4, double, real_t, 4) +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector4i, int64_t, int32_t, 4) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Quaternion, double, real_t, 4) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4) @@ -883,6 +885,8 @@ void register_indexed_setters_getters() { REGISTER_INDEXED_MEMBER(Vector2i); REGISTER_INDEXED_MEMBER(Vector3); REGISTER_INDEXED_MEMBER(Vector3i); + REGISTER_INDEXED_MEMBER(Vector4); + REGISTER_INDEXED_MEMBER(Vector4i); REGISTER_INDEXED_MEMBER(Quaternion); REGISTER_INDEXED_MEMBER(Color); REGISTER_INDEXED_MEMBER(Transform2D); diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index c1a0ad73b0..1f1439ab24 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -99,18 +99,105 @@ struct VariantUtilityFunctions { return Math::posmod(b, r); } - static inline double floor(double x) { + static inline Variant floor(Variant x, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + switch (x.get_type()) { + case Variant::INT: { + return VariantInternalAccessor<int64_t>::get(&x); + } break; + case Variant::FLOAT: { + return Math::floor(VariantInternalAccessor<double>::get(&x)); + } break; + case Variant::VECTOR2: { + return VariantInternalAccessor<Vector2>::get(&x).floor(); + } break; + case Variant::VECTOR3: { + return VariantInternalAccessor<Vector3>::get(&x).floor(); + } break; + case Variant::VECTOR4: { + return VariantInternalAccessor<Vector4>::get(&x).floor(); + } break; + default: { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + } + } + + static inline double floorf(double x) { return Math::floor(x); } - static inline double ceil(double x) { + static inline int floori(double x) { + return int(x); + } + + static inline Variant ceil(Variant x, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + switch (x.get_type()) { + case Variant::INT: { + return VariantInternalAccessor<int64_t>::get(&x); + } break; + case Variant::FLOAT: { + return Math::ceil(VariantInternalAccessor<double>::get(&x)); + } break; + case Variant::VECTOR2: { + return VariantInternalAccessor<Vector2>::get(&x).ceil(); + } break; + case Variant::VECTOR3: { + return VariantInternalAccessor<Vector3>::get(&x).ceil(); + } break; + case Variant::VECTOR4: { + return VariantInternalAccessor<Vector4>::get(&x).ceil(); + } break; + default: { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + } + } + + static inline double ceilf(double x) { return Math::ceil(x); } - static inline double round(double x) { + static inline int ceili(double x) { + return int(Math::ceil(x)); + } + + static inline Variant round(Variant x, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + switch (x.get_type()) { + case Variant::INT: { + return VariantInternalAccessor<int64_t>::get(&x); + } break; + case Variant::FLOAT: { + return Math::round(VariantInternalAccessor<double>::get(&x)); + } break; + case Variant::VECTOR2: { + return VariantInternalAccessor<Vector2>::get(&x).round(); + } break; + case Variant::VECTOR3: { + return VariantInternalAccessor<Vector3>::get(&x).round(); + } break; + case Variant::VECTOR4: { + return VariantInternalAccessor<Vector4>::get(&x).round(); + } break; + default: { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + } + } + + static inline double roundf(double x) { return Math::round(x); } + static inline int roundi(double x) { + return int(Math::round(x)); + } + static inline Variant abs(const Variant &x, Callable::CallError &r_error) { r_error.error = Callable::CallError::CALL_OK; switch (x.get_type()) { @@ -235,7 +322,44 @@ struct VariantUtilityFunctions { return Math::snapped(value, step); } - static inline double lerp(double from, double to, double weight) { + static inline Variant lerp(const Variant &from, const Variant &to, double weight, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + if (from.get_type() != to.get_type()) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + return Variant(); + } + + switch (from.get_type()) { + case Variant::FLOAT: { + return lerpf(VariantInternalAccessor<double>::get(&from), to, weight); + } break; + case Variant::VECTOR2: { + return VariantInternalAccessor<Vector2>::get(&from).lerp(VariantInternalAccessor<Vector2>::get(&to), weight); + } break; + case Variant::VECTOR3: { + return VariantInternalAccessor<Vector3>::get(&from).lerp(VariantInternalAccessor<Vector3>::get(&to), weight); + } break; + case Variant::VECTOR4: { + return VariantInternalAccessor<Vector4>::get(&from).lerp(VariantInternalAccessor<Vector4>::get(&to), weight); + } break; + case Variant::QUATERNION: { + return VariantInternalAccessor<Quaternion>::get(&from).slerp(VariantInternalAccessor<Quaternion>::get(&to), weight); + } break; + case Variant::BASIS: { + return VariantInternalAccessor<Basis>::get(&from).slerp(VariantInternalAccessor<Basis>::get(&to), weight); + } break; + case Variant::COLOR: { + return VariantInternalAccessor<Color>::get(&from).lerp(VariantInternalAccessor<Color>::get(&to), weight); + } break; + default: { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + } + } + + static inline double lerpf(double from, double to, double weight) { return Math::lerp(from, to, weight); } @@ -1252,17 +1376,24 @@ void Variant::_register_variant_utility_functions() { FUNCBINDR(fmod, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(fposmod, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(posmod, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(floor, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(ceil, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(round, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDVR(abs, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDVR(floor, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(floorf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(floori, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDVR(ceil, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(ceilf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(ceili, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDVR(round, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(roundf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(roundi, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDVR(abs, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(absf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(absi, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDVR(sign, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(signf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(signi, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); @@ -1280,7 +1411,8 @@ void Variant::_register_variant_utility_functions() { FUNCBINDR(step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(snapped, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(lerp, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDVR3(lerp, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(lerpf, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(cubic_interpolate, sarray("from", "to", "pre", "post", "weight"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(bezier_interpolate, sarray("start", "control_1", "control_2", "end", "t"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(lerp_angle, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH); @@ -1300,12 +1432,10 @@ void Variant::_register_variant_utility_functions() { FUNCBINDR(wrapf, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDVARARG(max, sarray(), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(maxi, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(maxf, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDVARARG(min, sarray(), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(mini, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(minf, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH); diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 30a2228294..658a13d05b 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -134,15 +134,32 @@ </description> </method> <method name="ceil"> - <return type="float" /> - <argument index="0" name="x" type="float" /> + <return type="Variant" /> + <argument index="0" name="x" type="Variant" /> <description> - Rounds [code]x[/code] upward (towards positive infinity), returning the smallest whole number that is not less than [code]x[/code]. + Rounds [code]x[/code] upward (towards positive infinity), returning the smallest whole number that is not less than [code]x[/code]. Supported types: [int], [float], [Vector2], [Vector3], [Vector4]. [codeblock] var i = ceil(1.45) # i is 2.0 i = ceil(1.001) # i is 2.0 [/codeblock] See also [method floor], [method round], and [method snapped]. + [b]Note:[/b] For better type safety, you can use [method ceilf], [method ceili], [method Vector2.ceil], [method Vector3.ceil] or [method Vector4.ceil] instead. + </description> + </method> + <method name="ceilf"> + <return type="float" /> + <argument index="0" name="x" type="float" /> + <description> + Rounds [code]x[/code] upward (towards positive infinity), returning the smallest whole number that is not less than [code]x[/code]. + A type-safe version of [method ceil], specialzied in floats. + </description> + </method> + <method name="ceili"> + <return type="int" /> + <argument index="0" name="x" type="float" /> + <description> + Rounds [code]x[/code] upward (towards positive infinity), returning the smallest whole number that is not less than [code]x[/code]. + A type-safe version of [method ceil] that returns integer. </description> </method> <method name="clamp"> @@ -300,10 +317,10 @@ </description> </method> <method name="floor"> - <return type="float" /> - <argument index="0" name="x" type="float" /> + <return type="Variant" /> + <argument index="0" name="x" type="Variant" /> <description> - Rounds [code]x[/code] downward (towards negative infinity), returning the largest whole number that is not more than [code]x[/code]. + Rounds [code]x[/code] downward (towards negative infinity), returning the largest whole number that is not more than [code]x[/code]. Supported types: [int], [float], [Vector2], [Vector3], [Vector4]. [codeblock] # a is 2.0 var a = floor(2.99) @@ -311,7 +328,23 @@ a = floor(-2.99) [/codeblock] See also [method ceil], [method round], and [method snapped]. - [b]Note:[/b] This method returns a float. If you need an integer, you can use [code]int(x)[/code] directly. + [b]Note:[/b] For better type safety, you can use [method floorf], [method floori], [method Vector2.floor], [method Vector3.floor] or [method Vector4.floor] instead. + </description> + </method> + <method name="floorf"> + <return type="float" /> + <argument index="0" name="x" type="float" /> + <description> + Rounds [code]x[/code] downward (towards negative infinity), returning the largest whole number that is not more than [code]x[/code]. + A type-safe version of [method floor], specialzied in floats. + </description> + </method> + <method name="floori"> + <return type="int" /> + <argument index="0" name="x" type="float" /> + <description> + Rounds [code]x[/code] downward (towards negative infinity), returning the largest whole number that is not more than [code]x[/code]. + Equivalent of doing [code]int(x)[/code]. </description> </method> <method name="fmod"> @@ -380,7 +413,7 @@ <argument index="1" name="to" type="float" /> <argument index="2" name="weight" type="float" /> <description> - Returns an interpolation or extrapolation factor considering the range specified in [code]from[/code] and [code]to[/code], and the interpolated value specified in [code]weight[/code]. The returned value will be between [code]0.0[/code] and [code]1.0[/code] if [code]weight[/code] is between [code]from[/code] and [code]to[/code] (inclusive). If [code]weight[/code] is located outside this range, then an extrapolation factor will be returned (return value lower than [code]0.0[/code] or greater than [code]1.0[/code]). + Returns an interpolation or extrapolation factor considering the range specified in [code]from[/code] and [code]to[/code], and the interpolated value specified in [code]weight[/code]. The returned value will be between [code]0.0[/code] and [code]1.0[/code] if [code]weight[/code] is between [code]from[/code] and [code]to[/code] (inclusive). If [code]weight[/code] is located outside this range, then an extrapolation factor will be returned (return value lower than [code]0.0[/code] or greater than [code]1.0[/code]). Use [method clamp] on the result of [method inverse_lerp] if this is not desired. [codeblock] # The interpolation ratio in the `lerp()` call below is 0.75. var middle = lerp(20, 30, 0.75) @@ -389,7 +422,7 @@ var ratio = inverse_lerp(20, 30, 27.5) # `ratio` is now 0.75. [/codeblock] - See also [method lerp] which performs the reverse of this operation. + See also [method lerp] which performs the reverse of this operation, and [method range_lerp] to map a continuous series of values to another. </description> </method> <method name="is_equal_approx"> @@ -439,16 +472,18 @@ </description> </method> <method name="lerp"> - <return type="float" /> - <argument index="0" name="from" type="float" /> - <argument index="1" name="to" type="float" /> - <argument index="2" name="weight" type="float" /> + <return type="Variant" /> + <argument index="0" name="from" type="Variant" /> + <argument index="1" name="to" type="Variant" /> + <argument index="2" name="weight" type="Variant" /> <description> - Linearly interpolates between two values by the factor defined in [code]weight[/code]. To perform interpolation, [code]weight[/code] should be between [code]0.0[/code] and [code]1.0[/code] (inclusive). However, values outside this range are allowed and can be used to perform [i]extrapolation[/i]. + Linearly interpolates between two values by the factor defined in [code]weight[/code]. To perform interpolation, [code]weight[/code] should be between [code]0.0[/code] and [code]1.0[/code] (inclusive). However, values outside this range are allowed and can be used to perform [i]extrapolation[/i]. Use [method clamp] on the result of [method lerp] if this is not desired. + Both [code]from[/code] and [code]to[/code] must have matching types. Supported types: [float], [Vector2], [Vector3], [Vector4], [Color], [Quaternion], [Basis]. [codeblock] lerp(0, 4, 0.75) # Returns 3.0 [/codeblock] - See also [method inverse_lerp] which performs the reverse of this operation. To perform eased interpolation with [method lerp], combine it with [method ease] or [method smoothstep]. + See also [method inverse_lerp] which performs the reverse of this operation. To perform eased interpolation with [method lerp], combine it with [method ease] or [method smoothstep]. See also [method range_lerp] to map a continuous series of values to another. + [b]Note:[/b] For better type safety, you can use [method lerpf], [method Vector2.lerp], [method Vector3.lerp], [method Vector4.lerp], [method Color.lerp], [method Quaternion.slerp] or [method Basis.slerp] instead. </description> </method> <method name="lerp_angle"> @@ -471,6 +506,19 @@ [b]Note:[/b] This method lerps through the shortest path between [code]from[/code] and [code]to[/code]. However, when these two angles are approximately [code]PI + k * TAU[/code] apart for any integer [code]k[/code], it's not obvious which way they lerp due to floating-point precision errors. For example, [code]lerp_angle(0, PI, weight)[/code] lerps counter-clockwise, while [code]lerp_angle(0, PI + 5 * TAU, weight)[/code] lerps clockwise. </description> </method> + <method name="lerpf"> + <return type="float" /> + <argument index="0" name="from" type="float" /> + <argument index="1" name="to" type="float" /> + <argument index="2" name="weight" type="float" /> + <description> + Linearly interpolates between two values by the factor defined in [code]weight[/code]. To perform interpolation, [code]weight[/code] should be between [code]0.0[/code] and [code]1.0[/code] (inclusive). However, values outside this range are allowed and can be used to perform [i]extrapolation[/i]. + [codeblock] + lerp(0, 4, 0.75) # Returns 3.0 + [/codeblock] + See also [method inverse_lerp] which performs the reverse of this operation. To perform eased interpolation with [method lerp], combine it with [method ease] or [method smoothstep]. + </description> + </method> <method name="linear2db"> <return type="float" /> <argument index="0" name="lin" type="float" /> @@ -807,10 +855,11 @@ <argument index="3" name="ostart" type="float" /> <argument index="4" name="ostop" type="float" /> <description> - Maps a [code]value[/code] from range [code][istart, istop][/code] to [code][ostart, ostop][/code]. + Maps a [code]value[/code] from range [code][istart, istop][/code] to [code][ostart, ostop][/code]. See also [method lerp] and [method inverse_lerp]. If [code]value[/code] is outside [code][istart, istop][/code], then the resulting value will also be outside [code][ostart, ostop][/code]. Use [method clamp] on the result of [method range_lerp] if this is not desired. [codeblock] range_lerp(75, 0, 100, -1, 1) # Returns 0.5 [/codeblock] + For complex use cases where you need multiple ranges, consider using [Curve] or [Gradient] instead. </description> </method> <method name="rid_allocate_id"> @@ -827,14 +876,33 @@ </description> </method> <method name="round"> - <return type="float" /> - <argument index="0" name="x" type="float" /> + <return type="Variant" /> + <argument index="0" name="x" type="Variant" /> <description> - Rounds [code]x[/code] to the nearest whole number, with halfway cases rounded away from zero. + Rounds [code]x[/code] to the nearest whole number, with halfway cases rounded away from zero. Supported types: [int], [float], [Vector2], [Vector3], [Vector4]. [codeblock] + round(2.4) # Returns 2 + round(2.5) # Returns 3 round(2.6) # Returns 3 [/codeblock] See also [method floor], [method ceil], and [method snapped]. + [b]Note:[/b] For better type safety, you can use [method roundf], [method roundi], [method Vector2.round], [method Vector3.round] or [method Vector4.round] instead. + </description> + </method> + <method name="roundf"> + <return type="float" /> + <argument index="0" name="x" type="float" /> + <description> + Rounds [code]x[/code] to the nearest whole number, with halfway cases rounded away from zero. + A type-safe version of [method round], specialzied in floats. + </description> + </method> + <method name="roundi"> + <return type="int" /> + <argument index="0" name="x" type="float" /> + <description> + Rounds [code]x[/code] to the nearest whole number, with halfway cases rounded away from zero. + A type-safe version of [method round] that returns integer. </description> </method> <method name="seed"> @@ -1209,6 +1277,7 @@ The [ResourceSaver] singleton. </member> <member name="ResourceUID" type="ResourceUID" setter="" getter=""> + The [ResourceUID] singleton. </member> <member name="TextServerManager" type="TextServerManager" setter="" getter=""> The [TextServerManager] singleton. @@ -2728,24 +2797,6 @@ <constant name="METHOD_FLAGS_DEFAULT" value="1" enum="MethodFlags"> Default method flags. </constant> - <constant name="RPC_MODE_DISABLED" value="0" enum="RPCMode"> - Used with [method Node.rpc_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods. - </constant> - <constant name="RPC_MODE_ANY_PEER" value="1" enum="RPCMode"> - Used with [method Node.rpc_config] to set a method to be callable remotely by any peer. Analogous to the [code]@rpc(any)[/code] annotation. Calls are accepted from all remote peers, no matter if they are node's authority or not. - </constant> - <constant name="RPC_MODE_AUTHORITY" value="2" enum="RPCMode"> - Used with [method Node.rpc_config] to set a method to be callable remotely only by the current multiplayer authority (which is the server by default). Analogous to the [code]@rpc(authority)[/code] annotation. See [method Node.set_multiplayer_authority]. - </constant> - <constant name="TRANSFER_MODE_UNRELIABLE" value="0" enum="TransferMode"> - Packets are not acknowledged, no resend attempts are made for lost packets. Packets may arrive in any order. Potentially faster than [constant TRANSFER_MODE_UNRELIABLE_ORDERED]. Use for non-critical data, and always consider whether the order matters. - </constant> - <constant name="TRANSFER_MODE_UNRELIABLE_ORDERED" value="1" enum="TransferMode"> - Packets are not acknowledged, no resend attempts are made for lost packets. Packets are received in the order they were sent in. Potentially faster than [constant TRANSFER_MODE_RELIABLE]. Use for non-critical data or data that would be outdated if received late due to resend attempt(s) anyway, for example movement and positional data. - </constant> - <constant name="TRANSFER_MODE_RELIABLE" value="2" enum="TransferMode"> - Packets must be received and resend attempts should be made until the packets are acknowledged. Packets must be received in the order they were sent in. Most reliable transfer mode, but potentially the slowest due to the overhead. Use for critical data that must be transmitted and arrive in order, for example an ability being triggered or a chat message. Consider carefully if the information really is critical, and use sparingly. - </constant> <constant name="TYPE_NIL" value="0" enum="Variant.Type"> Variable is [code]null[/code]. </constant> diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml index a92b237624..f40f11944d 100644 --- a/doc/classes/Animation.xml +++ b/doc/classes/Animation.xml @@ -391,13 +391,13 @@ </description> </method> <method name="track_insert_key"> - <return type="void" /> + <return type="int" /> <argument index="0" name="track_idx" type="int" /> <argument index="1" name="time" type="float" /> <argument index="2" name="key" type="Variant" /> <argument index="3" name="transition" type="float" default="1" /> <description> - Insert a generic key in a given track. + Inserts a generic key in a given track. Returns the key index. </description> </method> <method name="track_is_compressed" qualifiers="const"> diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml index 653607610d..d3c8bdac3a 100644 --- a/doc/classes/AnimationPlayer.xml +++ b/doc/classes/AnimationPlayer.xml @@ -1,11 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AnimationPlayer" inherits="Node" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - Container and player of [Animation] resources. + Player of [Animation] resources. </brief_description> <description> - An animation player is used for general-purpose playback of [Animation] resources. It contains a dictionary of animations (referenced by name) and custom blend times between their transitions. Additionally, animations can be played and blended in different channels. - [AnimationPlayer] is more suited than [Tween] for animations where you know the final values in advance. For example, fading a screen in and out is more easily done with an [AnimationPlayer] node thanks to the animation tools provided by the editor. That particular example can also be implemented with a [Tween] node, but it requires doing everything by code. + An animation player is used for general-purpose playback of [Animation] resources. It contains a dictionary of [AnimationLibrary] resources and custom blend times between animation transitions. + Some methods and properties use a single key to refence an animation directly. These keys are formatted as the key for the library, followed by a forward slash, then the key for the animation whithin the library, for example [code]"movement/run"[/code]. If the library's key is an empty string (known as the default library), the forward slash is omitted, being the same key used by the library. + [AnimationPlayer] is more suited than [Tween] for animations where you know the final values in advance. For example, fading a screen in and out is more easily done with an [AnimationPlayer] node thanks to the animation tools provided by the editor. That particular example can also be implemented with a [Tween], but it requires doing everything by code. Updating the target properties of animations occurs at process time. </description> <tutorials> @@ -19,6 +20,7 @@ <argument index="0" name="name" type="StringName" /> <argument index="1" name="library" type="AnimationLibrary" /> <description> + Adds [code]library[/code] to the animation player, under the key [code]name[/code]. </description> </method> <method name="advance"> @@ -32,7 +34,7 @@ <return type="StringName" /> <argument index="0" name="anim_from" type="StringName" /> <description> - Returns the name of the next animation in the queue. + Returns the key of the animation which is queued to play after the [code]anim_from[/code] animation. </description> </method> <method name="animation_set_next"> @@ -59,13 +61,14 @@ <return type="StringName" /> <argument index="0" name="animation" type="Animation" /> <description> - Returns the name of [code]animation[/code] or an empty string if not found. + Returns the key of [code]animation[/code] or an empty [StringName] if not found. </description> </method> <method name="find_animation_library" qualifiers="const"> <return type="StringName" /> <argument index="0" name="animation" type="Animation" /> <description> + Returns the key for the [AnimationLibrary] that contains [code]animation[/code] or an empty [StringName] if not found. </description> </method> <method name="get_animation" qualifiers="const"> @@ -79,17 +82,19 @@ <return type="AnimationLibrary" /> <argument index="0" name="name" type="StringName" /> <description> + Returns the first [AnimationLibrary] with key [code]name[/code] or [code]null[/code] if not found. </description> </method> <method name="get_animation_library_list" qualifiers="const"> <return type="StringName[]" /> <description> + Returns the list of stored library keys. </description> </method> <method name="get_animation_list" qualifiers="const"> <return type="PackedStringArray" /> <description> - Returns the list of stored animation names. + Returns the list of stored animation keys. </description> </method> <method name="get_blend_time" qualifiers="const"> @@ -97,7 +102,7 @@ <argument index="0" name="anim_from" type="StringName" /> <argument index="1" name="anim_to" type="StringName" /> <description> - Gets the blend time (in seconds) between two animations, referenced by their names. + Gets the blend time (in seconds) between two animations, referenced by their keys. </description> </method> <method name="get_playing_speed" qualifiers="const"> @@ -109,7 +114,7 @@ <method name="get_queue"> <return type="PackedStringArray" /> <description> - Returns a list of the animation names that are currently queued to play. + Returns a list of the animation keys that are currently queued to play. </description> </method> <method name="has_animation" qualifiers="const"> @@ -123,6 +128,7 @@ <return type="bool" /> <argument index="0" name="name" type="StringName" /> <description> + Returns [code]true[/code] if the [AnimationPlayer] stores an [AnimationLibrary] with key [code]name[/code]. </description> </method> <method name="is_playing" qualifiers="const"> @@ -164,6 +170,7 @@ <return type="void" /> <argument index="0" name="name" type="StringName" /> <description> + Removes the [AnimationLibrary] assosiated with the key [code]name[/code]. </description> </method> <method name="rename_animation_library"> @@ -171,6 +178,7 @@ <argument index="0" name="name" type="StringName" /> <argument index="1" name="newname" type="StringName" /> <description> + Moves the [AnimationLibrary] associated with the key [code]name[/code] to the key [code]newname[/code]. </description> </method> <method name="seek"> @@ -188,7 +196,7 @@ <argument index="1" name="anim_to" type="StringName" /> <argument index="2" name="sec" type="float" /> <description> - Specifies a blend time (in seconds) between two animations, referenced by their names. + Specifies a blend time (in seconds) between two animations, referenced by their keys. </description> </method> <method name="stop"> @@ -202,17 +210,17 @@ </methods> <members> <member name="assigned_animation" type="String" setter="set_assigned_animation" getter="get_assigned_animation"> - If playing, the current animation; otherwise, the animation last played. When set, would change the animation, but would not play it unless currently playing. See also [member current_animation]. + If playing, the the current animation's key, otherwise, the animation last played. When set, this changes the animation, but will not play it unless already playing. See also [member current_animation]. </member> <member name="autoplay" type="String" setter="set_autoplay" getter="get_autoplay" default=""""> - The name of the animation to play when the scene loads. + The key of the animation to play when the scene loads. </member> <member name="current_animation" type="String" setter="set_current_animation" getter="get_current_animation" default=""""> - The name of the currently playing animation. If no animation is playing, the property's value is an empty string. Changing this value does not restart the animation. See [method play] for more information on playing animations. + The key of the currently playing animation. If no animation is playing, the property's value is an empty string. Changing this value does not restart the animation. See [method play] for more information on playing animations. [b]Note:[/b] while this property appears in the inspector, it's not meant to be edited, and it's not saved in the scene. This property is mainly used to get the currently playing animation, and internally for animation playback tracks. For more information, see [Animation]. </member> <member name="current_animation_length" type="float" setter="" getter="get_current_animation_length"> - The length (in seconds) of the currently being played animation. + The length (in seconds) of the currently playing animation. </member> <member name="current_animation_position" type="float" setter="" getter="get_current_animation_position"> The position (in seconds) of the currently playing animation. @@ -220,6 +228,10 @@ <member name="method_call_mode" type="int" setter="set_method_call_mode" getter="get_method_call_mode" enum="AnimationPlayer.AnimationMethodCallMode" default="0"> The call mode to use for Call Method tracks. </member> + <member name="movie_quit_on_finish" type="bool" setter="set_movie_quit_on_finish_enabled" getter="is_movie_quit_on_finish_enabled" default="false"> + If [code]true[/code] and the engine is running in Movie Maker mode (see [MovieWriter]), exits the engine with [method SceneTree.quit] as soon as an animation is done playing in this [AnimationPlayer]. A message is printed when the engine quits for this reason. + [b]Note:[/b] This obeys the same logic as the [signal animation_finished] signal, so it will not quit the engine if the animation is set to be looping. + </member> <member name="playback_active" type="bool" setter="set_active" getter="is_active"> If [code]true[/code], updates animations in response to process-related notifications. </member> @@ -233,8 +245,8 @@ The speed scaling ratio. For instance, if this value is 1, then the animation plays at normal speed. If it's 0.5, then it plays at half speed. If it's 2, then it plays at double speed. </member> <member name="reset_on_save" type="bool" setter="set_reset_on_save_enabled" getter="is_reset_on_save_enabled" default="true"> - This is used by the editor. If set to [code]true[/code], the scene will be saved with the effects of the reset animation applied (as if it had been seeked to time 0), then reverted after saving. - In other words, the saved scene file will contain the "default pose", as defined by the reset animation, if any, with the editor keeping the values that the nodes had before saving. + This is used by the editor. If set to [code]true[/code], the scene will be saved with the effects of the reset animation (the animation with the key [code]"RESET"[/code]) applied as if it had been seeked to time 0, with the editor keeping the values that the scene had before saving. + This makes it more convenient to preview and edit animations in the editor, as changes to the scene will not be saved as long as they are set in the reset animation. </member> <member name="root_node" type="NodePath" setter="set_root" getter="get_root" default="NodePath("..")"> The node from which node path references will travel. @@ -245,14 +257,15 @@ <argument index="0" name="old_name" type="StringName" /> <argument index="1" name="new_name" type="StringName" /> <description> - Emitted when a queued animation plays after the previous animation was finished. See [method queue]. - [b]Note:[/b] The signal is not emitted when the animation is changed via [method play] or from [AnimationTree]. + Emitted when a queued animation plays after the previous animation finished. See [method queue]. + [b]Note:[/b] The signal is not emitted when the animation is changed via [method play] or by an [AnimationTree]. </description> </signal> <signal name="animation_finished"> <argument index="0" name="anim_name" type="StringName" /> <description> Notifies when an animation finished playing. + [b]Note:[/b] This signal is not emitted if an animation is looping. </description> </signal> <signal name="animation_started"> diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index 0f2dd6587a..f5c799d4de 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -67,7 +67,7 @@ <description> Creates a new surface. Surfaces are created to be rendered using a [code]primitive[/code], which may be any of the types defined in [enum Mesh.PrimitiveType]. (As a note, when using indices, it is recommended to only use points, lines, or triangles.) [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface. - The [code]arrays[/code] argument is an array of arrays. See [enum Mesh.ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array or be empty, except for [constant Mesh.ARRAY_INDEX] if it is used. + The [code]arrays[/code] argument is an array of arrays. See [enum Mesh.ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array (or be an exact multiple of the vertex array's length, when multiple elements of a sub-array correspond to a single vertex) or be empty, except for [constant Mesh.ARRAY_INDEX] if it is used. </description> </method> <method name="clear_blend_shapes"> diff --git a/doc/classes/AudioEffectRecord.xml b/doc/classes/AudioEffectRecord.xml index 9728011bb2..32a6aea340 100644 --- a/doc/classes/AudioEffectRecord.xml +++ b/doc/classes/AudioEffectRecord.xml @@ -14,7 +14,7 @@ </tutorials> <methods> <method name="get_recording" qualifiers="const"> - <return type="AudioStreamSample" /> + <return type="AudioStreamWAV" /> <description> Returns the recorded sample. </description> @@ -34,8 +34,8 @@ </method> </methods> <members> - <member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamSample.Format" default="1"> - Specifies the format in which the sample will be recorded. See [enum AudioStreamSample.Format] for available formats. + <member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamWAV.Format" default="1"> + Specifies the format in which the sample will be recorded. See [enum AudioStreamWAV.Format] for available formats. </member> </members> </class> diff --git a/doc/classes/AudioStream.xml b/doc/classes/AudioStream.xml index 68f64505d0..7645cafe86 100644 --- a/doc/classes/AudioStream.xml +++ b/doc/classes/AudioStream.xml @@ -4,7 +4,7 @@ Base class for audio streams. </brief_description> <description> - Base class for audio streams. Audio streams are used for sound effects and music playback, and support WAV (via [AudioStreamSample]) and OGG (via [AudioStreamOGGVorbis]) file formats. + Base class for audio streams. Audio streams are used for sound effects and music playback, and support WAV (via [AudioStreamWAV]) and Ogg (via [AudioStreamOggVorbis]) file formats. </description> <tutorials> <link title="Audio streams">$DOCS_URL/tutorials/audio/audio_streams.html</link> diff --git a/doc/classes/AudioStreamPlayback.xml b/doc/classes/AudioStreamPlayback.xml index d3d97e0c8a..f1a1c18c1c 100644 --- a/doc/classes/AudioStreamPlayback.xml +++ b/doc/classes/AudioStreamPlayback.xml @@ -4,7 +4,7 @@ Meta class for playing back audio. </brief_description> <description> - Can play, loop, pause a scroll through audio. See [AudioStream] and [AudioStreamOGGVorbis] for usage. + Can play, loop, pause a scroll through audio. See [AudioStream] and [AudioStreamOggVorbis] for usage. </description> <tutorials> <link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link> diff --git a/doc/classes/AudioStreamSample.xml b/doc/classes/AudioStreamWAV.xml index 62f27ce876..17595aec2f 100644 --- a/doc/classes/AudioStreamSample.xml +++ b/doc/classes/AudioStreamWAV.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamSample" inherits="AudioStream" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="AudioStreamWAV" inherits="AudioStream" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> Stores audio data loaded from WAV files. </brief_description> <description> - AudioStreamSample stores sound samples loaded from WAV files. To play the stored sound, use an [AudioStreamPlayer] (for non-positional audio) or [AudioStreamPlayer2D]/[AudioStreamPlayer3D] (for positional audio). The sound can be looped. + AudioStreamWAV stores sound samples loaded from WAV files. To play the stored sound, use an [AudioStreamPlayer] (for non-positional audio) or [AudioStreamPlayer2D]/[AudioStreamPlayer3D] (for positional audio). The sound can be looped. This class can also be used to store dynamically-generated PCM audio data. See also [AudioStreamGenerator] for procedural audio generation. </description> <tutorials> @@ -14,7 +14,7 @@ <return type="int" enum="Error" /> <argument index="0" name="path" type="String" /> <description> - Saves the AudioStreamSample as a WAV file to [code]path[/code]. Samples with IMA ADPCM format can't be saved. + Saves the AudioStreamWAV as a WAV file to [code]path[/code]. Samples with IMA ADPCM format can't be saved. [b]Note:[/b] A [code].wav[/code] extension is automatically appended to [code]path[/code] if it is missing. </description> </method> @@ -24,7 +24,7 @@ Contains the audio data in bytes. [b]Note:[/b] This property expects signed PCM8 data. To convert unsigned PCM8 to signed PCM8, subtract 128 from each byte. </member> - <member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamSample.Format" default="0"> + <member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamWAV.Format" default="0"> Audio format. See [enum Format] constants for values. </member> <member name="loop_begin" type="int" setter="set_loop_begin" getter="get_loop_begin" default="0"> @@ -33,7 +33,7 @@ <member name="loop_end" type="int" setter="set_loop_end" getter="get_loop_end" default="0"> The loop end point (in number of samples, relative to the beginning of the sample). This information will be imported automatically from the WAV file if present. </member> - <member name="loop_mode" type="int" setter="set_loop_mode" getter="get_loop_mode" enum="AudioStreamSample.LoopMode" default="0"> + <member name="loop_mode" type="int" setter="set_loop_mode" getter="get_loop_mode" enum="AudioStreamWAV.LoopMode" default="0"> The loop mode. This information will be imported automatically from the WAV file if present. See [enum LoopMode] constants for values. </member> <member name="mix_rate" type="int" setter="set_mix_rate" getter="get_mix_rate" default="44100"> diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index b3cea7217e..d0290ff5fd 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -218,30 +218,44 @@ Grows object vertices in the direction of their normals. </member> <member name="heightmap_deep_parallax" type="bool" setter="set_heightmap_deep_parallax" getter="is_heightmap_deep_parallax_enabled" default="false"> + If [code]true[/code], uses parallax occlusion mapping to represent depth in the material instead of simple offset mapping (see [member heightmap_enabled]). This results in a more convincing depth effect, but is much more expensive on the GPU. Only enable this on materials where it makes a significant visual difference. </member> <member name="heightmap_enabled" type="bool" setter="set_feature" getter="get_feature" default="false"> - If [code]true[/code], height mapping is enabled (also called "parallax mapping" or "depth mapping"). See also [member normal_enabled]. + If [code]true[/code], height mapping is enabled (also called "parallax mapping" or "depth mapping"). See also [member normal_enabled]. Height mapping is a demanding feature on the GPU, so it should only be used on materials where it makes a significant visual difference. [b]Note:[/b] Height mapping is not supported if triplanar mapping is used on the same material. The value of [member heightmap_enabled] will be ignored if [member uv1_triplanar] is enabled. </member> <member name="heightmap_flip_binormal" type="bool" setter="set_heightmap_deep_parallax_flip_binormal" getter="get_heightmap_deep_parallax_flip_binormal" default="false"> + If [code]true[/code], flips the mesh's binormal vectors when interpreting the height map. If the heightmap effect looks strange when the camera moves (even with a reasonable [member heightmap_scale]), try setting this to [code]true[/code]. </member> <member name="heightmap_flip_tangent" type="bool" setter="set_heightmap_deep_parallax_flip_tangent" getter="get_heightmap_deep_parallax_flip_tangent" default="false"> + If [code]true[/code], flips the mesh's tangent vectors when interpreting the height map. If the heightmap effect looks strange when the camera moves (even with a reasonable [member heightmap_scale]), try setting this to [code]true[/code]. </member> <member name="heightmap_flip_texture" type="bool" setter="set_flag" getter="get_flag" default="false"> + If [code]true[/code], interprets the height map texture as a depth map, with brighter values appearing to be "lower" in altitude compared to darker values. + This can be enabled for compatibility with some materials authored for Godot 3.x. This is not necessary if the Invert import option was used to invert the depth map in Godot 3.x, in which case [member heightmap_flip_texture] should remain [code]false[/code]. </member> <member name="heightmap_max_layers" type="int" setter="set_heightmap_deep_parallax_max_layers" getter="get_heightmap_deep_parallax_max_layers"> + The number of layers to use for parallax occlusion mapping when the camera is up close to the material. Higher values result in a more convincing depth effect, especially in materials that have steep height changes. Higher values have a significant cost on the GPU, so it should only be increased on materials where it makes a significant visual difference. + [b]Note:[/b] Only effective if [member heightmap_deep_parallax] is [code]true[/code]. </member> <member name="heightmap_min_layers" type="int" setter="set_heightmap_deep_parallax_min_layers" getter="get_heightmap_deep_parallax_min_layers"> + The number of layers to use for parallax occlusion mapping when the camera is far away from the material. Higher values result in a more convincing depth effect, especially in materials that have steep height changes. Higher values have a significant cost on the GPU, so it should only be increased on materials where it makes a significant visual difference. + [b]Note:[/b] Only effective if [member heightmap_deep_parallax] is [code]true[/code]. </member> - <member name="heightmap_scale" type="float" setter="set_heightmap_scale" getter="get_heightmap_scale" default="0.05"> + <member name="heightmap_scale" type="float" setter="set_heightmap_scale" getter="get_heightmap_scale" default="5.0"> + The heightmap scale to use for the parallax effect (see [member heightmap_enabled]). The default value is tuned so that the highest point (value = 255) appears to be 5 cm higher than the lowest point (value = 0). Higher values result in a deeper appearance, but may result in artifacts appearing when looking at the material from oblique angles, especially when the camera moves. Negative values can be used to invert the parallax effect, but this is different from inverting the texture using [member heightmap_flip_texture] as the material will also appear to be "closer" to the camera. In most cases, [member heightmap_scale] should be kept to a positive value. + [b]Note:[/b] If the height map effect looks strange regardless of this value, try adjusting [member heightmap_flip_binormal] and [member heightmap_flip_tangent]. See also [member heightmap_texture] for recommendations on authoring heightmap textures, as the way the heightmap texture is authored affects how [member heightmap_scale] behaves. </member> <member name="heightmap_texture" type="Texture2D" setter="set_texture" getter="get_texture"> + The texture to use as a height map. See also [member heightmap_enabled]. + For best results, the texture should be normalized (with [member heightmap_scale] reduced to compensate). In [url=https://gimp.org]GIMP[/url], this can be done using [b]Colors > Auto > Equalize[/b]. If the texture only uses a small part of its available range, the parallax effect may look strange, especially when the camera moves. + [b]Note:[/b] To reduce memory usage and improve loading times, you may be able to use a lower-resolution heightmap texture as most heightmaps are only comprised of low-frequency data. </member> <member name="metallic" type="float" setter="set_metallic" getter="get_metallic" default="0.0"> A high value makes the material appear more like a metal. Non-metals use their albedo as the diffuse color and add diffuse to the specular reflection. With non-metals, the reflection appears on top of the albedo color. Metals use their albedo as a multiplier to the specular reflection and set the diffuse color to black resulting in a tinted reflection. Materials work better when fully metal or fully non-metal, values between [code]0[/code] and [code]1[/code] should only be used for blending between metal and non-metal sections. To alter the amount of reflection use [member roughness]. </member> <member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" default="0.5"> - Sets the size of the specular lobe. The specular lobe is the bright spot that is reflected from light sources. + Adjusts the strength of specular reflections. Specular reflections are composed of scene reflections and the specular lobe which is the bright spot that is reflected from light sources. When set to [code]0.0[/code], no specular reflections will be visible. This differs from the [constant SPECULAR_DISABLED] [enum SpecularMode] as [constant SPECULAR_DISABLED] only applies to the specular lobe from the light source. [b]Note:[/b] Unlike [member metallic], this is not energy-conserving, so it should be left at [code]0.5[/code] in most cases. See also [member roughness]. </member> <member name="metallic_texture" type="Texture2D" setter="set_texture" getter="get_texture"> diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml index dacdca1cee..b0282e4107 100644 --- a/doc/classes/CPUParticles2D.xml +++ b/doc/classes/CPUParticles2D.xml @@ -192,8 +192,8 @@ </member> <member name="linear_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0"> </member> - <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> - If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. + <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="false"> + If [code]true[/code], particles use the parent node's coordinate space (known as local coordinates). This will cause particles to move and rotate along the [CPUParticles2D] node (and its parents) when it is moved or rotated. If [code]false[/code], particles use global coordinates; they will not move or rotate along the [CPUParticles2D] node (and its parents) when it is moved or rotated. </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false"> If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end. diff --git a/doc/classes/CPUParticles3D.xml b/doc/classes/CPUParticles3D.xml index f2a0040ed4..d8faf8e91d 100644 --- a/doc/classes/CPUParticles3D.xml +++ b/doc/classes/CPUParticles3D.xml @@ -224,8 +224,8 @@ <member name="linear_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0"> Minimum linear acceleration. </member> - <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> - If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. + <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="false"> + If [code]true[/code], particles use the parent node's coordinate space (known as local coordinates). This will cause particles to move and rotate along the [CPUParticles3D] node (and its parents) when it is moved or rotated. If [code]false[/code], particles use global coordinates; they will not move or rotate along the [CPUParticles3D] node (and its parents) when it is moved or rotated. </member> <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh"> The [Mesh] used for each particle. If [code]null[/code], particles will be spheres. diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml index 3aedbbd1e6..643351efc0 100644 --- a/doc/classes/Camera3D.xml +++ b/doc/classes/Camera3D.xml @@ -113,7 +113,7 @@ <argument index="2" name="z_near" type="float" /> <argument index="3" name="z_far" type="float" /> <description> - Sets the camera projection to frustum mode (see [constant PROJECTION_FRUSTUM]), by specifying a [code]size[/code], an [code]offset[/code], and the [code]z_near[/code] and [code]z_far[/code] clip planes in world space units. + Sets the camera projection to frustum mode (see [constant PROJECTION_FRUSTUM]), by specifying a [code]size[/code], an [code]offset[/code], and the [code]z_near[/code] and [code]z_far[/code] clip planes in world space units. See also [member frustum_offset]. </description> </method> <method name="set_orthogonal"> @@ -144,7 +144,7 @@ # This code block is part of a script that inherits from Node3D. # `control` is a reference to a node inheriting from Control. control.visible = not get_viewport().get_camera_3d().is_position_behind(global_transform.origin) - control.rect_position = get_viewport().get_camera_3d().unproject_position(global_transform.origin) + control.position = get_viewport().get_camera_3d().unproject_position(global_transform.origin) [/codeblock] </description> </method> @@ -179,6 +179,7 @@ </member> <member name="frustum_offset" type="Vector2" setter="set_frustum_offset" getter="get_frustum_offset" default="Vector2(0, 0)"> The camera's frustum offset. This can be changed from the default to create "tilted frustum" effects such as [url=https://zdoom.org/wiki/Y-shearing]Y-shearing[/url]. + [b]Note:[/b] Only effective if [member projection] is [constant PROJECTION_FRUSTUM]. </member> <member name="h_offset" type="float" setter="set_h_offset" getter="get_h_offset" default="0.0"> The horizontal (X) offset of the camera viewport. diff --git a/doc/classes/CharacterBody3D.xml b/doc/classes/CharacterBody3D.xml index 6c5cd62fe1..795bd7a429 100644 --- a/doc/classes/CharacterBody3D.xml +++ b/doc/classes/CharacterBody3D.xml @@ -159,10 +159,10 @@ Sets the behavior to apply when you leave a moving platform. By default, to be physically accurate, when you leave the last platform velocity is applied. See [enum MovingPlatformApplyVelocityOnLeave] constants for available behavior. </member> <member name="moving_platform_floor_layers" type="int" setter="set_moving_platform_floor_layers" getter="get_moving_platform_floor_layers" default="4294967295"> - Collision layers that will be included for detecting floor bodies that will act as moving platforms to be followed by the [CharacterBody2D]. By default, all floor bodies are detected and propagate their velocity. + Collision layers that will be included for detecting floor bodies that will act as moving platforms to be followed by the [CharacterBody3D]. By default, all floor bodies are detected and propagate their velocity. </member> <member name="moving_platform_wall_layers" type="int" setter="set_moving_platform_wall_layers" getter="get_moving_platform_wall_layers" default="0"> - Collision layers that will be included for detecting wall bodies that will act as moving platforms to be followed by the [CharacterBody2D]. By default, all wall bodies are ignored. + Collision layers that will be included for detecting wall bodies that will act as moving platforms to be followed by the [CharacterBody3D]. By default, all wall bodies are ignored. </member> <member name="slide_on_ceiling" type="bool" setter="set_slide_on_ceiling_enabled" getter="is_slide_on_ceiling_enabled" default="true"> If [code]true[/code], during a jump against the ceiling, the body will slide, if [code]false[/code] it will be stopped and will fall vertically. diff --git a/doc/classes/CollisionObject2D.xml b/doc/classes/CollisionObject2D.xml index 5d025985cc..95d99855f6 100644 --- a/doc/classes/CollisionObject2D.xml +++ b/doc/classes/CollisionObject2D.xml @@ -16,7 +16,8 @@ <argument index="1" name="event" type="InputEvent" /> <argument index="2" name="shape_idx" type="int" /> <description> - Accepts unhandled [InputEvent]s. Requires [member input_pickable] to be [code]true[/code]. [code]shape_idx[/code] is the child index of the clicked [Shape2D]. Connect to the [code]input_event[/code] signal to easily pick up these events. + Accepts unhandled [InputEvent]s. [code]shape_idx[/code] is the child index of the clicked [Shape2D]. Connect to the [code]input_event[/code] signal to easily pick up these events. + [b]Note:[/b] [method _input_event] requires [member input_pickable] to be [code]true[/code] and at least one [member collision_layer] bit to be set. </description> </method> <method name="create_shape_owner"> @@ -218,17 +219,19 @@ <argument index="1" name="event" type="InputEvent" /> <argument index="2" name="shape_idx" type="int" /> <description> - Emitted when an input event occurs. Requires [member input_pickable] to be [code]true[/code] and at least one [code]collision_layer[/code] bit to be set. See [method _input_event] for details. + Emitted when an input event occurs. Requires [member input_pickable] to be [code]true[/code] and at least one [member collision_layer] bit to be set. See [method _input_event] for details. </description> </signal> <signal name="mouse_entered"> <description> Emitted when the mouse pointer enters any of this object's shapes. Requires [member input_pickable] to be [code]true[/code] and at least one [member collision_layer] bit to be set. Note that moving between different shapes within a single [CollisionObject2D] won't cause this signal to be emitted. + [b]Note:[/b] Due to the lack of continuous collision detection, this signal may not be emitted in the expected order if the mouse moves fast enough and the [CollisionObject2D]'s area is small. This signal may also not be emitted if another [CollisionObject2D] is overlapping the [CollisionObject2D] in question. </description> </signal> <signal name="mouse_exited"> <description> Emitted when the mouse pointer exits all this object's shapes. Requires [member input_pickable] to be [code]true[/code] and at least one [member collision_layer] bit to be set. Note that moving between different shapes within a single [CollisionObject2D] won't cause this signal to be emitted. + [b]Note:[/b] Due to the lack of continuous collision detection, this signal may not be emitted in the expected order if the mouse moves fast enough and the [CollisionObject2D]'s area is small. This signal may also not be emitted if another [CollisionObject2D] is overlapping the [CollisionObject2D] in question. </description> </signal> <signal name="mouse_shape_entered"> diff --git a/doc/classes/CollisionObject3D.xml b/doc/classes/CollisionObject3D.xml index 2aac5528f4..7284a7e341 100644 --- a/doc/classes/CollisionObject3D.xml +++ b/doc/classes/CollisionObject3D.xml @@ -18,6 +18,7 @@ <argument index="4" name="shape_idx" type="int" /> <description> Receives unhandled [InputEvent]s. [code]position[/code] is the location in world space of the mouse pointer on the surface of the shape with index [code]shape_idx[/code] and [code]normal[/code] is the normal vector of the surface at that point. Connect to the [signal input_event] signal to easily pick up these events. + [b]Note:[/b] [method _input_event] requires [member input_ray_pickable] to be [code]true[/code] and at least one [member collision_layer] bit to be set. </description> </method> <method name="create_shape_owner"> @@ -199,12 +200,14 @@ </signal> <signal name="mouse_entered"> <description> - Emitted when the mouse pointer enters any of this object's shapes. + Emitted when the mouse pointer enters any of this object's shapes. Requires [member input_ray_pickable] to be [code]true[/code] and at least one [member collision_layer] bit to be set. + [b]Note:[/b] Due to the lack of continuous collision detection, this signal may not be emitted in the expected order if the mouse moves fast enough and the [CollisionObject2D]'s area is small. This signal may also not be emitted if another [CollisionObject2D] is overlapping the [CollisionObject2D] in question. </description> </signal> <signal name="mouse_exited"> <description> - Emitted when the mouse pointer exits all this object's shapes. + Emitted when the mouse pointer exits all this object's shapes. Requires [member input_ray_pickable] to be [code]true[/code] and at least one [member collision_layer] bit to be set. + [b]Note:[/b] Due to the lack of continuous collision detection, this signal may not be emitted in the expected order if the mouse moves fast enough and the [CollisionObject2D]'s area is small. This signal may also not be emitted if another [CollisionObject2D] is overlapping the [CollisionObject2D] in question. </description> </signal> </signals> diff --git a/doc/classes/Curve.xml b/doc/classes/Curve.xml index 383d33532b..179b0344c2 100644 --- a/doc/classes/Curve.xml +++ b/doc/classes/Curve.xml @@ -5,6 +5,7 @@ </brief_description> <description> A curve that can be saved and re-used for other objects. By default, it ranges between [code]0[/code] and [code]1[/code] on the Y axis and positions points relative to the [code]0.5[/code] Y position. + See also [Gradient] which is designed for color interpolation. See also [Curve2D] and [Curve3D]. </description> <tutorials> </tutorials> diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml index 861b4b480c..3322ab4c66 100644 --- a/doc/classes/Decal.xml +++ b/doc/classes/Decal.xml @@ -58,34 +58,35 @@ </methods> <members> <member name="albedo_mix" type="float" setter="set_albedo_mix" getter="get_albedo_mix" default="1.0"> - Blends the albedo [Color] of the decal with albedo [Color] of the underlying mesh. + Blends the albedo [Color] of the decal with albedo [Color] of the underlying mesh. This can be set to [code]0.0[/code] to create a decal that only affects normal or ORM. In this case, an albedo texture is still required as its alpha channel will determine where the normal and ORM will be overridden. See also [member modulate]. </member> <member name="cull_mask" type="int" setter="set_cull_mask" getter="get_cull_mask" default="1048575"> Specifies which [member VisualInstance3D.layers] this decal will project on. By default, Decals affect all layers. This is used so you can specify which types of objects receive the Decal and which do not. This is especially useful so you can ensure that dynamic objects don't accidentally receive a Decal intended for the terrain under them. </member> - <member name="distance_fade_begin" type="float" setter="set_distance_fade_begin" getter="get_distance_fade_begin" default="10.0"> - Distance from the camera at which the Decal begins to fade away. + <member name="distance_fade_begin" type="float" setter="set_distance_fade_begin" getter="get_distance_fade_begin" default="40.0"> + The distance from the camera at which the Decal begins to fade away (in 3D units). </member> <member name="distance_fade_enabled" type="bool" setter="set_enable_distance_fade" getter="is_distance_fade_enabled" default="false"> - If [code]true[/code], decals will smoothly fade away when far from the active [Camera3D] starting at [member distance_fade_begin]. The Decal will fade out over [member distance_fade_length], after which it will be culled and not sent to the shader at all. Use this to reduce the number of active Decals in a scene and thus improve performance. + If [code]true[/code], decals will smoothly fade away when far from the active [Camera3D] starting at [member distance_fade_begin]. The Decal will fade out over [member distance_fade_begin] + [member distance_fade_length], after which it will be culled and not sent to the shader at all. Use this to reduce the number of active Decals in a scene and thus improve performance. </member> - <member name="distance_fade_length" type="float" setter="set_distance_fade_length" getter="get_distance_fade_length" default="1.0"> - Distance over which the Decal fades. The Decal becomes slowly more transparent over this distance and is completely invisible at the end. + <member name="distance_fade_length" type="float" setter="set_distance_fade_length" getter="get_distance_fade_length" default="10.0"> + The distance over which the Decal fades (in 3D units). The Decal becomes slowly more transparent over this distance and is completely invisible at the end. Higher values result in a smoother fade-out transition, which is more suited when the camera moves fast. </member> <member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy" default="1.0"> - Energy multiplier for the emission texture. This will make the decal emit light at a higher intensity. + Energy multiplier for the emission texture. This will make the decal emit light at a higher or lower intensity, independently of the albedo color. See also [member modulate]. </member> <member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3(1, 1, 1)"> Sets the size of the [AABB] used by the decal. The AABB goes from [code]-extents[/code] to [code]extents[/code]. </member> <member name="lower_fade" type="float" setter="set_lower_fade" getter="get_lower_fade" default="0.3"> - Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB]. Only positive values are valid (negative values will be clamped to [code]0.0[/code]). + Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB]. Only positive values are valid (negative values will be clamped to [code]0.0[/code]). See also [member upper_fade]. </member> <member name="modulate" type="Color" setter="set_modulate" getter="get_modulate" default="Color(1, 1, 1, 1)"> - Changes the [Color] of the Decal by multiplying it with this value. + Changes the [Color] of the Decal by multiplying the albedo and emission colors with this value. The alpha component is only taken into account when multiplying the albedo color, not the emission color. See also [member emission_energy] and [member albedo_mix] to change the emission and albedo intensity independently of each other. </member> <member name="normal_fade" type="float" setter="set_normal_fade" getter="get_normal_fade" default="0.0"> Fades the Decal if the angle between the Decal's [AABB] and the target surface becomes too large. A value of [code]0[/code] projects the Decal regardless of angle, a value of [code]1[/code] limits the Decal to surfaces that are nearly perpendicular. + [b]Note:[/b] Setting [member normal_fade] to a value greater than [code]0.0[/code] has a small performance cost due to the added normal angle computations. </member> <member name="texture_albedo" type="Texture2D" setter="set_texture" getter="get_texture"> [Texture2D] with the base [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object. @@ -98,13 +99,15 @@ <member name="texture_normal" type="Texture2D" setter="set_texture" getter="get_texture"> [Texture2D] with the per-pixel normal map for the decal. Use this to add extra detail to decals. [b]Note:[/b] Unlike [BaseMaterial3D] whose filter mode can be adjusted on a per-material basis, the filter mode for [Decal] textures is set globally with [member ProjectSettings.rendering/textures/decals/filter]. + [b]Note:[/b] Setting this texture alone will not result in a visible decal, as [member texture_albedo] must also be set. To create a normal-only decal, load an albedo texture into [member texture_albedo] and set [member albedo_mix] to [code]0.0[/code]. The albedo texture's alpha channel will be used to determine where the underlying surface's normal map should be overridden (and its intensity). </member> <member name="texture_orm" type="Texture2D" setter="set_texture" getter="get_texture"> [Texture2D] storing ambient occlusion, roughness, and metallic for the decal. Use this to add extra detail to decals. [b]Note:[/b] Unlike [BaseMaterial3D] whose filter mode can be adjusted on a per-material basis, the filter mode for [Decal] textures is set globally with [member ProjectSettings.rendering/textures/decals/filter]. + [b]Note:[/b] Setting this texture alone will not result in a visible decal, as [member texture_albedo] must also be set. To create a ORM-only decal, load an albedo texture into [member texture_albedo] and set [member albedo_mix] to [code]0.0[/code]. The albedo texture's alpha channel will be used to determine where the underlying surface's ORM map should be overridden (and its intensity). </member> <member name="upper_fade" type="float" setter="set_upper_fade" getter="get_upper_fade" default="0.3"> - Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB]. Only positive values are valid (negative values will be clamped to [code]0.0[/code]). + Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB]. Only positive values are valid (negative values will be clamped to [code]0.0[/code]). See also [member lower_fade]. </member> </members> <constants> diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index cec504584c..bc6cd88fa5 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -930,7 +930,7 @@ <return type="void" /> <argument index="0" name="existing_text" type="String" /> <argument index="1" name="position" type="Rect2" default="Rect2(0, 0, 0, 0)" /> - <argument index="2" name="multiline" type="bool" default="false" /> + <argument index="2" name="type" type="int" enum="DisplayServer.VirtualKeyboardType" default="0" /> <argument index="3" name="max_length" type="int" default="-1" /> <argument index="4" name="cursor_start" type="int" default="-1" /> <argument index="5" name="cursor_end" type="int" default="-1" /> @@ -938,11 +938,11 @@ Shows the virtual keyboard if the platform has one. [code]existing_text[/code] parameter is useful for implementing your own [LineEdit] or [TextEdit], as it tells the virtual keyboard what text has already been typed (the virtual keyboard uses it for auto-correct and predictions). [code]position[/code] parameter is the screen space [Rect2] of the edited text. - [code]multiline[/code] parameter needs to be set to [code]true[/code] to be able to enter multiple lines of text, as in [TextEdit]. + [code]type[/code] parameter allows configuring which type of virtual keyboard to show. [code]max_length[/code] limits the number of characters that can be entered if different from [code]-1[/code]. [code]cursor_start[/code] can optionally define the current text cursor position if [code]cursor_end[/code] is not set. [code]cursor_start[/code] and [code]cursor_end[/code] can optionally define the current text selection. - [b]Note:[/b] This method is implemented on Android, iOS and UWP. + [b]Note:[/b] This method is implemented on Android, iOS and HTML5. </description> </method> <method name="warp_mouse"> @@ -1049,7 +1049,7 @@ <return type="int" enum="DisplayServer.VSyncMode" /> <argument index="0" name="window_id" type="int" default="0" /> <description> - Returns the VSync mode of the given window. + Returns the V-Sync mode of the given window. </description> </method> <method name="window_move_to_foreground"> @@ -1234,7 +1234,7 @@ <argument index="0" name="vsync_mode" type="int" enum="DisplayServer.VSyncMode" /> <argument index="1" name="window_id" type="int" default="0" /> <description> - Sets the VSync mode of the given window. + Sets the V-Sync mode of the given window. See [enum DisplayServer.VSyncMode] for possible values and how they affect the behavior of your application. Depending on the platform and used renderer, the engine will fall back to [constant VSYNC_ENABLED], if the desired mode is not supported. </description> @@ -1323,6 +1323,31 @@ </constant> <constant name="SCREEN_SENSOR" value="6" enum="ScreenOrientation"> </constant> + <constant name="KEYBOARD_TYPE_DEFAULT" value="0" enum="VirtualKeyboardType"> + Default text virtual keyboard. + </constant> + <constant name="KEYBOARD_TYPE_MULTILINE" value="1" enum="VirtualKeyboardType"> + Multiline virtual keyboard. + </constant> + <constant name="KEYBOARD_TYPE_NUMBER" value="2" enum="VirtualKeyboardType"> + Virtual number keypad, useful for PIN entry. + </constant> + <constant name="KEYBOARD_TYPE_NUMBER_DECIMAL" value="3" enum="VirtualKeyboardType"> + Virtual number keypad, useful for entering fractional numbers. + </constant> + <constant name="KEYBOARD_TYPE_PHONE" value="4" enum="VirtualKeyboardType"> + Virtual phone number keypad. + </constant> + <constant name="KEYBOARD_TYPE_EMAIL_ADDRESS" value="5" enum="VirtualKeyboardType"> + Virtual keyboard with additional keys to assist with typing email addresses. + </constant> + <constant name="KEYBOARD_TYPE_PASSWORD" value="6" enum="VirtualKeyboardType"> + Virtual keyboard for entering a password. On most platforms, this should disable autocomplete and autocapitalization. + [b]Note:[/b] This is not supported on HTML5. Instead, this behaves identically to [constant KEYBOARD_TYPE_DEFAULT]. + </constant> + <constant name="KEYBOARD_TYPE_URL" value="7" enum="VirtualKeyboardType"> + Virtual keyboard with additional keys to assist with typing URLs. + </constant> <constant name="CURSOR_ARROW" value="0" enum="CursorShape"> </constant> <constant name="CURSOR_IBEAM" value="1" enum="CursorShape"> diff --git a/doc/classes/EditorFeatureProfile.xml b/doc/classes/EditorFeatureProfile.xml index 2ab87b0dd1..a6bdc294ac 100644 --- a/doc/classes/EditorFeatureProfile.xml +++ b/doc/classes/EditorFeatureProfile.xml @@ -57,7 +57,7 @@ <return type="int" enum="Error" /> <argument index="0" name="path" type="String" /> <description> - Saves the editor feature profile to a file in JSON format. It can then be imported using the feature profile manager's [b]Import[/b] button or the [method load_from_file] button. + Saves the editor feature profile to a file in JSON format. It can then be imported using the feature profile manager's [b]Import[/b] button or the [method load_from_file] method. </description> </method> <method name="set_disable_class"> diff --git a/doc/classes/EditorPaths.xml b/doc/classes/EditorPaths.xml index d44c08cb0f..2975ea6d75 100644 --- a/doc/classes/EditorPaths.xml +++ b/doc/classes/EditorPaths.xml @@ -48,6 +48,12 @@ [/codeblock] </description> </method> + <method name="get_project_settings_dir" qualifiers="const"> + <return type="String" /> + <description> + Returns the project-specific editor settings path. Projects all have a unique subdirectory inside the settings path where project-specific editor settings are saved. + </description> + </method> <method name="get_self_contained_file" qualifiers="const"> <return type="String" /> <description> diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml index 84f8523da3..586458bd28 100644 --- a/doc/classes/EditorProperty.xml +++ b/doc/classes/EditorProperty.xml @@ -101,6 +101,13 @@ Used by sub-inspectors. Emit it if what was selected was an Object ID. </description> </signal> + <signal name="property_can_revert_changed"> + <argument index="0" name="property" type="StringName" /> + <argument index="1" name="can_revert" type="bool" /> + <description> + Emitted when the revertability (i.e., whether it has a non-default value and thus is displayed with a revert icon) of a property has changed. + </description> + </signal> <signal name="property_changed"> <argument index="0" name="property" type="StringName" /> <argument index="1" name="value" type="Variant" /> diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index ac2250ab6d..ade7bc1256 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -105,12 +105,6 @@ Returns project-specific metadata for the [code]section[/code] and [code]key[/code] specified. If the metadata doesn't exist, [code]default[/code] will be returned instead. See also [method set_project_metadata]. </description> </method> - <method name="get_project_settings_dir" qualifiers="const"> - <return type="String" /> - <description> - Returns the project-specific settings path. Projects all have a unique subdirectory inside the settings path where project-specific settings are saved. - </description> - </method> <method name="get_recent_dirs" qualifiers="const"> <return type="PackedStringArray" /> <description> @@ -157,6 +151,7 @@ <argument index="0" name="name" type="String" /> <argument index="1" name="actions_list" type="Array" /> <description> + Overrides the built-in editor action [code]name[/code] with the input actions defined in [code]actions_list[/code]. </description> </method> <method name="set_favorites"> @@ -200,6 +195,730 @@ </description> </method> </methods> + <members> + <member name="debugger/profiler_frame_history_size" type="int" setter="" getter=""> + The size of the profiler's frame history. The default value (3600) allows seeing up to 60 seconds of profiling if the project renders at a constant 60 FPS. Higher values allow viewing longer periods of profiling in the graphs, especially when the project is running at high framerates. + </member> + <member name="docks/filesystem/always_show_folders" type="bool" setter="" getter=""> + If [code]true[/code], displays folders in the FileSystem dock's bottom pane when split mode is enabled. If [code]false[/code], only files will be displayed in the bottom pane. Split mode can be toggled by pressing the icon next to the [code]res://[/code] folder path. + [b]Note:[/b] This setting has no effect when split mode is disabled (which is the default). + </member> + <member name="docks/filesystem/textfile_extensions" type="String" setter="" getter=""> + List of file extensions to consider as editable text files in the FileSystem dock (by double-clicking on the files). + </member> + <member name="docks/filesystem/thumbnail_size" type="int" setter="" getter=""> + The thumbnail size to use in the FileSystem dock (in pixels). See also [member filesystem/file_dialog/thumbnail_size]. + </member> + <member name="docks/property_editor/auto_refresh_interval" type="float" setter="" getter=""> + The refresh interval to use for the inspector dock's properties. The effect of this setting is mainly noticeable when adjusting gizmos in the 2D/3D editor and looking at the inspector at the same time. Lower values make the inspector more often, but take up more CPU time. + </member> + <member name="docks/property_editor/subresource_hue_tint" type="float" setter="" getter=""> + The tint intensity to use for the subresources background in the inspector dock. The tint is used to distinguish between different subresources in the inspector. Higher values result in a more noticeable background color difference. + </member> + <member name="docks/scene_tree/auto_expand_to_selected" type="bool" setter="" getter=""> + If [code]true[/code], the scene tree dock will automatically unfold nodes when a node that has folded parents is selected. + </member> + <member name="docks/scene_tree/start_create_dialog_fully_expanded" type="bool" setter="" getter=""> + If [code]true[/code], the Create dialog (Create New Node/Create New Resource) will start with all its sections expanded. Otherwise, sections will be collapsed until the user starts searching (which will automatically expand sections as needed). + </member> + <member name="editors/2d/bone_color1" type="Color" setter="" getter=""> + The "start" stop of the color gradient to use for bones in the 2D skeleton editor. + </member> + <member name="editors/2d/bone_color2" type="Color" setter="" getter=""> + The "end" stop of the color gradient to use for bones in the 2D skeleton editor. + </member> + <member name="editors/2d/bone_ik_color" type="Color" setter="" getter=""> + The color to use for inverse kinematics-enabled bones in the 2D skeleton editor. + </member> + <member name="editors/2d/bone_outline_color" type="Color" setter="" getter=""> + The outline color to use for non-selected bones in the 2D skeleton editor. See also [member editors/2d/bone_selected_color]. + </member> + <member name="editors/2d/bone_outline_size" type="int" setter="" getter=""> + The outline size in the 2D skeleton editor (in pixels). See also [member editors/2d/bone_width]. + </member> + <member name="editors/2d/bone_selected_color" type="Color" setter="" getter=""> + The color to use for selected bones in the 2D skeleton editor. See also [member editors/2d/bone_outline_color]. + </member> + <member name="editors/2d/bone_width" type="int" setter="" getter=""> + The bone width in the 2D skeleton editor (in pixels). See also [member editors/2d/bone_outline_size]. + </member> + <member name="editors/2d/constrain_editor_view" type="bool" setter="" getter=""> + If [code]true[/code], prevents the 2D editor viewport from leaving the scene. Limits are calculated dynamically based on nodes present in the current scene. If [code]false[/code], the 2D editor viewport will be able to move freely, but you risk getting lost when zooming out too far. You can refocus on the scene by selecting a node then pressing [kbd]F[/kbd]. + </member> + <member name="editors/2d/grid_color" type="Color" setter="" getter=""> + The grid color to use in the 2D editor. + </member> + <member name="editors/2d/guides_color" type="Color" setter="" getter=""> + The guides color to use in the 2D editor. Guides can be created by dragging the mouse cursor from the rulers. + </member> + <member name="editors/2d/smart_snapping_line_color" type="Color" setter="" getter=""> + The color to use when drawing smart snapping lines in the 2D editor. The smart snapping lines will automatically display when moving 2D nodes if smart snapping is enabled in the Snapping Options menu at the top of the 2D editor viewport. + </member> + <member name="editors/2d/viewport_border_color" type="Color" setter="" getter=""> + The color of the viewport border in the 2D editor. This border represents the viewport's size at the base resolution defined in the Project Settings. Objects placed outside this border will not be visible unless a [Camera2D] node is used, or unless the window is resized and the stretch mode is set to [code]disabled[/code]. + </member> + <member name="editors/3d/default_fov" type="float" setter="" getter=""> + The default camera field of view to use in the 3D editor (in degrees). The camera field of view can be adjusted on a per-scene basis using the [b]View[/b] menu at the top of the 3D editor. If a scene had its camera field of view adjusted using the [b]View[/b] menu, this setting is ignored in the scene in question. This setting is also ignored while a Camera3D node is being previewed in the editor. + </member> + <member name="editors/3d/default_z_far" type="float" setter="" getter=""> + The default camera far clip distance to use in the 3D editor (in degrees). Higher values make it possible to view objects placed further away from the camera, at the cost of lower precision in the depth buffer (which can result in visible Z-fighting in the distance). The camera far clip distance can be adjusted on a per-scene basis using the [b]View[/b] menu at the top of the 3D editor. If a scene had its camera far clip distance adjusted using the [b]View[/b] menu, this setting is ignored in the scene in question. This setting is also ignored while a Camera3D node is being previewed in the editor. + </member> + <member name="editors/3d/default_z_near" type="float" setter="" getter=""> + The default camera near clip distance to use in the 3D editor (in degrees). Lower values make it possible to view objects placed closer to the camera, at the cost of lower precision in the depth buffer (which can result in visible Z-fighting in the distance). The camera near clip distance can be adjusted on a per-scene basis using the [b]View[/b] menu at the top of the 3D editor. If a scene had its camera near clip distance adjusted using the [b]View[/b] menu, this setting is ignored in the scene in question. This setting is also ignored while a Camera3D node is being previewed in the editor. + </member> + <member name="editors/3d/freelook/freelook_activation_modifier" type="int" setter="" getter=""> + The modifier key to use to enable freelook in the 3D editor (on top of pressing the right mouse button). + [b]Note:[/b] Regardless of this setting, the freelook toggle keyboard shortcut ([kbd]Shift + F[/kbd] by default) is always available. + [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed. + </member> + <member name="editors/3d/freelook/freelook_base_speed" type="float" setter="" getter=""> + The base 3D freelook speed in units per second. This can be adjusted by using the mouse wheel while in freelook mode, or by holding down the "fast" or "slow" modifier keys ([kbd]Shift[/kbd] and [kbd]Alt[/kbd] by default, respectively). + </member> + <member name="editors/3d/freelook/freelook_inertia" type="float" setter="" getter=""> + The inertia of the 3D freelook camera. Higher values make the camera start and stop slower, which looks smoother but adds latency. + </member> + <member name="editors/3d/freelook/freelook_navigation_scheme" type="int" setter="" getter=""> + The navigation scheme to use when freelook is enabled in the 3D editor. Some of the navigation schemes below may be more convenient when designing specific levels in the 3D editor. + - [b]Default:[/b] The "Freelook Forward", "Freelook Backward", "Freelook Up" and "Freelook Down" keys will move relative to the camera, taking its pitch angle into account for the movement. + - [b]Partially Axis-Locked:[/b] The "Freelook Forward" and "Freelook Backward" keys will move relative to the camera, taking its pitch angle into account for the movement. The "Freelook Up" and "Freelook Down" keys will move in an "absolute" manner, [i]not[/i] taking the camera's pitch angle into account for the movement. + - [b]Fully Axis-Locked:[/b] The "Freelook Forward", "Freelook Backward", "Freelook Up" and "Freelook Down" keys will move in an "absolute" manner, [i]not[/i] taking the camera's pitch angle into account for the movement. + See also [member editors/3d/navigation/navigation_scheme]. + </member> + <member name="editors/3d/freelook/freelook_sensitivity" type="float" setter="" getter=""> + The mouse sensitivity to use while freelook mode is active in the 3D editor. See also [member editors/3d/navigation_feel/orbit_sensitivity]. + </member> + <member name="editors/3d/freelook/freelook_speed_zoom_link" type="bool" setter="" getter=""> + If [code]true[/code], freelook speed is linked to the zoom value used in the camera orbit mode in the 3D editor. + </member> + <member name="editors/3d/grid_division_level_bias" type="float" setter="" getter=""> + The grid division bias to use in the 3D editor. Negative values will cause small grid divisions to appear earlier, whereas positive values will cause small grid divisions to appear later. + </member> + <member name="editors/3d/grid_division_level_max" type="int" setter="" getter=""> + The smallest grid division to use in the 3D editor, specified as a power of 2. The grid will not be able to get larger than [code]1 ^ grid_division_level_max[/code] units. By default, this means grid divisions cannot get smaller than 100 units each, no matter how far away the camera is from the grid. + </member> + <member name="editors/3d/grid_division_level_min" type="int" setter="" getter=""> + The smallest grid division to use in the 3D editor, specified as a power of 2. The grid will not be able to get smaller than [code]1 ^ grid_division_level_min[/code] units. By default, this means grid divisions cannot get smaller than 1 unit each, no matter how close the camera is from the grid. + </member> + <member name="editors/3d/grid_size" type="int" setter="" getter=""> + The grid size in units. Higher values prevent the grid from appearing "cut off" at certain angles, but make the grid more demanding to render. Depending on the camera's position, the grid may not be fully visible since a shader is used to fade it progressively. + </member> + <member name="editors/3d/grid_xy_plane" type="bool" setter="" getter=""> + If [code]true[/code], render the grid on an XY plane. This can be useful for 3D side-scrolling games. + </member> + <member name="editors/3d/grid_xz_plane" type="bool" setter="" getter=""> + If [code]true[/code], render the grid on an XZ plane. + </member> + <member name="editors/3d/grid_yz_plane" type="bool" setter="" getter=""> + If [code]true[/code], render the grid on an YZ plane. This can be useful for 3D side-scrolling games. + </member> + <member name="editors/3d/navigation/emulate_3_button_mouse" type="bool" setter="" getter=""> + If [code]true[/code], enables 3-button mouse emulation mode. This is useful on laptops when using a trackpad. + When 3-button mouse emulation mode is enabled, the pan, zoom and orbit modifiers can always be used in the 3D editor viewport, even when not holding down any mouse button. + [b]Note:[/b] No matter the orbit modifier configured in [member editors/3d/navigation/orbit_modifier], [kbd]Alt[/kbd] will always remain usable for orbiting in this mode to improve usability with graphics tablets. + </member> + <member name="editors/3d/navigation/emulate_numpad" type="bool" setter="" getter=""> + If [code]true[/code], allows using the top row [kbd]0[/kbd]-[kbd]9[/kbd] keys to function as their equivalent numpad keys for 3D editor navigation. This should be enabled on keyboards that have no numeric keypad available. + </member> + <member name="editors/3d/navigation/invert_x_axis" type="bool" setter="" getter=""> + If [code]true[/code], invert the horizontal mouse axis when panning or orbiting in the 3D editor. This setting does [i]not[/i] apply to freelook mode. + </member> + <member name="editors/3d/navigation/invert_y_axis" type="bool" setter="" getter=""> + If [code]true[/code], invert the vertical mouse axis when panning, orbiting, or using freelook mode in the 3D editor. + </member> + <member name="editors/3d/navigation/navigation_scheme" type="int" setter="" getter=""> + The navigation scheme to use in the 3D editor. Changing this setting will affect the mouse buttons that must be held down to perform certain operations in the 3D editor viewport. + - [b]Godot[/b] Middle mouse button to orbit, [kbd]Shift + Middle mouse button[/kbd] to pan. [kbd]Mouse wheel[/kbd] to zoom. + - [b]Maya:[/b] [kbd]Alt + Left mouse buttton[/kbd] to orbit. [kbd]Middle mouse button[/kbd] to pan, [kbd]Shift + Middle mouse button[/kbd] to pan 10 times faster. [kbd]Mouse wheel[/kbd] to zoom. + - [b]Modo:[/b] [kbd]Alt + Left mouse buttton[/kbd] to orbit. [kbd]Alt + Shift + Left mouse button[/kbd] to pan. [kbd]Ctrl + Alt + Left mouse button[/kbd] to zoom. + See also [member editors/3d/freelook/freelook_navigation_scheme]. + [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed. + </member> + <member name="editors/3d/navigation/orbit_modifier" type="int" setter="" getter=""> + The modifier key that must be held to orbit in the 3D editor. + [b]Note:[/b] If [member editors/3d/navigation/emulate_3_button_mouse] is [code]true[/code], [kbd]Alt[/kbd] will always remain usable for orbiting to improve usability with graphics tablets. + [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed. + </member> + <member name="editors/3d/navigation/pan_modifier" type="int" setter="" getter=""> + The modifier key that must be held to pan in the 3D editor. + [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed. + </member> + <member name="editors/3d/navigation/warped_mouse_panning" type="bool" setter="" getter=""> + If [code]true[/code], warps the mouse around the 3D viewport while panning in the 3D editor. This makes it possible to pan over a large area without having to exit panning then mouse the mouse back constantly. + </member> + <member name="editors/3d/navigation/zoom_modifier" type="int" setter="" getter=""> + The modifier key that must be held to zoom in the 3D editor. + [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed. + </member> + <member name="editors/3d/navigation/zoom_style" type="int" setter="" getter=""> + The mouse cursor movement direction to use when zooming by moving the mouse. This does not affect zooming with the mouse wheel. + </member> + <member name="editors/3d/navigation_feel/orbit_inertia" type="float" setter="" getter=""> + The inertia to use when orbiting in the 3D editor. Higher values make the camera start and stop slower, which looks smoother but adds latency. + </member> + <member name="editors/3d/navigation_feel/orbit_sensitivity" type="float" setter="" getter=""> + The mouse sensitivity to use when orbiting in the 3D editor. See also [member editors/3d/freelook/freelook_sensitivity]. + </member> + <member name="editors/3d/navigation_feel/translation_inertia" type="float" setter="" getter=""> + The inertia to use when panning in the 3D editor. Higher values make the camera start and stop slower, which looks smoother but adds latency. + </member> + <member name="editors/3d/navigation_feel/zoom_inertia" type="float" setter="" getter=""> + The inertia to use when zooming in the 3D editor. Higher values make the camera start and stop slower, which looks smoother but adds latency. + </member> + <member name="editors/3d/primary_grid_color" type="Color" setter="" getter=""> + The color to use for the primary 3D grid. The color's alpha channel affects the grid's opacity. + </member> + <member name="editors/3d/primary_grid_steps" type="int" setter="" getter=""> + If set above 0, where a primary grid line should be drawn. By default, primary lines are configured to be more visible than secondary lines. This helps with measurements in the 3D editor. See also [member editors/3d/primary_grid_color] and [member editors/3d/secondary_grid_color]. + </member> + <member name="editors/3d/secondary_grid_color" type="Color" setter="" getter=""> + The color to use for the secondary 3D grid. This is generally a less visible color than [member editors/3d/primary_grid_color]. The color's alpha channel affects the grid's opacity. + </member> + <member name="editors/3d/selection_box_color" type="Color" setter="" getter=""> + The color to use for the selection box that surrounds selected nodes in the 3D editor viewport. The color's alpha channel influences the selection box's opacity. + </member> + <member name="editors/3d_gizmos/gizmo_colors/instantiated" type="Color" setter="" getter=""> + The color override to use for 3D editor gizmos if the [Node3D] in question is part of an instanced scene file (from the perspective of the current scene). + </member> + <member name="editors/3d_gizmos/gizmo_colors/joint" type="Color" setter="" getter=""> + The 3D editor gizmo color for [Joint3D]s and [PhysicalBone3D]s. + </member> + <member name="editors/3d_gizmos/gizmo_colors/shape" type="Color" setter="" getter=""> + The 3D editor gizmo color for [CollisionShape3D]s, [VehicleWheel3D]s, [RayCast3D]s and [SpringArm3D]s. + </member> + <member name="editors/animation/autorename_animation_tracks" type="bool" setter="" getter=""> + If [code]true[/code], automatically updates animation tracks' target paths when renaming or reparenting nodes in the Scene tree dock. + </member> + <member name="editors/animation/confirm_insert_track" type="bool" setter="" getter=""> + If [code]true[/code], display a confirmation dialog when adding a new track to an animation by pressing the "key" icon next to a property. + </member> + <member name="editors/animation/default_create_bezier_tracks" type="bool" setter="" getter=""> + If [code]true[/code], create a Bezier track instead of a standard track when pressing the "key" icon next to a property. Bezier tracks provide more control over animation curves, but are more difficult to adjust quickly. + </member> + <member name="editors/animation/default_create_reset_tracks" type="bool" setter="" getter=""> + If [code]true[/code], create a [code]RESET[/code] track when creating a new animation track. This track can be used to restore the animation to a "default" state. + </member> + <member name="editors/animation/onion_layers_future_color" type="Color" setter="" getter=""> + The modulate color to use for "future" frames displayed in the animation editor's onion skinning feature. + </member> + <member name="editors/animation/onion_layers_past_color" type="Color" setter="" getter=""> + The modulate color to use for "past" frames displayed in the animation editor's onion skinning feature. + </member> + <member name="editors/grid_map/pick_distance" type="float" setter="" getter=""> + The maximum distance at which tiles can be placed on a GridMap, relative to the camera position (in 3D units). + </member> + <member name="editors/panning/2d_editor_pan_speed" type="int" setter="" getter=""> + The panning speed when using the mouse wheel or touchscreen events in the 2D editor. This setting does not apply to panning by holding down the middle or right mouse buttons. + </member> + <member name="editors/panning/2d_editor_panning_scheme" type="int" setter="" getter=""> + Controls whether the mouse wheel scroll zooms or pans in the 2D editor. See also [member editors/panning/sub_editors_panning_scheme] and [member editors/panning/animation_editors_panning_scheme]. + </member> + <member name="editors/panning/animation_editors_panning_scheme" type="int" setter="" getter=""> + Controls whether the mouse wheel scroll zooms or pans in the animation track and Bezier editors. See also [member editors/panning/2d_editor_panning_scheme] and [member editors/panning/sub_editors_panning_scheme] (which controls the animation blend tree editor's pan behavior). + </member> + <member name="editors/panning/simple_panning" type="bool" setter="" getter=""> + If [code]true[/code], allows panning by holding down [kbd]Space[/kbd] in the 2D editor viewport (in addition to panning with the middle or right mouse buttons). If [code]false[/code], the left mouse button must be held down while holding down [kbd]Space[/kbd] to pan in the 2D editor viewport. + </member> + <member name="editors/panning/sub_editors_panning_scheme" type="int" setter="" getter=""> + Controls whether the mouse wheel scroll zooms or pans in subeditors. The list of affected subeditors is: animation blend tree editor, [Polygon2D] editor, tileset editor, texture region editor, visual shader editor and visual script editor. See also [member editors/panning/2d_editor_panning_scheme] and [member editors/panning/animation_editors_panning_scheme]. + </member> + <member name="editors/panning/warped_mouse_panning" type="bool" setter="" getter=""> + If [code]true[/code], warps the mouse around the 2D viewport while panning in the 2D editor. This makes it possible to pan over a large area without having to exit panning then mouse the mouse back constantly. + </member> + <member name="editors/polygon_editor/point_grab_radius" type="int" setter="" getter=""> + The radius in which points can be selected in the [Polygon2D] and [CollisionPolygon2D] editors (in pixels). Higher values make it easier to select points quickly, but can make it more difficult to select the expected point when several points are located close to each other. + </member> + <member name="editors/polygon_editor/show_previous_outline" type="bool" setter="" getter=""> + If [code]true[/code], displays the polygon's previous shape in the 2D polygon editors with an opaque gray outline. This outline is displayed while dragging a point until the left mouse button is released. + </member> + <member name="editors/tiles_editor/display_grid" type="bool" setter="" getter=""> + If [code]true[/code], displays a grid while the TileMap editor is active. See also [member editors/tiles_editor/grid_color]. + </member> + <member name="editors/tiles_editor/grid_color" type="Color" setter="" getter=""> + The color to use for the TileMap editor's grid. + [b]Note:[/b] Only effective if [member editors/tiles_editor/display_grid] is [code]true[/code]. + </member> + <member name="editors/visual_editors/lines_curvature" type="float" setter="" getter=""> + The curvature to use for connection lines in the visual script and visual shader editors. Higher values will make connection lines appear more curved, with values above [code]0.5[/code] resulting in more "angular" turns in the middle of connection lines. + </member> + <member name="editors/visual_editors/minimap_opacity" type="float" setter="" getter=""> + The opacity of the minimap displayed in the bottom-right corner of the visual script and visual shader editors. + </member> + <member name="editors/visual_editors/visual_shader/port_preview_size" type="int" setter="" getter=""> + The size to use for port previews in the visual shader uniforms (toggled by clicking the "eye" icon next to an output). The value is defined in pixels at 100% zoom, and will scale with zoom automatically. + </member> + <member name="filesystem/directories/autoscan_project_path" type="String" setter="" getter=""> + The folder where projects should be scanned for (recursively), in a way similar to the project manager's [b]Scan[/b]button. This can be set to the same value as [member filesystem/directories/default_project_path] for convenience. + [b]Note:[/b] Setting this path to a folder with very large amounts of files/folders can slow down the project manager startup significantly. To keep the project manager quick to start up, it is recommended to set this value to a folder as "specific" as possible. + </member> + <member name="filesystem/directories/default_project_path" type="String" setter="" getter=""> + The folder where new projects should be created by default when clicking the project manager's [b]New Project[/b] button. This can be set to the same value as [member filesystem/directories/autoscan_project_path] for convenience. + </member> + <member name="filesystem/file_dialog/display_mode" type="int" setter="" getter=""> + The display mode to use in the editor's file dialogs. + - [b]Thumbnails[/b] takes more space, but displays dynamic resource thumbnails, making resources easier to preview without having to open them. + - [b]List[/b] is more compact but doesn't display dynamic resource thumbnails. Instead, it displays static icons based on the file extension. + </member> + <member name="filesystem/file_dialog/show_hidden_files" type="bool" setter="" getter=""> + If [code]true[/code], display hidden files in the editor's file dialogs. Files that have names starting with [code].[/code] are considered hidden (e.g. [code].hidden_file[/code]). + </member> + <member name="filesystem/file_dialog/thumbnail_size" type="int" setter="" getter=""> + The thumbnail size to use in the editor's file dialogs (in pixels). See also [member docks/filesystem/thumbnail_size]. + </member> + <member name="filesystem/on_save/compress_binary_resources" type="bool" setter="" getter=""> + If [code]true[/code], uses lossless compression for binary resources. + </member> + <member name="filesystem/on_save/safe_save_on_backup_then_rename" type="bool" setter="" getter=""> + If [code]true[/code], when saving a file, the editor will rename the old file to a different name, save a new file, then only remove the old file once the new file has been saved. This makes loss of data less likely to happen if the editor or operating system exits unexpectedly while saving (e.g. due to a crash or power outage). + [b]Note:[/b] On Windows, this feature can interact negatively with certain antivirus programs. In this case, you may have to set this to [code]false[/code] to prevent file locking issues. + </member> + <member name="interface/editor/automatically_open_screenshots" type="bool" setter="" getter=""> + If [code]true[/code], automatically opens screenshots with the default program associated to [code].png[/code] files after a screenshot is taken using the [b]Editor > Take Screenshot[/b] action. + </member> + <member name="interface/editor/code_font" type="String" setter="" getter=""> + The font to use for the script editor. Must be a resource of a [Font] type such as a [code].ttf[/code] or [code].otf[/code] font file. + </member> + <member name="interface/editor/code_font_contextual_ligatures" type="int" setter="" getter=""> + The font ligatures to enable for the currently configured code font. Not all fonts include support for ligatures. + [b]Note:[/b] The default editor code font (Hack) does not have contextual ligatures in its font file. + </member> + <member name="interface/editor/code_font_custom_opentype_features" type="String" setter="" getter=""> + List of custom OpenType features to use, if supported by the currently configured code font. Not all fonts include support for custom OpenType features. The string should follow the OpenType specification. + [b]Note:[/b] The default editor code font (Hack) does not have custom OpenType features in its font file. + </member> + <member name="interface/editor/code_font_custom_variations" type="String" setter="" getter=""> + List of alternative characters to use, if supported by the currently configured code font. Not all fonts include support for custom variations. The string should follow the OpenType specification. + [b]Note:[/b] The default editor code font (Hack) does not have alternate characters in its font file. + </member> + <member name="interface/editor/code_font_size" type="int" setter="" getter=""> + The size of the font in the script editor. This setting does not impact the font size of the Output panel (see [member run/output/font_size]). + </member> + <member name="interface/editor/custom_display_scale" type="float" setter="" getter=""> + The custom editor scale factor to use. This can be used for displays with very high DPI where a scale factor of 200% is not sufficient. + [b]Note:[/b] Only effective if [member interface/editor/display_scale] is set to [b]Custom[/b]. + </member> + <member name="interface/editor/debug/enable_pseudolocalization" type="bool" setter="" getter=""> + If [code]true[/code], lengthens the editor's localizable strings and replaces their characters with accented variants. This allows spotting non-localizable strings easily, while also ensuring the UI layout doesn't break when strings are made longer (as many languages require strings to be longer). + This is a debugging feature and should only be enabled when working on the editor itself. + </member> + <member name="interface/editor/display_scale" type="int" setter="" getter=""> + The display scale factor to use for the editor interface. Higher values are more suited to hiDPI/Retina displays. + If set to [b]Auto[/b], the editor scale is automatically determined based on the screen resolution and reported display DPI. This heuristic is not always ideal, which means you can get better results by setting the editor scale manually. + If set to [b]Custom[/b], the scaling value in [member interface/editor/custom_display_scale] will be used. + </member> + <member name="interface/editor/editor_language" type="String" setter="" getter=""> + The language to use for the editor interface. + Translations are provided by the community. If you spot a mistake, [url=https://docs.godotengine.org/en/latest/community/contributing/editor_and_docs_localization.html]contribute to editor translations on Weblate![/url] + </member> + <member name="interface/editor/font_antialiased" type="bool" setter="" getter=""> + If [code]true[/code], enables FreeType's font antialiasing on the editor fonts. Most fonts are not designed to look good with antialiasing disabled, so it's recommended to leave this enabled unless you're using a pixel art font. + </member> + <member name="interface/editor/font_hinting" type="int" setter="" getter=""> + The font hinting mode to use for the editor fonts. FreeType supports the following font hinting modes: + - [b]None:[/b] Don't use font hinting when rasterizing the font. This results in a smooth font, but it can look blurry. + - [b]Light:[/b] Use hinting on the X axis only. This is a compromise between font sharpness and smoothness. + - [b]Normal:[/b] Use hinting on both X and Y axes. This results in a sharp font, but it doesn't look very smooth. + If set to [b]Auto[/b], the font hinting mode will be set to match the current operating system in use. This means the [b]Light[/b] hinting mode will be used on Windows and Linux, and the [b]None[/b] hinting mode will be used on macOS. + </member> + <member name="interface/editor/font_subpixel_positioning" type="int" setter="" getter=""> + The subpixel positioning mode to use when rendering editor font glyphs. This affects both the main and code fonts. [b]Disabled[/b] is the fastest to render and uses the least memory. [b]Auto[/b] only uses subpixel positioning for small font sizes (where the benefit is the most noticeable). [b]One half of a pixel[/b] and [b]One quarter of a pixel[/b] force the same subpixel positioning mode for all editor fonts, regardless of their size (with [b]One quarter of a pixel[/b] being the highest-quality option). + </member> + <member name="interface/editor/low_processor_mode_sleep_usec" type="float" setter="" getter=""> + The amount of sleeping between frames when the low-processor usage mode is enabled (in microseconds). Higher values will result in lower CPU/GPU usage, which can improve battery life on laptops. However, higher values will result in a less responsive editor. The default value is set to allow for maximum smoothness on monitors up to 144 Hz. See also [member interface/editor/unfocused_low_processor_mode_sleep_usec]. + </member> + <member name="interface/editor/main_font" type="String" setter="" getter=""> + The font to use for the editor interface. Must be a resource of a [Font] type such as a [code].ttf[/code] or [code].otf[/code] font file. + </member> + <member name="interface/editor/main_font_bold" type="String" setter="" getter=""> + The font to use for bold text in the editor interface. Must be a resource of a [Font] type such as a [code].ttf[/code] or [code].otf[/code] font file. + </member> + <member name="interface/editor/main_font_size" type="int" setter="" getter=""> + The size of the font in the editor interface. + </member> + <member name="interface/editor/mouse_extra_buttons_navigate_history" type="bool" setter="" getter=""> + If [code]true[/code], the mouse's additional side buttons will be usable to navigate in the script editor's file history. Set this to [code]false[/code] if you're using the side buttons for other purposes (such as a push-to-talk button in a VoIP program). + </member> + <member name="interface/editor/save_each_scene_on_quit" type="bool" setter="" getter=""> + If [code]true[/code], the editor will save all scenes when confirming the [b]Save[/b] action when quitting the editor or quitting to the project list. If [code]false[/code], the editor will ask to save each scene individually. + </member> + <member name="interface/editor/separate_distraction_mode" type="bool" setter="" getter=""> + If [code]true[/code], the editor's Script tab will have a separate distraction mode setting from the 2D/3D/AssetLib tabs. If [code]false[/code], the distraction-free mode toggle is shared between all tabs. + </member> + <member name="interface/editor/show_internal_errors_in_toast_notifications" type="int" setter="" getter=""> + If enabled, displays internal engine errors in toast notifications (toggleable by clicking the "bell" icon at the bottom of the editor). No matter the value of this setting, non-internal engine errors will always be visible in toast notifications. + The default [b]Auto[/b] value will only enable this if the editor was compiled with the [code]dev=yes[/code] option (the default is [code]dev=no[/code]). + </member> + <member name="interface/editor/single_window_mode" type="bool" setter="" getter=""> + If [code]true[/code], embed modal windows such as docks inside the main editor window. When single-window mode is enabled, tooltips will also be embedded inside the main editor window, which means they can't be displayed outside of the editor window. + </member> + <member name="interface/editor/unfocused_low_processor_mode_sleep_usec" type="float" setter="" getter=""> + When the editor window is unfocused, the amount of sleeping between frames when the low-processor usage mode is enabled (in microseconds). Higher values will result in lower CPU/GPU usage, which can improve battery life on laptops (in addition to improving the running project's performance if the editor has to redraw continuously). However, higher values will result in a less responsive editor. The default value is set to limit the editor to 20 FPS when the editor window is unfocused. See also [member interface/editor/low_processor_mode_sleep_usec]. + </member> + <member name="interface/inspector/max_array_dictionary_items_per_page" type="int" setter="" getter=""> + The number of [Array] or [Dictionary] items to display on each "page" in the inspector. Higher values allow viewing more values per page, but take more time to load. This increased load time is noticeable when selecting nodes that have array or dictionary properties in the editor. + </member> + <member name="interface/inspector/show_low_level_opentype_features" type="bool" setter="" getter=""> + If [code]true[/code], display OpenType features marked as [code]hidden[/code] by the font file in the [Font] editor. + </member> + <member name="interface/scene_tabs/display_close_button" type="int" setter="" getter=""> + Controls when the Close (X) button is displayed on scene tabs at the top of the editor. + </member> + <member name="interface/scene_tabs/maximum_width" type="int" setter="" getter=""> + The maximum width of each scene tab at the top editor (in pixels). + </member> + <member name="interface/scene_tabs/show_script_button" type="bool" setter="" getter=""> + If [code]true[/code], show a button next to each scene tab that opens the scene's "dominant" script when clicked. The "dominant" script is the one that is at the highest level in the scene's hierarchy. + </member> + <member name="interface/scene_tabs/show_thumbnail_on_hover" type="bool" setter="" getter=""> + If [code]true[/code], display an automatically-generated thumbnail when hovering scene tabs with the mouse. Scene thumbnails are generated when saving the scene. + </member> + <member name="interface/theme/accent_color" type="Color" setter="" getter=""> + The color to use for "highlighted" user interface elements in the editor (pressed and hovered items). + </member> + <member name="interface/theme/additional_spacing" type="float" setter="" getter=""> + The spacing to add for buttons and list items in the editor (in pixels). Increasing this value is useful to improve usability on touch screens, at the cost of reducing the amount of usable screen real estate. + </member> + <member name="interface/theme/base_color" type="Color" setter="" getter=""> + The base color to use for user interface elements in the editor. Secondary colors (such as darker/lighter variants) are derived from this color. + </member> + <member name="interface/theme/border_size" type="int" setter="" getter=""> + The border size to use for interface elements (in pixels). + </member> + <member name="interface/theme/contrast" type="float" setter="" getter=""> + The contrast factor to use when deriving the editor theme's base color (see [member interface/theme/base_color]). When using a positive values, the derived colors will be [i]darker[/i] than the base color. This contrast factor can be set to a negative value, which will make the derived colors [i]brighter[/i] than the base color. Negative contrast rates often look better for light themes. + </member> + <member name="interface/theme/corner_radius" type="int" setter="" getter=""> + The corner radius to use for interface elements (in pixels). [code]0[/code] is square. + </member> + <member name="interface/theme/custom_theme" type="String" setter="" getter=""> + The custom theme resource to use for the editor. Must be a Godot theme resource in [code].tres[/code] or [code].res[/code] format. + </member> + <member name="interface/theme/icon_and_font_color" type="int" setter="" getter=""> + The icon and font color scheme to use in the editor. + - [b]Auto[/b] determines the color scheme to use automatically based on [member interface/theme/base_color]. + - [b]Dark[/b] makes fonts and icons light (suitable for dark themes). + - [b]Light[/b] makes fonts and icons dark (suitable for light themes). Icon colors are automatically converted by the editor following [url=https://github.com/godotengine/godot/blob/master/editor/editor_themes.cpp#L135]this set of rules[/url]. + </member> + <member name="interface/theme/icon_saturation" type="float" setter="" getter=""> + The saturation to use for editor icons. Higher values result in more vibrant colors. + [b]Note:[/b] The default editor icon saturation was increased by 30% in Godot 4.0 and later. To get Godot 3.x's icon saturation back, set [member interface/theme/icon_saturation] to [code]0.77[/code]. + </member> + <member name="interface/theme/preset" type="String" setter="" getter=""> + The editor theme preset to use. + </member> + <member name="interface/theme/relationship_line_opacity" type="float" setter="" getter=""> + The opacity to use when drawing relationship lines in the editor's [Tree]-based GUIs (such as the Scene tree dock). + </member> + <member name="network/debug/remote_host" type="String" setter="" getter=""> + The address to listen to when starting the remote debugger. This can be set to [code]0.0.0.0[/code] to allow external clients to connect to the remote debugger (instead of restricting the remote debugger to connections from [code]localhost[/code]). + </member> + <member name="network/debug/remote_port" type="int" setter="" getter=""> + The port to listen to when starting the remote debugger. Godot will try to use port numbers above the configured number if the configured number is already taken by another application. + </member> + <member name="network/http_proxy/host" type="String" setter="" getter=""> + The host to use to contact the HTTP and HTTPS proxy in the editor (for the asset library and export template downloads). See also [member network/http_proxy/port]. + [b]Note:[/b] Godot currently doesn't automatically use system proxy settings, so you have to enter them manually here if needed. + </member> + <member name="network/http_proxy/port" type="int" setter="" getter=""> + The port number to use to contact the HTTP and HTTPS proxy in the editor (for the asset library and export template downloads). See also [member network/http_proxy/host]. + [b]Note:[/b] Godot currently doesn't automatically use system proxy settings, so you have to enter them manually here if needed. + </member> + <member name="network/ssl/editor_ssl_certificates" type="String" setter="" getter=""> + The SSL certificate bundle to use for HTTP requests made within the editor (e.g. from the AssetLib tab). If left empty, the [url=https://github.com/godotengine/godot/blob/master/thirdparty/certs/ca-certificates.crt]included Mozilla certificate bundle[/url] will be used. + </member> + <member name="project_manager/sorting_order" type="int" setter="" getter=""> + The sorting order to use in the project manager. When changing the sorting order in the project manager, this setting is set permanently in the editor settings. + </member> + <member name="run/auto_save/save_before_running" type="bool" setter="" getter=""> + If [code]true[/code], saves all scenes and scripts automatically before running the project. Setting this to [code]false[/code] prevents the editor from saving if there are no changes which can speed up the project startup slightly, but it makes it possible to run a project that has unsaved changes. (Unsaved changes will not be visible in the running project.) + </member> + <member name="run/output/always_clear_output_on_play" type="bool" setter="" getter=""> + If [code]true[/code], the editor will clear the Output panel when running the project. + </member> + <member name="run/output/always_close_output_on_stop" type="bool" setter="" getter=""> + If [code]true[/code], the editor will collapse the Output panel when stopping the project. + </member> + <member name="run/output/always_open_output_on_play" type="bool" setter="" getter=""> + If [code]true[/code], the editor will expand the Output panel when running the project. + </member> + <member name="run/output/font_size" type="int" setter="" getter=""> + The size of the font in the [b]Output[/b] panel at the bottom of the editor. This setting does not impact the font size of the script editor (see [member interface/editor/code_font_size]). + </member> + <member name="run/window_placement/rect" type="int" setter="" getter=""> + The window mode to use to display the project when starting the project from the editor. + </member> + <member name="run/window_placement/rect_custom_position" type="Vector2" setter="" getter=""> + The custom position to use when starting the project from the editor (in pixels from the top-left corner). Only effective if [member run/window_placement/rect] is set to [b]Custom Position[/b]. + </member> + <member name="run/window_placement/screen" type="int" setter="" getter=""> + The monitor to display the project on when starting the project from the editor. + </member> + <member name="text_editor/appearance/caret/caret_blink" type="bool" setter="" getter=""> + If [code]true[/code], makes the caret blink according to [member text_editor/appearance/caret/caret_blink_speed]. Disabling this setting can improve battery life on laptops if you spend long amounts of time in the script editor, since it will reduce the frequency at which the editor needs to be redrawn. + </member> + <member name="text_editor/appearance/caret/caret_blink_speed" type="float" setter="" getter=""> + The interval at which to blink the caret (in seconds). See also [member text_editor/appearance/caret/caret_blink]. + </member> + <member name="text_editor/appearance/caret/highlight_all_occurrences" type="bool" setter="" getter=""> + If [code]true[/code], highlights all occurrences of the currently selected text in the script editor. See also [member text_editor/theme/highlighting/word_highlighted_color]. + </member> + <member name="text_editor/appearance/caret/highlight_current_line" type="bool" setter="" getter=""> + If [code]true[/code], colors the background of the line the caret is currently on with [member text_editor/theme/highlighting/current_line_color]. + </member> + <member name="text_editor/appearance/caret/type" type="int" setter="" getter=""> + The shape of the caret to use in the script editor. [b]Line[/b] displays a vertical line to the left of the current character, whereas [b]Block[/b] displays a outline over the current character. + </member> + <member name="text_editor/appearance/guidelines/line_length_guideline_hard_column" type="int" setter="" getter=""> + The column at which to display a subtle line as a line length guideline for scripts. This should generally be greater than [member text_editor/appearance/guidelines/line_length_guideline_soft_column]. + </member> + <member name="text_editor/appearance/guidelines/line_length_guideline_soft_column" type="int" setter="" getter=""> + The column at which to display a [i]very[/i] subtle line as a line length guideline for scripts. This should generally be lower than [member text_editor/appearance/guidelines/line_length_guideline_hard_column]. + </member> + <member name="text_editor/appearance/guidelines/show_line_length_guidelines" type="bool" setter="" getter=""> + If [code]true[/code], displays line length guidelines to help you keep line lengths in check. See also [member text_editor/appearance/guidelines/line_length_guideline_soft_column] and [member text_editor/appearance/guidelines/line_length_guideline_hard_column]. + </member> + <member name="text_editor/appearance/gutters/highlight_type_safe_lines" type="bool" setter="" getter=""> + If [code]true[/code], highlights type-safe lines by displaying their line number color with [member text_editor/theme/highlighting/safe_line_number_color] instead of [member text_editor/theme/highlighting/line_number_color]. Type-safe lines are lines of code where the type of all variables is known at compile-time. These type-safe lines will run faster in Godot 4.0 and later thanks to typed instructions. + </member> + <member name="text_editor/appearance/gutters/line_numbers_zero_padded" type="bool" setter="" getter=""> + If [code]true[/code], displays line numbers with zero padding (e.g. [code]007[/code] instead of [code]7[/code]). + </member> + <member name="text_editor/appearance/gutters/show_bookmark_gutter" type="bool" setter="" getter=""> + If [code]true[/code], displays a gutter at the left containing icons for bookmarks. + </member> + <member name="text_editor/appearance/gutters/show_info_gutter" type="bool" setter="" getter=""> + If [code]true[/code], displays a gutter at the left containing icons for methods with signal connections. + </member> + <member name="text_editor/appearance/gutters/show_line_numbers" type="bool" setter="" getter=""> + If [code]true[/code], displays line numbers in the gutter at the left. + </member> + <member name="text_editor/appearance/lines/code_folding" type="bool" setter="" getter=""> + If [code]true[/code], displays the folding arrows next to indented code sections and allows code folding. If [code]false[/code], hides the folding arrows next to indented code sections and disallows code folding. + </member> + <member name="text_editor/appearance/lines/word_wrap" type="int" setter="" getter=""> + If [code]true[/code], wraps long lines over multiple lines to avoid horizontal scrolling. This is a display-only feature; it does not actually insert line breaks in your scripts. + </member> + <member name="text_editor/appearance/minimap/minimap_width" type="int" setter="" getter=""> + The width of the minimap in the script editor (in pixels). + </member> + <member name="text_editor/appearance/minimap/show_minimap" type="bool" setter="" getter=""> + If [code]true[/code], draws an overview of the script near the scroll bar. The minimap can be left-clicked to scroll directly to a location in an "absolute" manner. + </member> + <member name="text_editor/appearance/whitespace/draw_spaces" type="bool" setter="" getter=""> + If [code]true[/code], draws space characters as centered points. + </member> + <member name="text_editor/appearance/whitespace/draw_tabs" type="bool" setter="" getter=""> + If [code]true[/code], draws tab characters as chevrons. + </member> + <member name="text_editor/appearance/whitespace/line_spacing" type="int" setter="" getter=""> + The space to add between lines (in pixels). Greater line spacing can help improve readability at the cost of displaying less lines on screen. + </member> + <member name="text_editor/behavior/files/auto_reload_scripts_on_external_change" type="bool" setter="" getter=""> + If [code]true[/code], automatically reloads scripts in the editor when they have been modified and saved by external editors. + </member> + <member name="text_editor/behavior/files/autosave_interval_secs" type="int" setter="" getter=""> + If set to a value greater than [code]0[/code], automatically saves the current script following the specified interval (in seconds). This can be used to prevent data loss if the editor crashes. + </member> + <member name="text_editor/behavior/files/convert_indent_on_save" type="bool" setter="" getter=""> + If [code]true[/code], converts indentation to match the script editor's indentation settings when saving a script. See also [member text_editor/behavior/indent/type]. + </member> + <member name="text_editor/behavior/files/restore_scripts_on_load" type="bool" setter="" getter=""> + If [code]true[/code], reopens scripts that were opened in the last session when the editor is reopened on a given project. + </member> + <member name="text_editor/behavior/files/trim_trailing_whitespace_on_save" type="bool" setter="" getter=""> + If [code]true[/code], trims trailing whitespace when saving a script. Trailing whitespace refers to tab and space characters placed at the end of lines. Since these serve no practical purpose, they can and should be removed to make version control diffs less noisy. + </member> + <member name="text_editor/behavior/indent/auto_indent" type="bool" setter="" getter=""> + If [code]true[/code], automatically indents code when pressing the [kbd]Enter[/kbd] key based on blocks above the new line. + </member> + <member name="text_editor/behavior/indent/size" type="int" setter="" getter=""> + When using tab indentation, determines the length of each tab. When using space indentation, determines how many spaces are inserted when pressing [kbd]Tab[/kbd] and when automatic indentation is performed. + </member> + <member name="text_editor/behavior/indent/type" type="int" setter="" getter=""> + The indentation style to use (tabs or spaces). + [b]Note:[/b] The [url=https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_styleguide.html]GDScript style guide[/url] recommends using tabs for indentation. It is advised to change this setting only if you need to work on a project that currently uses spaces for indentation. + </member> + <member name="text_editor/behavior/navigation/drag_and_drop_selection" type="bool" setter="" getter=""> + If [code]true[/code], allows drag-and-dropping text in the script editor to move text. Disable this if you find yourself accidentally drag-and-dropping text in the script editor. + </member> + <member name="text_editor/behavior/navigation/move_caret_on_right_click" type="bool" setter="" getter=""> + If [code]true[/code], the caret will be moved when right-clicking somewhere in the script editor (like when left-clicking or middle-clicking). If [code]false[/code], the caret will only be moved when left-clicking or middle-clicking somewhere. + </member> + <member name="text_editor/behavior/navigation/scroll_past_end_of_file" type="bool" setter="" getter=""> + If [code]true[/code], allows scrolling past the end of the file. + </member> + <member name="text_editor/behavior/navigation/smooth_scrolling" type="bool" setter="" getter=""> + If [code]true[/code], allows scrolling in sub-line intervals and enables a smooth scrolling animation when using the mouse wheel to scroll. + [b]Note:[/b] [member text_editor/behavior/navigation/smooth_scrolling] currently behaves poorly in projects where [member ProjectSettings.physics/common/physics_ticks_per_second] has been increased significantly from its default value ([code]60[/code]). In this case, it is recommended to disable this setting. + </member> + <member name="text_editor/behavior/navigation/stay_in_script_editor_on_node_selected" type="bool" setter="" getter=""> + If [code]true[/code], prevents automatically switching between the Script and 2D/3D screens when selecting a node in the Scene tree dock. + </member> + <member name="text_editor/behavior/navigation/v_scroll_speed" type="int" setter="" getter=""> + The number of pixels to scroll with every mouse wheel increment. Higher values make the script scroll by faster when using the mouse wheel. + [b]Note:[/b] You can hold down [kbd]Alt[/kbd] while using the mouse wheel to temporarily scroll 5 times faster. + </member> + <member name="text_editor/completion/add_type_hints" type="bool" setter="" getter=""> + If [code]true[/code], adds static typing hints such as [code]-> void[/code] and [code]: int[/code] when performing method definition autocompletion. + </member> + <member name="text_editor/completion/auto_brace_complete" type="bool" setter="" getter=""> + If [code]true[/code], automatically completes braces when making use of code completion. + </member> + <member name="text_editor/completion/code_complete_delay" type="float" setter="" getter=""> + The delay in seconds after which autocompletion suggestions should be displayed when the user stops typing. + </member> + <member name="text_editor/completion/complete_file_paths" type="bool" setter="" getter=""> + If [code]true[/code], provides autocompletion suggestions for file paths in methods such as [code]load()[/code] and [code]preload()[/code]. + </member> + <member name="text_editor/completion/idle_parse_delay" type="float" setter="" getter=""> + The delay in seconds after which the script editor should check for errors when the user stops typing. + </member> + <member name="text_editor/completion/put_callhint_tooltip_below_current_line" type="bool" setter="" getter=""> + If [code]true[/code], the code completion tooltip will appear below the current line unless there is no space on screen below the current line. If [code]false[/code], the code completion tooltip will appear above the current line. + </member> + <member name="text_editor/completion/use_single_quotes" type="bool" setter="" getter=""> + If [code]true[/code], performs string autocompletion with single quotes. If [code]false[/code], performs string autocompletion with double quotes (which matches the [url=https://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/gdscript_styleguide.html]GDScript style guide[/url]). + </member> + <member name="text_editor/help/class_reference_examples" type="int" setter="" getter=""> + Controls which multi-line code blocks should be displayed in the editor help. This setting does not affect single-line code literals in the editor help. + </member> + <member name="text_editor/help/help_font_size" type="int" setter="" getter=""> + The font size to use for the editor help (built-in class reference). + </member> + <member name="text_editor/help/help_source_font_size" type="int" setter="" getter=""> + The font size to use for code samples in the editor help (built-in class reference). + </member> + <member name="text_editor/help/help_title_font_size" type="int" setter="" getter=""> + The font size to use for headings in the editor help (built-in class reference). + </member> + <member name="text_editor/help/show_help_index" type="bool" setter="" getter=""> + If [code]true[/code], displays a table of contents at the left of the editor help (at the location where the members overview would appear when editing a script). + </member> + <member name="text_editor/script_list/show_members_overview" type="bool" setter="" getter=""> + If [code]true[/code], displays an overview of the current script's member variables and functions at the left of the script editor. See also [member text_editor/script_list/sort_members_outline_alphabetically]. + </member> + <member name="text_editor/script_list/sort_members_outline_alphabetically" type="bool" setter="" getter=""> + If [code]true[/code], sorts the members outline (located at the left of the script editor) using alphabetical order. If [code]false[/code], sorts the members outline depending on the order in which members are found in the script. + [b]Note:[/b] Only effective if [member text_editor/script_list/show_members_overview] is [code]true[/code]. + </member> + <member name="text_editor/theme/color_theme" type="String" setter="" getter=""> + The syntax theme to use in the script editor. + You can save your own syntax theme from your current settings by using [b]File > Theme > Save As...[/b] at the top of the script editor. The syntax theme will then be available locally in the list of color themes. + You can find additional syntax themes to install in the [url=https://github.com/godotengine/godot-syntax-themes]godot-syntax-themes[/url] repository. + </member> + <member name="text_editor/theme/highlighting/background_color" type="Color" setter="" getter=""> + The script editor's background color. If set to a translucent color, the editor theme's base color will be visible behind. + </member> + <member name="text_editor/theme/highlighting/base_type_color" type="Color" setter="" getter=""> + The script editor's base type color (used for types like [Vector2], [Vector3], ...). + </member> + <member name="text_editor/theme/highlighting/bookmark_color" type="Color" setter="" getter=""> + The script editor's bookmark icon color (displayed in the gutter). + </member> + <member name="text_editor/theme/highlighting/brace_mismatch_color" type="Color" setter="" getter=""> + The script editor's brace mismatch color. Used when the caret is currently on a mismatched brace, parenthesis or bracket character. + </member> + <member name="text_editor/theme/highlighting/breakpoint_color" type="Color" setter="" getter=""> + The script editor's breakpoint icon color (displayed in the gutter). + </member> + <member name="text_editor/theme/highlighting/caret_background_color" type="Color" setter="" getter=""> + The script editor's caret background color. + [b]Note:[/b] This setting has no effect as it's currently unused. + </member> + <member name="text_editor/theme/highlighting/caret_color" type="Color" setter="" getter=""> + The script editor's caret color. + </member> + <member name="text_editor/theme/highlighting/code_folding_color" type="Color" setter="" getter=""> + The script editor's color for the code folding icon (displayed in the gutter). + </member> + <member name="text_editor/theme/highlighting/comment_color" type="Color" setter="" getter=""> + The script editor's comment color. + [b]Note:[/b] In GDScript, unlike Python, multiline strings are not considered to be comments, and will use the string highlighting color instead. + </member> + <member name="text_editor/theme/highlighting/completion_background_color" type="Color" setter="" getter=""> + The script editor's autocompletion box background color. + </member> + <member name="text_editor/theme/highlighting/completion_existing_color" type="Color" setter="" getter=""> + The script editor's autocompletion box background color to highlight existing characters in the completion results. This should be a translucent color so that [member text_editor/theme/highlighting/completion_selected_color] can be seen behind. + </member> + <member name="text_editor/theme/highlighting/completion_font_color" type="Color" setter="" getter=""> + The script editor's autocompletion box text color. + </member> + <member name="text_editor/theme/highlighting/completion_scroll_color" type="Color" setter="" getter=""> + The script editor's autocompletion box scroll bar color. + </member> + <member name="text_editor/theme/highlighting/completion_scroll_hovered_color" type="Color" setter="" getter=""> + The script editor's autocompletion box scroll bar color when hovered or pressed with the mouse. + </member> + <member name="text_editor/theme/highlighting/completion_selected_color" type="Color" setter="" getter=""> + The script editor's autocompletion box background color for the currently selected line. + </member> + <member name="text_editor/theme/highlighting/control_flow_keyword_color" type="Color" setter="" getter=""> + The script editor's control flow keyword color (used for keywords like [code]if[/code], [code]for[/code], [code]return[/code], ...). + </member> + <member name="text_editor/theme/highlighting/current_line_color" type="Color" setter="" getter=""> + The script editor's background color for the line the caret is currently on. This should be set to a translucent color so that it can display on top of other line color modifiers such as [member text_editor/theme/highlighting/mark_color]. + </member> + <member name="text_editor/theme/highlighting/engine_type_color" type="Color" setter="" getter=""> + The script editor's engine type color ([Vector2], [Vector3], [Color], ...). + </member> + <member name="text_editor/theme/highlighting/executing_line_color" type="Color" setter="" getter=""> + The script editor's color for the debugger's executing line icon (displayed in the gutter). + </member> + <member name="text_editor/theme/highlighting/function_color" type="Color" setter="" getter=""> + The script editor's function call color. + [b]Note:[/b] When using the GDScript syntax highlighter, this is replaced by the function declaration color configured in the syntax theme for function declarations (e.g. [code]func _ready():[/code]). + </member> + <member name="text_editor/theme/highlighting/keyword_color" type="Color" setter="" getter=""> + The script editor's non-control flow keyword color (used for keywords like [code]var[/code], [code]func[/code], some built-in methods, ...). + </member> + <member name="text_editor/theme/highlighting/line_length_guideline_color" type="Color" setter="" getter=""> + The script editor's color for the line length guideline. The "hard" line length guideline will be drawn with this color, whereas the "soft" line length guideline will be drawn with an opacity twice as low. + </member> + <member name="text_editor/theme/highlighting/line_number_color" type="Color" setter="" getter=""> + The script editor's color for line numbers. See also [member text_editor/theme/highlighting/safe_line_number_color]. + </member> + <member name="text_editor/theme/highlighting/mark_color" type="Color" setter="" getter=""> + The script editor's background color for lines with errors. This should be set to a translucent color so that it can display on top of other line color modifiers such as [member text_editor/theme/highlighting/current_line_color]. + </member> + <member name="text_editor/theme/highlighting/member_variable_color" type="Color" setter="" getter=""> + The script editor's color for member variables on objects (e.g. [code]self.some_property[/code]). + [b]Note:[/b] This color is not used for local variable declaration and access. + </member> + <member name="text_editor/theme/highlighting/number_color" type="Color" setter="" getter=""> + The script editor's color for numbers (integer and floating-point). + </member> + <member name="text_editor/theme/highlighting/safe_line_number_color" type="Color" setter="" getter=""> + The script editor's color for type-safe line numbers. See also [member text_editor/theme/highlighting/line_number_color]. + [b]Note:[/b] Only displayed if [member text_editor/appearance/gutters/highlight_type_safe_lines] is [code]true[/code]. + </member> + <member name="text_editor/theme/highlighting/search_result_border_color" type="Color" setter="" getter=""> + The script editor's color for the border of search results. This border helps bring further attention to the search result. Set this color's opacity to 0 to disable the border. + </member> + <member name="text_editor/theme/highlighting/search_result_color" type="Color" setter="" getter=""> + The script editor's background color for search results. + </member> + <member name="text_editor/theme/highlighting/selection_color" type="Color" setter="" getter=""> + The script editor's background color for the currently selected text. + </member> + <member name="text_editor/theme/highlighting/string_color" type="Color" setter="" getter=""> + The script editor's color for strings (single-line and multi-line). + </member> + <member name="text_editor/theme/highlighting/symbol_color" type="Color" setter="" getter=""> + The script editor's color for operators ([code]( ) [ ] { } + - * /[/code], ...). + </member> + <member name="text_editor/theme/highlighting/text_color" type="Color" setter="" getter=""> + The script editor's color for text not highlighted by any syntax highlighting rule. + </member> + <member name="text_editor/theme/highlighting/text_selected_color" type="Color" setter="" getter=""> + The script editor's background color for text. This should be set to a translucent color so that it can display on top of other line color modifiers such as [member text_editor/theme/highlighting/current_line_color]. + </member> + <member name="text_editor/theme/highlighting/user_type_color" type="Color" setter="" getter=""> + The script editor's color for user-defined types (using [code]@class_name[/code]). + </member> + <member name="text_editor/theme/highlighting/word_highlighted_color" type="Color" setter="" getter=""> + The script editor's color for words highlighted by selecting them. Only visible if [member text_editor/appearance/caret/highlight_all_occurrences] is [code]true[/code]. + </member> + </members> <signals> <signal name="settings_changed"> <description> diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index 506992e3af..36dfee833b 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -151,6 +151,12 @@ [/codeblocks] </description> </method> + <method name="get_write_movie_path" qualifiers="const"> + <return type="String" /> + <description> + Returns the path to the [MovieWriter]'s output file, or an empty string if the engine wasn't started in Movie Maker mode. This path can be absolute or relative depending on how the user specified it. + </description> + </method> <method name="has_singleton" qualifiers="const"> <return type="bool" /> <argument index="0" name="name" type="StringName" /> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 9da360915b..f662a07825 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -97,7 +97,7 @@ Blend factor between the fog's color and the color of the background [Sky]. Must have [member background_mode] set to [constant BG_SKY]. This is useful to simulate [url=https://en.wikipedia.org/wiki/Aerial_perspective]aerial perspective[/url] in large scenes with low density fog. However, it is not very useful for high-density fog, as the sky will shine through. When set to [code]1.0[/code], the fog color comes completely from the [Sky]. If set to [code]0.0[/code], aerial perspective is disabled. </member> - <member name="fog_density" type="float" setter="set_fog_density" getter="get_fog_density" default="0.001"> + <member name="fog_density" type="float" setter="set_fog_density" getter="get_fog_density" default="0.01"> The exponential fog density to use. Higher values result in a more dense fog. </member> <member name="fog_enabled" type="bool" setter="set_fog_enabled" getter="is_fog_enabled" default="false"> @@ -109,7 +109,7 @@ <member name="fog_height_density" type="float" setter="set_fog_height_density" getter="get_fog_height_density" default="0.0"> The density used to increase fog as height decreases. To make fog increase as height increases, use a negative value. </member> - <member name="fog_light_color" type="Color" setter="set_fog_light_color" getter="get_fog_light_color" default="Color(0.5, 0.6, 0.7, 1)"> + <member name="fog_light_color" type="Color" setter="set_fog_light_color" getter="get_fog_light_color" default="Color(0.518, 0.553, 0.608, 1)"> The fog's color. </member> <member name="fog_light_energy" type="float" setter="set_fog_light_energy" getter="get_fog_light_energy" default="1.0"> @@ -320,8 +320,9 @@ <member name="volumetric_fog_enabled" type="bool" setter="set_volumetric_fog_enabled" getter="is_volumetric_fog_enabled" default="false"> Enables the volumetric fog effect. Volumetric fog uses a screen-aligned froxel buffer to calculate accurate volumetric scattering in the short to medium range. Volumetric fog interacts with [FogVolume]s and lights to calculate localized and global fog. Volumetric fog uses a PBR single-scattering model based on extinction, scattering, and emission which it exposes to users as density, albedo, and emission. </member> - <member name="volumetric_fog_gi_inject" type="float" setter="set_volumetric_fog_gi_inject" getter="get_volumetric_fog_gi_inject" default="0.0"> - Scales the strength of Global Illumination used in the volumetric fog. A value of [code]0[/code] means that Global Illumination will not impact the volumetric fog. + <member name="volumetric_fog_gi_inject" type="float" setter="set_volumetric_fog_gi_inject" getter="get_volumetric_fog_gi_inject" default="1.0"> + Scales the strength of Global Illumination used in the volumetric fog. A value of [code]0.0[/code] means that Global Illumination will not impact the volumetric fog. + [b]Note:[/b] Only [VoxelGI] and SDFGI ([member Environment.sdfgi_enabled]) are taken into account when using [member volumetric_fog_gi_inject]. Global illumination from [LightmapGI], [ReflectionProbe] and SSIL (see [member ssil_enabled]) will be ignored by volumetric fog. </member> <member name="volumetric_fog_length" type="float" setter="set_volumetric_fog_length" getter="get_volumetric_fog_length" default="64.0"> The distance over which the volumetric fog is computed. Increase to compute fog over a greater range, decrease to add more detail when a long range is not needed. For best quality fog, keep this as low as possible. diff --git a/doc/classes/File.xml b/doc/classes/File.xml index 0b4a8fa46e..3a2776ff21 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -115,9 +115,10 @@ </method> <method name="get_as_text" qualifiers="const"> <return type="String" /> + <argument index="0" name="skip_cr" type="bool" default="false" /> <description> - Returns the whole file as a [String]. - Text is interpreted as being UTF-8 encoded. + Returns the whole file as a [String]. Text is interpreted as being UTF-8 encoded. + If [code]skip_cr[/code] is [code]true[/code], carriage return characters ([code]\r[/code], CR) will be ignored when parsing the UTF-8, so that only line feed characters ([code]\n[/code], LF) represent a new line (Unix convention). </description> </method> <method name="get_buffer" qualifiers="const"> diff --git a/doc/classes/FontFile.xml b/doc/classes/FontFile.xml index aaf871d55a..dc2cbdde63 100644 --- a/doc/classes/FontFile.xml +++ b/doc/classes/FontFile.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="FontFile" inherits="Font" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - FontFile source data and prerendered glyph cache, imported from dynamic or bitmap font. + Font source data and prerendered glyph cache, imported from dynamic or bitmap font. </brief_description> <description> [FontFile] contains a set of glyphs to represent Unicode characters imported from a font file, as well as a cache of rasterized glyphs, and a set of fallback [Font]s to use. diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml index 53894bad87..e60ab094c6 100644 --- a/doc/classes/GPUParticles2D.xml +++ b/doc/classes/GPUParticles2D.xml @@ -63,8 +63,8 @@ <member name="lifetime" type="float" setter="set_lifetime" getter="get_lifetime" default="1.0"> Amount of time each particle will exist. </member> - <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> - If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. + <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="false"> + If [code]true[/code], particles use the parent node's coordinate space (known as local coordinates). This will cause particles to move and rotate along the [GPUParticles2D] node (and its parents) when it is moved or rotated. If [code]false[/code], particles use global coordinates; they will not move or rotate along the [GPUParticles2D] node (and its parents) when it is moved or rotated. </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false"> If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end. diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml index c4bd18db69..b415c56154 100644 --- a/doc/classes/GPUParticles3D.xml +++ b/doc/classes/GPUParticles3D.xml @@ -95,8 +95,8 @@ <member name="lifetime" type="float" setter="set_lifetime" getter="get_lifetime" default="1.0"> Amount of time each particle will exist. </member> - <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> - If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. + <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="false"> + If [code]true[/code], particles use the parent node's coordinate space (known as local coordinates). This will cause particles to move and rotate along the [GPUParticles3D] node (and its parents) when it is moved or rotated. If [code]false[/code], particles use global coordinates; they will not move or rotate along the [GPUParticles3D] node (and its parents) when it is moved or rotated. </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false"> If [code]true[/code], only [code]amount[/code] particles will be emitted. diff --git a/doc/classes/GPUParticlesCollisionSDF3D.xml b/doc/classes/GPUParticlesCollisionSDF3D.xml index c9af07288e..bc8b3c7c11 100644 --- a/doc/classes/GPUParticlesCollisionSDF3D.xml +++ b/doc/classes/GPUParticlesCollisionSDF3D.xml @@ -13,7 +13,27 @@ </description> <tutorials> </tutorials> + <methods> + <method name="get_bake_mask_value" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="layer_number" type="int" /> + <description> + Returns whether or not the specified layer of the [member bake_mask] is enabled, given a [code]layer_number[/code] between 1 and 32. + </description> + </method> + <method name="set_bake_mask_value"> + <return type="void" /> + <argument index="0" name="layer_number" type="int" /> + <argument index="1" name="value" type="bool" /> + <description> + Based on [code]value[/code], enables or disables the specified layer in the [member bake_mask], given a [code]layer_number[/code] between 1 and 32. + </description> + </method> + </methods> <members> + <member name="bake_mask" type="int" setter="set_bake_mask" getter="get_bake_mask" default="4294967295"> + The visual layers to account for when baking the particle collision SDF. Only [MeshInstance3D]s whose [member VisualInstance3D.layers] match with this [member bake_mask] will be included in the generated particle collision SDF. By default, all objects are taken into account for the particle collision SDF baking. + </member> <member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3(1, 1, 1)"> The collision SDF's extents in 3D units. To improve SDF quality, the [member extents] should be set as small as possible while covering the parts of the scene you need. </member> diff --git a/doc/classes/Geometry2D.xml b/doc/classes/Geometry2D.xml index b84e221d1c..a4cfa1ddff 100644 --- a/doc/classes/Geometry2D.xml +++ b/doc/classes/Geometry2D.xml @@ -126,7 +126,7 @@ <return type="Dictionary" /> <argument index="0" name="sizes" type="PackedVector2Array" /> <description> - Given an array of [Vector2]s representing tiles, builds an atlas. The returned dictionary has two keys: [code]points[/code] is a vector of [Vector2] that specifies the positions of each tile, [code]size[/code] contains the overall size of the whole atlas as [Vector2]. + Given an array of [Vector2]s representing tiles, builds an atlas. The returned dictionary has two keys: [code]points[/code] is an array of [Vector2] that specifies the positions of each tile, [code]size[/code] contains the overall size of the whole atlas as [Vector2]. </description> </method> <method name="merge_polygons"> @@ -188,6 +188,16 @@ Returns if [code]point[/code] is inside the triangle specified by [code]a[/code], [code]b[/code] and [code]c[/code]. </description> </method> + <method name="segment_intersects_circle"> + <return type="float" /> + <argument index="0" name="segment_from" type="Vector2" /> + <argument index="1" name="segment_to" type="Vector2" /> + <argument index="2" name="circle_position" type="Vector2" /> + <argument index="3" name="circle_radius" type="float" /> + <description> + Given the 2D segment ([code]segment_from[/code], [code]segment_to[/code]), returns the position on the segment (as a number between 0 and 1) at which the segment hits the circle that is located at position [code]circle_position[/code] and has radius [code]circle_radius[/code]. If the segment does not intersect the circle, -1 is returned (this is also the case if the line extending the segment would intersect the circle, but the segment does not). + </description> + </method> <method name="segment_intersects_segment"> <return type="Variant" /> <argument index="0" name="from_a" type="Vector2" /> diff --git a/doc/classes/GeometryInstance3D.xml b/doc/classes/GeometryInstance3D.xml index c803f43fb0..365efa6761 100644 --- a/doc/classes/GeometryInstance3D.xml +++ b/doc/classes/GeometryInstance3D.xml @@ -9,7 +9,7 @@ <tutorials> </tutorials> <methods> - <method name="get_shader_instance_uniform" qualifiers="const"> + <method name="get_instance_shader_uniform" qualifiers="const"> <return type="Variant" /> <argument index="0" name="uniform" type="StringName" /> <description> @@ -22,7 +22,7 @@ Overrides the bounding box of this node with a custom one. To remove it, set an [AABB] with all fields set to zero. </description> </method> - <method name="set_shader_instance_uniform"> + <method name="set_instance_shader_uniform"> <return type="void" /> <argument index="0" name="uniform" type="StringName" /> <argument index="1" name="value" type="Variant" /> diff --git a/doc/classes/Gradient.xml b/doc/classes/Gradient.xml index 89c968cc9e..8c5373216a 100644 --- a/doc/classes/Gradient.xml +++ b/doc/classes/Gradient.xml @@ -5,6 +5,7 @@ </brief_description> <description> Given a set of colors, this resource will interpolate them in order. This means that if you have color 1, color 2 and color 3, the gradient will interpolate from color 1 to color 2 and from color 2 to color 3. The gradient will initially have 2 colors (black and white), one (black) at gradient lower offset 0 and the other (white) at the gradient higher offset 1. + See also [Curve] which supports more complex easing methods, but does not support colors. </description> <tutorials> </tutorials> diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index 965dbe7449..33145dccd0 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -55,6 +55,29 @@ [/codeblock] </description> </method> + <method name="_is_node_hover_valid" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="from" type="StringName" /> + <argument index="1" name="from_slot" type="int" /> + <argument index="2" name="to" type="StringName" /> + <argument index="3" name="to_slot" type="int" /> + <description> + This virtual method can be used to insert additional error detection while the user is dragging a connection over a valid port. + Return [code]true[/code] if the connection is indeed valid or return [code]false[/code] if the connection is impossible. If the connection is impossible, no snapping to the port and thus no connection request to that port will happen. + In this example a connection to same node is suppressed: + [codeblocks] + [gdscript] + func _is_node_hover_valid(from, from_slot, to, to_slot): + return from != to + [/gdscript] + [csharp] + public override bool _IsNodeHoverValid(String from, int fromSlot, String to, int toSlot) { + return from != to; + } + [/csharp] + [/codeblocks] + </description> + </method> <method name="add_valid_connection_type"> <return type="void" /> <argument index="0" name="from_type" type="int" /> diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml index 5a9d12d01b..fb437b6d8e 100644 --- a/doc/classes/HTTPClient.xml +++ b/doc/classes/HTTPClient.xml @@ -4,7 +4,8 @@ Low-level hyper-text transfer protocol client. </brief_description> <description> - Hyper-text transfer protocol client (sometimes called "User Agent"). Used to make HTTP requests to download web content, upload files and other data or to communicate with various services, among other use cases. [b]See the [HTTPRequest] node for a higher-level alternative.[/b] + Hyper-text transfer protocol client (sometimes called "User Agent"). Used to make HTTP requests to download web content, upload files and other data or to communicate with various services, among other use cases. + See the [HTTPRequest] node for a higher-level alternative. [b]Note:[/b] This client only needs to connect to a host once (see [method connect_to_host]) to send multiple requests. Because of this, methods that take URLs usually take just the part after the host instead of the full URL, as the client is already connected to a host. See [method request] for a full example and to get started. A [HTTPClient] should be reused between multiple requests or to connect to different hosts instead of creating one client per request. Supports SSL and SSL server certificate verification. HTTP status codes in the 2xx range indicate success, 3xx redirection (i.e. "try again, but over here"), 4xx something was wrong with the request, and 5xx something went wrong on the server's side. For more information on HTTP, see https://developer.mozilla.org/en-US/docs/Web/HTTP (or read RFC 2616 to get it straight from the source: https://tools.ietf.org/html/rfc2616). diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index a927345e79..754d1ae68a 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -250,7 +250,7 @@ </description> </method> <method name="get_size" qualifiers="const"> - <return type="Vector2" /> + <return type="Vector2i" /> <description> Returns the image's size (width and height). </description> diff --git a/doc/classes/ImporterMesh.xml b/doc/classes/ImporterMesh.xml index 00601cec75..201c0ddd38 100644 --- a/doc/classes/ImporterMesh.xml +++ b/doc/classes/ImporterMesh.xml @@ -30,7 +30,7 @@ <description> Creates a new surface, analogous to [method ArrayMesh.add_surface_from_arrays]. Surfaces are created to be rendered using a [code]primitive[/code], which may be any of the types defined in [enum Mesh.PrimitiveType]. (As a note, when using indices, it is recommended to only use points, lines, or triangles.) [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface. - The [code]arrays[/code] argument is an array of arrays. See [enum Mesh.ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array or be empty, except for [constant Mesh.ARRAY_INDEX] if it is used. + The [code]arrays[/code] argument is an array of arrays. See [enum Mesh.ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array (or be an exact multiple of the vertex array's length, when multiple elements of a sub-array correspond to a single vertex) or be empty, except for [constant Mesh.ARRAY_INDEX] if it is used. </description> </method> <method name="clear"> diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index e73021ead4..796a80873f 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -354,9 +354,11 @@ <return type="void" /> <argument index="0" name="duration_ms" type="int" default="500" /> <description> - Vibrate Android and iOS devices. + Vibrate handheld devices. + [b]Note:[/b] This method is implemented on Android, iOS, and HTML5. [b]Note:[/b] For Android, it requires enabling the [code]VIBRATE[/code] permission in the export preset. [b]Note:[/b] For iOS, specifying the duration is supported in iOS 13 and later. + [b]Note:[/b] Some web browsers such as Safari and Firefox for Android do not support this method. </description> </method> <method name="warp_mouse"> diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 15c97b0838..97ee946acd 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -445,7 +445,7 @@ <theme_item name="font_selected_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)"> Text [Color] used when the item is selected. </theme_item> - <theme_item name="guide_color" data_type="color" type="Color" default="Color(0, 0, 0, 0.1)"> + <theme_item name="guide_color" data_type="color" type="Color" default="Color(0.7, 0.7, 0.7, 0.25)"> [Color] of the guideline. The guideline is a line drawn between each row of items. </theme_item> <theme_item name="h_separation" data_type="constant" type="int" default="4"> diff --git a/doc/classes/Label3D.xml b/doc/classes/Label3D.xml index 2c3c27079a..5ba0a2d79a 100644 --- a/doc/classes/Label3D.xml +++ b/doc/classes/Label3D.xml @@ -79,7 +79,7 @@ </member> <member name="outline_render_priority" type="int" setter="set_outline_render_priority" getter="get_outline_render_priority" default="-1"> Sets the render priority for the text outline. Higher priority objects will be sorted in front of lower priority objects. - [b]Node:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). + [b]Note:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). [b]Note:[/b] This only applies to sorting of transparent objects. This will not impact how transparent objects are sorted relative to opaque objects. This is because opaque objects are not sorted, while transparent objects are sorted from back to front (subject to priority). </member> <member name="outline_size" type="int" setter="set_outline_size" getter="get_outline_size" default="0"> @@ -90,7 +90,7 @@ </member> <member name="render_priority" type="int" setter="set_render_priority" getter="get_render_priority" default="0"> Sets the render priority for the text. Higher priority objects will be sorted in front of lower priority objects. - [b]Node:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). + [b]Note:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). [b]Note:[/b] This only applies to sorting of transparent objects. This will not impact how transparent objects are sorted relative to opaque objects. This is because opaque objects are not sorted, while transparent objects are sorted from back to front (subject to priority). </member> <member name="shaded" type="bool" setter="set_draw_flag" getter="get_draw_flag" default="false"> @@ -126,7 +126,7 @@ If set, lights in the environment affect the label. </constant> <constant name="FLAG_DOUBLE_SIDED" value="1" enum="DrawFlags"> - If set, text can be seen from the back as well. If not, the texture is invisible when looking at it from behind. + If set, text can be seen from the back as well. If not, the text is invisible when looking at it from behind. </constant> <constant name="FLAG_DISABLE_DEPTH_TEST" value="2" enum="DrawFlags"> Disables the depth test, so this object is drawn on top of all others. However, objects drawn after it in the draw order may cover it. diff --git a/doc/classes/LabelSettings.xml b/doc/classes/LabelSettings.xml index 227313d3b3..aa972f2cf3 100644 --- a/doc/classes/LabelSettings.xml +++ b/doc/classes/LabelSettings.xml @@ -9,21 +9,21 @@ <members> <member name="font" type="Font" setter="set_font" getter="get_font"> </member> - <member name="font_color" type="Color" setter="set_font_color" getter="get_font_color" default="Color(0.875, 0.875, 0.875, 1)"> + <member name="font_color" type="Color" setter="set_font_color" getter="get_font_color" default="Color(1, 1, 1, 1)"> </member> <member name="font_size" type="int" setter="set_font_size" getter="get_font_size" default="16"> </member> - <member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="0.0"> + <member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="3.0"> </member> <member name="outline_color" type="Color" setter="set_outline_color" getter="get_outline_color" default="Color(1, 1, 1, 1)"> </member> <member name="outline_size" type="int" setter="set_outline_size" getter="get_outline_size" default="0"> </member> - <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color(1, 1, 1, 1)"> + <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color(0, 0, 0, 0)"> </member> <member name="shadow_offset" type="Vector2" setter="set_shadow_offset" getter="get_shadow_offset" default="Vector2(1, 1)"> </member> - <member name="shadow_size" type="int" setter="set_shadow_size" getter="get_shadow_size" default="0"> + <member name="shadow_size" type="int" setter="set_shadow_size" getter="get_shadow_size" default="1"> </member> </members> </class> diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index 0ebd83c882..46c3e57547 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -37,13 +37,12 @@ [b]Note:[/b] Only effective for [OmniLight3D] and [SpotLight3D]. </member> <member name="distance_fade_length" type="float" setter="set_distance_fade_length" getter="get_distance_fade_length" default="10.0"> - Distance over which the light fades. The light's energy is progressively reduced over this distance and is completely invisible at the end. + Distance over which the light and its shadow fades. The light's energy and shadow's opacity is progressively reduced over this distance and is completely invisible at the end. [b]Note:[/b] Only effective for [OmniLight3D] and [SpotLight3D]. </member> <member name="distance_fade_shadow" type="float" setter="set_distance_fade_shadow" getter="get_distance_fade_shadow" default="50.0"> The distance from the camera at which the light's shadow cuts off (in 3D units). Set this to a value lower than [member distance_fade_begin] + [member distance_fade_length] to further improve performance, as shadow rendering is often more expensive than light rendering itself. [b]Note:[/b] Only effective for [OmniLight3D] and [SpotLight3D], and only when [member shadow_enabled] is [code]true[/code]. - [b]Note:[/b] Due to a rendering engine limitation, shadows will be disabled instantly instead of fading smoothly according to [member distance_fade_length]. This may result in visible pop-in depending on the scene topography. </member> <member name="editor_only" type="bool" setter="set_editor_only" getter="is_editor_only" default="false"> If [code]true[/code], the light only appears in the editor and will not be visible at runtime. @@ -95,6 +94,9 @@ <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_opacity" type="float" setter="set_param" getter="get_param" default="1.0"> + The opacity to use when rendering the light's shadow map. Values lower than [code]1.0[/code] make the light appear through shadows. This can be used to fake global illumination at a low performance cost. + </member> <member name="shadow_reverse_cull_face" type="bool" setter="set_shadow_reverse_cull_face" getter="get_shadow_reverse_cull_face" default="false"> If [code]true[/code], reverses the backface culling of the mesh. This can be useful when you have a flat mesh that has a light behind it. If you need to cast a shadow on both sides of the mesh, set the mesh to use double-sided shadows with [constant GeometryInstance3D.SHADOW_CASTING_SETTING_DOUBLE_SIDED]. </member> @@ -150,15 +152,19 @@ <constant name="PARAM_SHADOW_PANCAKE_SIZE" value="15" enum="Param"> Constant for accessing [member DirectionalLight3D.directional_shadow_pancake_size]. </constant> - <constant name="PARAM_SHADOW_BLUR" value="16" enum="Param"> + <constant name="PARAM_SHADOW_OPACITY" value="16" enum="Param"> + Constant for accessing [member shadow_opacity]. + </constant> + <constant name="PARAM_SHADOW_BLUR" value="17" enum="Param"> Constant for accessing [member shadow_blur]. </constant> - <constant name="PARAM_SHADOW_VOLUMETRIC_FOG_FADE" value="17" enum="Param"> + <constant name="PARAM_SHADOW_VOLUMETRIC_FOG_FADE" value="18" enum="Param"> + Constant for accessing [member shadow_fog_fade]. </constant> - <constant name="PARAM_TRANSMITTANCE_BIAS" value="18" enum="Param"> + <constant name="PARAM_TRANSMITTANCE_BIAS" value="19" enum="Param"> Constant for accessing [member shadow_transmittance_bias]. </constant> - <constant name="PARAM_MAX" value="19" enum="Param"> + <constant name="PARAM_MAX" value="20" enum="Param"> Represents the size of the [enum Param] enum. </constant> <constant name="BAKE_DISABLED" value="0" enum="BakeMode"> diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index 84471bafc0..2ff13a676b 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -246,6 +246,9 @@ <member name="virtual_keyboard_enabled" type="bool" setter="set_virtual_keyboard_enabled" getter="is_virtual_keyboard_enabled" default="true"> If [code]true[/code], the native virtual keyboard is shown when focused on platforms that support it. </member> + <member name="virtual_keyboard_type" type="int" setter="set_virtual_keyboard_type" getter="get_virtual_keyboard_type" enum="LineEdit.VirtualKeyboardType" default="0"> + Specifies the type of virtual keyboard to show. + </member> </members> <signals> <signal name="text_change_rejected"> @@ -356,6 +359,31 @@ <constant name="MENU_MAX" value="28" enum="MenuItems"> Represents the size of the [enum MenuItems] enum. </constant> + <constant name="KEYBOARD_TYPE_DEFAULT" value="0" enum="VirtualKeyboardType"> + Default text virtual keyboard. + </constant> + <constant name="KEYBOARD_TYPE_MULTILINE" value="1" enum="VirtualKeyboardType"> + Multiline virtual keyboard. + </constant> + <constant name="KEYBOARD_TYPE_NUMBER" value="2" enum="VirtualKeyboardType"> + Virtual number keypad, useful for PIN entry. + </constant> + <constant name="KEYBOARD_TYPE_NUMBER_DECIMAL" value="3" enum="VirtualKeyboardType"> + Virtual number keypad, useful for entering fractional numbers. + </constant> + <constant name="KEYBOARD_TYPE_PHONE" value="4" enum="VirtualKeyboardType"> + Virtual phone number keypad. + </constant> + <constant name="KEYBOARD_TYPE_EMAIL_ADDRESS" value="5" enum="VirtualKeyboardType"> + Virtual keyboard with additional keys to assist with typing email addresses. + </constant> + <constant name="KEYBOARD_TYPE_PASSWORD" value="6" enum="VirtualKeyboardType"> + Virtual keyboard for entering a password. On most platforms, this should disable autocomplete and autocapitalization. + [b]Note:[/b] This is not supported on HTML5. Instead, this behaves identically to [constant KEYBOARD_TYPE_DEFAULT]. + </constant> + <constant name="KEYBOARD_TYPE_URL" value="7" enum="VirtualKeyboardType"> + Virtual keyboard with additional keys to assist with typing URLs. + </constant> </constants> <theme_items> <theme_item name="caret_color" data_type="color" type="Color" default="Color(0.95, 0.95, 0.95, 1)"> diff --git a/doc/classes/MeshInstance3D.xml b/doc/classes/MeshInstance3D.xml index f368190a29..24f1f9918b 100644 --- a/doc/classes/MeshInstance3D.xml +++ b/doc/classes/MeshInstance3D.xml @@ -4,7 +4,7 @@ Node that instances meshes into a scenario. </brief_description> <description> - MeshInstance3D is a node that takes a [Mesh] resource and adds it to the current scenario by creating an instance of it. This is the class most often used render 3D geometry and can be used to instance a single [Mesh] in many places. This allows reuse of geometry which can save on resources. When a [Mesh] has to be instantiated more than thousands of times at close proximity, consider using a [MultiMesh] in a [MultiMeshInstance3D] instead. + MeshInstance3D is a node that takes a [Mesh] resource and adds it to the current scenario by creating an instance of it. This is the class most often used render 3D geometry and can be used to instance a single [Mesh] in many places. This allows reusing geometry, which can save on resources. When a [Mesh] has to be instantiated more than thousands of times at close proximity, consider using a [MultiMesh] in a [MultiMeshInstance3D] instead. </description> <tutorials> <link title="3D Material Testers Demo">https://godotengine.org/asset-library/asset/123</link> diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml index 9d8f1e1e5d..3431a3347b 100644 --- a/doc/classes/MultiMesh.xml +++ b/doc/classes/MultiMesh.xml @@ -54,7 +54,7 @@ <argument index="1" name="color" type="Color" /> <description> Sets the color of a specific instance by [i]multiplying[/i] the mesh's existing vertex colors. - For the color to take effect, ensure that [member use_colors] is [code]true[/code] on the [MultiMesh] and [member BaseMaterial3D.vertex_color_use_as_albedo] is [code]true[/code] on the material. + For the color to take effect, ensure that [member use_colors] is [code]true[/code] on the [MultiMesh] and [member BaseMaterial3D.vertex_color_use_as_albedo] is [code]true[/code] on the material. If the color doesn't look as expected, make sure the material's albedo color is set to pure white ([code]Color(1, 1, 1)[/code]). </description> </method> <method name="set_instance_custom_data"> diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml index 059d147979..06658bf004 100644 --- a/doc/classes/MultiplayerAPI.xml +++ b/doc/classes/MultiplayerAPI.xml @@ -1,88 +1,108 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="MultiplayerAPI" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - High-level multiplayer API. + High-level multiplayer API interface. </brief_description> <description> - This class implements the high-level multiplayer API. See also [MultiplayerPeer]. - By default, [SceneTree] has a reference to this class that is used to provide multiplayer capabilities (i.e. RPCs) across the whole scene. + Base class for high-level multiplayer API implementations. See also [MultiplayerPeer]. + By default, [SceneTree] has a reference to an implementation of this class and uses it to provide multiplayer capabilities (i.e. RPCs) across the whole scene. It is possible to override the MultiplayerAPI instance used by specific tree branches by calling the [method SceneTree.set_multiplayer] method, effectively allowing to run both client and server in the same scene. - [b]Note:[/b] The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice. - [b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android. + It is also possible to extend or replace the default implementation via scripting or native extensions. See [MultiplayerAPIExtension] for details about extensions, [SceneMultiplayer] for the details about the default implementation. </description> <tutorials> </tutorials> <methods> - <method name="clear"> - <return type="void" /> + <method name="create_default_interface" qualifiers="static"> + <return type="MultiplayerAPI" /> + <description> + Returns a new instance of the default MultiplayerAPI. + </description> + </method> + <method name="get_default_interface" qualifiers="static"> + <return type="StringName" /> <description> - Clears the current MultiplayerAPI network state (you shouldn't call this unless you know what you are doing). + Returns the default MultiplayerAPI implementation class name. This is usually [code]"SceneMultiplayer"[/code] when [SceneMultiplayer] is available. See [method set_default_interface]. </description> </method> - <method name="get_peers" qualifiers="const"> + <method name="get_peers"> <return type="PackedInt32Array" /> <description> Returns the peer IDs of all connected peers of this MultiplayerAPI's [member multiplayer_peer]. </description> </method> - <method name="get_remote_sender_id" qualifiers="const"> + <method name="get_remote_sender_id"> <return type="int" /> <description> Returns the sender's peer ID for the RPC currently being executed. [b]Note:[/b] If not inside an RPC this method will return 0. </description> </method> - <method name="get_unique_id" qualifiers="const"> + <method name="get_unique_id"> <return type="int" /> <description> Returns the unique peer ID of this MultiplayerAPI's [member multiplayer_peer]. </description> </method> - <method name="has_multiplayer_peer" qualifiers="const"> + <method name="has_multiplayer_peer"> <return type="bool" /> <description> Returns [code]true[/code] if there is a [member multiplayer_peer] set. </description> </method> - <method name="is_server" qualifiers="const"> + <method name="is_server"> <return type="bool" /> <description> Returns [code]true[/code] if this MultiplayerAPI's [member multiplayer_peer] is valid and in server mode (listening for connections). </description> </method> + <method name="object_configuration_add"> + <return type="int" enum="Error" /> + <argument index="0" name="object" type="Object" /> + <argument index="1" name="configuration" type="Variant" /> + <description> + Notifies the MultiplayerAPI of a new [code]configuration[/code] for the given [code]object[/code]. This method is used internally by [SceneTree] to configure the root path for this MultiplayerAPI (passing [code]null[/code] and a valid [NodePath] as [code]configuration[/code]). This method can be further used by MultiplayerAPI implementations to provide additional features, refer to specific implementation (e.g. [SceneMultiplayer]) for details on how they use it. + [b]Note:[/b] This method is mostly relevant when extending or overriding the MultiplayerAPI behavior via [MultiplayerAPIExtension]. + </description> + </method> + <method name="object_configuration_remove"> + <return type="int" enum="Error" /> + <argument index="0" name="object" type="Object" /> + <argument index="1" name="configuration" type="Variant" /> + <description> + Notifies the MultiplayerAPI to remove a [code]configuration[/code] for the given [code]object[/code]. This method is used internally by [SceneTree] to configure the root path for this MultiplayerAPI (passing [code]null[/code] and an empty [NodePath] as [code]configuration[/code]). This method can be further used by MultiplayerAPI implementations to provide additional features, refer to specific implementation (e.g. [SceneMultiplayer]) for details on how they use it. + [b]Note:[/b] This method is mostly relevant when extending or overriding the MultiplayerAPI behavior via [MultiplayerAPIExtension]. + </description> + </method> <method name="poll"> - <return type="void" /> + <return type="int" enum="Error" /> <description> Method used for polling the MultiplayerAPI. You only need to worry about this if you set [member SceneTree.multiplayer_poll] to [code]false[/code]. By default, [SceneTree] will poll its MultiplayerAPI(s) for you. [b]Note:[/b] This method results in RPCs being called, so they will be executed in the same context of this function (e.g. [code]_process[/code], [code]physics[/code], [Thread]). </description> </method> - <method name="send_bytes"> + <method name="rpc"> <return type="int" enum="Error" /> - <argument index="0" name="bytes" type="PackedByteArray" /> - <argument index="1" name="id" type="int" default="0" /> - <argument index="2" name="mode" type="int" enum="TransferMode" default="2" /> - <argument index="3" name="channel" type="int" default="0" /> + <argument index="0" name="peer" type="int" /> + <argument index="1" name="object" type="Object" /> + <argument index="2" name="method" type="StringName" /> + <argument index="3" name="arguments" type="Array" default="[]" /> + <description> + Sends an RPC to the target [code]peer[/code]. The given [code]method[/code] will be called on the remote [code]object[/code] with the provided [code]arguments[/code]. The RPC may also be called locally depending on the implementation and RPC configuration. See [method Node.rpc] and [method Node.rpc_config]. + [b]Note:[/b] Prefer using [method Node.rpc], [method Node.rpc_id], or [code]my_method.rpc(peer, arg1, arg2, ...)[/code] (in GDScript), since they are faster. This method is mostly useful in conjunction with [MultiplayerAPIExtension] when augmenting or replacing the multiplayer capabilities. + </description> + </method> + <method name="set_default_interface" qualifiers="static"> + <return type="void" /> + <argument index="0" name="interface_name" type="StringName" /> <description> - Sends the given raw [code]bytes[/code] to a specific peer identified by [code]id[/code] (see [method MultiplayerPeer.set_target_peer]). Default ID is [code]0[/code], i.e. broadcast to all peers. + Sets the default MultiplayerAPI implementation class. This method can be used by modules and extensions to configure which implementation will be used by [SceneTree] when the engine starts. </description> </method> </methods> <members> - <member name="allow_object_decoding" type="bool" setter="set_allow_object_decoding" getter="is_object_decoding_allowed" default="false"> - If [code]true[/code], the MultiplayerAPI will allow encoding and decoding of object during RPCs. - [b]Warning:[/b] Deserialized objects can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats such as remote code execution. - </member> <member name="multiplayer_peer" type="MultiplayerPeer" setter="set_multiplayer_peer" getter="get_multiplayer_peer"> The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_server]) and will set root node's network mode to authority, or it will become a regular client peer. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals. </member> - <member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" default="false"> - If [code]true[/code], the MultiplayerAPI's [member multiplayer_peer] refuses new incoming connections. - </member> - <member name="root_path" type="NodePath" setter="set_root_path" getter="get_root_path" default="NodePath("")"> - The root path to use for RPCs and replication. Instead of an absolute path, a relative path will be used to find the node upon which the RPC should be executed. - This effectively allows to have different branches of the scene tree to be managed by different MultiplayerAPI, allowing for example to run both client and server in the same scene. - </member> </members> <signals> <signal name="connected_to_server"> @@ -107,17 +127,21 @@ Emitted when this MultiplayerAPI's [member multiplayer_peer] disconnects from a peer. Clients get notified when other clients disconnect from the same server. </description> </signal> - <signal name="peer_packet"> - <argument index="0" name="id" type="int" /> - <argument index="1" name="packet" type="PackedByteArray" /> - <description> - Emitted when this MultiplayerAPI's [member multiplayer_peer] receives a [code]packet[/code] with custom data (see [method send_bytes]). ID is the peer ID of the peer that sent the packet. - </description> - </signal> <signal name="server_disconnected"> <description> Emitted when this MultiplayerAPI's [member multiplayer_peer] disconnects from server. Only emitted on clients. </description> </signal> </signals> + <constants> + <constant name="RPC_MODE_DISABLED" value="0" enum="RPCMode"> + Used with [method Node.rpc_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods. + </constant> + <constant name="RPC_MODE_ANY_PEER" value="1" enum="RPCMode"> + Used with [method Node.rpc_config] to set a method to be callable remotely by any peer. Analogous to the [code]@rpc(any)[/code] annotation. Calls are accepted from all remote peers, no matter if they are node's authority or not. + </constant> + <constant name="RPC_MODE_AUTHORITY" value="2" enum="RPCMode"> + Used with [method Node.rpc_config] to set a method to be callable remotely only by the current multiplayer authority (which is the server by default). Analogous to the [code]@rpc(authority)[/code] annotation. See [method Node.set_multiplayer_authority]. + </constant> + </constants> </class> diff --git a/doc/classes/MultiplayerAPIExtension.xml b/doc/classes/MultiplayerAPIExtension.xml new file mode 100644 index 0000000000..c369977d57 --- /dev/null +++ b/doc/classes/MultiplayerAPIExtension.xml @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="MultiplayerAPIExtension" inherits="MultiplayerAPI" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Base class used for extending the [MultiplayerAPI]. + </brief_description> + <description> + This class can be used to augment or replace the default [MultiplayerAPI] implementation via script or extensions. + The following example augment the default implemenation ([SceneMultiplayer]) by logging every RPC being made, and every object being configured for replication. + [codeblocks] + [gdscript] + extends MultiplayerAPIExtension + class_name LogMultiplayer + + # We want to augment the default SceneMultiplayer. + var base_multiplayer = SceneMultiplayer.new() + + func _init(): + # Just passthourgh base signals (copied to var to avoid cyclic reference) + var cts = connected_to_server + var cf = connection_failed + var pc = peer_connected + var pd = peer_disconnected + base_multiplayer.connected_to_server.connect(func(): cts.emit()) + base_multiplayer.connection_failed.connect(func(): cf.emit()) + base_multiplayer.peer_connected.connect(func(id): pc.emit(id)) + base_multiplayer.peer_disconnected.connect(func(id): pd.emit(id)) + + # Log RPC being made and forward it to the default multiplayer. + func _rpc(peer: int, object: Object, method: StringName, args: Array) -> int: # Error + print("Got RPC for %d: %s::%s(%s)" % [peer, object, method, args]) + return base_multiplayer.rpc(peer, object, method, args) + + # Log configuration add. E.g. root path (nullptr, NodePath), replication (Node, Spawner|Synchronizer), custom. + func _object_configuration_add(object, config: Variant) -> int: # Error + if config is MultiplayerSynchronizer: + print("Adding synchronization configuration for %s. Synchronizer: %s" % [object, config]) + elif config is MultiplayerSpawner: + print("Adding node %s to the spawn list. Spawner: %s" % [object, config]) + return base_multiplayer.object_configuration_add(object, config) + + # Log configuration remove. E.g. root path (nullptr, NodePath), replication (Node, Spawner|Synchronizer), custom. + func _object_configuration_remove(object, config: Variant) -> int: # Error + if config is MultiplayerSynchronizer: + print("Removing synchronization configuration for %s. Synchronizer: %s" % [object, config]) + elif config is MultiplayerSpawner: + print("Removing node %s from the spawn list. Spawner: %s" % [object, config]) + return base_multiplayer.object_configuration_remove(object, config) + + # These can be optional, but in our case we want to augment SceneMultiplayer, so forward everything. + func _set_multiplayer_peer(p_peer: MultiplayerPeer): + base_multiplayer.multiplayer_peer = p_peer + + func _get_multiplayer_peer() -> MultiplayerPeer: + return base_multiplayer.multiplayer_peer + + func _get_unique_id() -> int: + return base_multiplayer.get_unique_id() + + func _get_peer_ids() -> PackedInt32Array: + return base_multiplayer.get_peers() + [/gdscript] + [/codeblocks] + Then in your main scene or in an autoload call [method SceneTree.set_multiplayer] to start using your custom [MultiplayerAPI]: + [codeblocks] + [gdscript] + # autoload.gd + func _enter_tree(): + # Sets our custom multiplayer as the main one in SceneTree. + get_tree().set_multiplayer(LogMultiplayer.new()) + [/gdscript] + [/codeblocks] + Native extensions can alternatively use the [method MultiplayerAPI.set_default_interface] method during initialization to configure themselves as the default implementation. + </description> + <tutorials> + </tutorials> + <methods> + <method name="_get_multiplayer_peer" qualifiers="virtual"> + <return type="MultiplayerPeer" /> + <description> + Called when the [member MultiplayerAPI.multiplayer_peer] is retrieved. + </description> + </method> + <method name="_get_peer_ids" qualifiers="virtual const"> + <return type="PackedInt32Array" /> + <description> + Callback for [method MultiplayerAPI.get_peers]. + </description> + </method> + <method name="_get_remote_sender_id" qualifiers="virtual const"> + <return type="int" /> + <description> + Callback for [method MultiplayerAPI.get_remote_sender_id]. + </description> + </method> + <method name="_get_unique_id" qualifiers="virtual const"> + <return type="int" /> + <description> + Callback for [method MultiplayerAPI.get_unique_id]. + </description> + </method> + <method name="_object_configuration_add" qualifiers="virtual"> + <return type="int" /> + <argument index="0" name="object" type="Object" /> + <argument index="1" name="configuration" type="Variant" /> + <description> + Callback for [method MultiplayerAPI.object_configuration_add]. + </description> + </method> + <method name="_object_configuration_remove" qualifiers="virtual"> + <return type="int" /> + <argument index="0" name="object" type="Object" /> + <argument index="1" name="configuration" type="Variant" /> + <description> + Callback for [method MultiplayerAPI.object_configuration_remove]. + </description> + </method> + <method name="_poll" qualifiers="virtual"> + <return type="int" /> + <description> + Callback for [method MultiplayerAPI.poll]. + </description> + </method> + <method name="_rpc" qualifiers="virtual"> + <return type="int" /> + <argument index="0" name="peer" type="int" /> + <argument index="1" name="object" type="Object" /> + <argument index="2" name="method" type="StringName" /> + <argument index="3" name="args" type="Array" /> + <description> + Callback for [method MultiplayerAPI.rpc]. + </description> + </method> + <method name="_set_multiplayer_peer" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="multiplayer_peer" type="MultiplayerPeer" /> + <description> + Called when the [member MultiplayerAPI.multiplayer_peer] is set. + </description> + </method> + </methods> +</class> diff --git a/doc/classes/MultiplayerPeer.xml b/doc/classes/MultiplayerPeer.xml index 4a3559b0f7..6dde40f018 100644 --- a/doc/classes/MultiplayerPeer.xml +++ b/doc/classes/MultiplayerPeer.xml @@ -60,7 +60,7 @@ The channel to use to send packets. Many network APIs such as ENet and WebRTC allow the creation of multiple independent channels which behaves, in a way, like separate connections. This means that reliable data will only block delivery of other packets on that channel, and ordering will only be in respect to the channel the packet is being sent on. Using different channels to send [b]different and independent[/b] state updates is a common way to optimize network usage and decrease latency in fast-paced games. [b]Note:[/b] The default channel ([code]0[/code]) actually works as 3 separate channels (one for each [enum TransferMode]) so that [constant TRANSFER_MODE_RELIABLE] and [constant TRANSFER_MODE_UNRELIABLE_ORDERED] does not interact with each other by default. Refer to the specific network API documentation (e.g. ENet or WebRTC) to learn how to set up channels correctly. </member> - <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" enum="TransferMode" default="2"> + <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" enum="MultiplayerPeer.TransferMode" default="2"> The manner in which to send packets to the [code]target_peer[/code]. See [enum TransferMode]. </member> </members> @@ -109,5 +109,14 @@ <constant name="TARGET_PEER_SERVER" value="1"> Packets are sent to the server alone. </constant> + <constant name="TRANSFER_MODE_UNRELIABLE" value="0" enum="TransferMode"> + Packets are not acknowledged, no resend attempts are made for lost packets. Packets may arrive in any order. Potentially faster than [constant TRANSFER_MODE_UNRELIABLE_ORDERED]. Use for non-critical data, and always consider whether the order matters. + </constant> + <constant name="TRANSFER_MODE_UNRELIABLE_ORDERED" value="1" enum="TransferMode"> + Packets are not acknowledged, no resend attempts are made for lost packets. Packets are received in the order they were sent in. Potentially faster than [constant TRANSFER_MODE_RELIABLE]. Use for non-critical data or data that would be outdated if received late due to resend attempt(s) anyway, for example movement and positional data. + </constant> + <constant name="TRANSFER_MODE_RELIABLE" value="2" enum="TransferMode"> + Packets must be received and resend attempts should be made until the packets are acknowledged. Packets must be received in the order they were sent in. Most reliable transfer mode, but potentially the slowest due to the overhead. Use for critical data that must be transmitted and arrive in order, for example an ability being triggered or a chat message. Consider carefully if the information really is critical, and use sparingly. + </constant> </constants> </class> diff --git a/doc/classes/MultiplayerSpawner.xml b/doc/classes/MultiplayerSpawner.xml deleted file mode 100644 index 9de67068eb..0000000000 --- a/doc/classes/MultiplayerSpawner.xml +++ /dev/null @@ -1,65 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="MultiplayerSpawner" inherits="Node" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - <method name="_spawn_custom" qualifiers="virtual"> - <return type="Object" /> - <argument index="0" name="data" type="Variant" /> - <description> - </description> - </method> - <method name="add_spawnable_scene"> - <return type="void" /> - <argument index="0" name="path" type="String" /> - <description> - </description> - </method> - <method name="clear_spawnable_scenes"> - <return type="void" /> - <description> - </description> - </method> - <method name="get_spawnable_scene" qualifiers="const"> - <return type="String" /> - <argument index="0" name="path" type="int" /> - <description> - </description> - </method> - <method name="get_spawnable_scene_count" qualifiers="const"> - <return type="int" /> - <description> - </description> - </method> - <method name="spawn"> - <return type="Node" /> - <argument index="0" name="data" type="Variant" default="null" /> - <description> - </description> - </method> - </methods> - <members> - <member name="spawn_limit" type="int" setter="set_spawn_limit" getter="get_spawn_limit" default="0"> - </member> - <member name="spawn_path" type="NodePath" setter="set_spawn_path" getter="get_spawn_path" default="NodePath("")"> - </member> - </members> - <signals> - <signal name="despawned"> - <argument index="0" name="scene_id" type="int" /> - <argument index="1" name="node" type="Node" /> - <description> - </description> - </signal> - <signal name="spawned"> - <argument index="0" name="scene_id" type="int" /> - <argument index="1" name="node" type="Node" /> - <description> - </description> - </signal> - </signals> -</class> diff --git a/doc/classes/MultiplayerSynchronizer.xml b/doc/classes/MultiplayerSynchronizer.xml deleted file mode 100644 index 3766491a6c..0000000000 --- a/doc/classes/MultiplayerSynchronizer.xml +++ /dev/null @@ -1,69 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="MultiplayerSynchronizer" inherits="Node" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - <method name="add_visibility_filter"> - <return type="void" /> - <argument index="0" name="filter" type="Callable" /> - <description> - </description> - </method> - <method name="get_visibility_for" qualifiers="const"> - <return type="bool" /> - <argument index="0" name="peer" type="int" /> - <description> - </description> - </method> - <method name="remove_visibility_filter"> - <return type="void" /> - <argument index="0" name="filter" type="Callable" /> - <description> - </description> - </method> - <method name="set_visibility_for"> - <return type="void" /> - <argument index="0" name="peer" type="int" /> - <argument index="1" name="visible" type="bool" /> - <description> - </description> - </method> - <method name="update_visibility"> - <return type="void" /> - <argument index="0" name="for_peer" type="int" default="0" /> - <description> - </description> - </method> - </methods> - <members> - <member name="public_visibility" type="bool" setter="set_visibility_public" getter="is_visibility_public" default="true"> - </member> - <member name="replication_config" type="SceneReplicationConfig" setter="set_replication_config" getter="get_replication_config"> - </member> - <member name="replication_interval" type="float" setter="set_replication_interval" getter="get_replication_interval" default="0.0"> - </member> - <member name="root_path" type="NodePath" setter="set_root_path" getter="get_root_path" default="NodePath("..")"> - </member> - <member name="visibility_update_mode" type="int" setter="set_visibility_update_mode" getter="get_visibility_update_mode" enum="MultiplayerSynchronizer.VisibilityUpdateMode" default="0"> - </member> - </members> - <signals> - <signal name="visibility_changed"> - <argument index="0" name="for_peer" type="int" /> - <description> - </description> - </signal> - </signals> - <constants> - <constant name="VISIBILITY_PROCESS_IDLE" value="0" enum="VisibilityUpdateMode"> - </constant> - <constant name="VISIBILITY_PROCESS_PHYSICS" value="1" enum="VisibilityUpdateMode"> - </constant> - <constant name="VISIBILITY_PROCESS_NONE" value="2" enum="VisibilityUpdateMode"> - </constant> - </constants> -</class> diff --git a/doc/classes/NavigationMesh.xml b/doc/classes/NavigationMesh.xml index 966f964b12..33d2535ca2 100644 --- a/doc/classes/NavigationMesh.xml +++ b/doc/classes/NavigationMesh.xml @@ -28,6 +28,7 @@ <argument index="0" name="mesh" type="Mesh" /> <description> Initializes the navigation mesh by setting the vertices and indices according to a [Mesh]. + [b]Note:[/b] The given [code]mesh[/code] must be of type [constant Mesh.PRIMITIVE_TRIANGLES] and have an index array. </description> </method> <method name="get_collision_mask_value" qualifiers="const"> diff --git a/doc/classes/NavigationRegion2D.xml b/doc/classes/NavigationRegion2D.xml index c48ca18e9e..75b6544827 100644 --- a/doc/classes/NavigationRegion2D.xml +++ b/doc/classes/NavigationRegion2D.xml @@ -8,7 +8,7 @@ Two regions can be connected to each other if they share a similar edge. You can set the minimum distance between two vertices required to connect two edges by using [method NavigationServer2D.map_set_edge_connection_margin]. [b]Note:[/b] Overlapping two regions' polygons is not enough for connecting two regions. They must share a similar edge. The pathfinding cost of entering this region from another region can be controlled with the [member enter_cost] value. - [b]Note[/b]: This value is not added to the path cost when the start position is already inside this region. + [b]Note:[/b] This value is not added to the path cost when the start position is already inside this region. The pathfinding cost of traveling distances inside this region can be controlled with the [member travel_cost] multiplier. </description> <tutorials> diff --git a/doc/classes/NavigationRegion3D.xml b/doc/classes/NavigationRegion3D.xml index 9f4feee072..f5824a24fd 100644 --- a/doc/classes/NavigationRegion3D.xml +++ b/doc/classes/NavigationRegion3D.xml @@ -8,7 +8,7 @@ Two regions can be connected to each other if they share a similar edge. You can set the minimum distance between two vertices required to connect two edges by using [method NavigationServer3D.map_set_edge_connection_margin]. [b]Note:[/b] Overlapping two regions' navmeshes is not enough for connecting two regions. They must share a similar edge. The cost of entering this region from another region can be controlled with the [member enter_cost] value. - [b]Note[/b]: This value is not added to the path cost when the start position is already inside this region. + [b]Note:[/b] This value is not added to the path cost when the start position is already inside this region. The cost of traveling distances inside this region can be controlled with the [member travel_cost] multiplier. </description> <tutorials> diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index 5185b353bc..8600c2643a 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -415,5 +415,10 @@ Emitted when a navigation map is updated, when a region moves or is modified. </description> </signal> + <signal name="navigation_debug_changed"> + <description> + Emitted when navigation debug settings are changed. Only available in debug builds. + </description> + </signal> </signals> </class> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index b7591ed4f4..8cc8498609 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -622,7 +622,7 @@ </description> </method> <method name="rpc" qualifiers="vararg"> - <return type="void" /> + <return type="int" enum="Error" /> <argument index="0" name="method" type="StringName" /> <description> Sends a remote procedure call request for the given [code]method[/code] to peers on the network (and locally), optionally sending all additional arguments as arguments to the method called by the RPC. The call request will only be received by nodes with the same [NodePath], including the exact same node name. Behaviour depends on the RPC configuration for the given method, see [method rpc_config]. Methods are not exposed to RPCs by default. Returns [code]null[/code]. @@ -630,18 +630,24 @@ </description> </method> <method name="rpc_config"> - <return type="int" /> + <return type="void" /> <argument index="0" name="method" type="StringName" /> - <argument index="1" name="rpc_mode" type="int" enum="RPCMode" /> - <argument index="2" name="call_local" type="bool" default="false" /> - <argument index="3" name="transfer_mode" type="int" enum="TransferMode" default="2" /> - <argument index="4" name="channel" type="int" default="0" /> + <argument index="1" name="config" type="Variant" /> <description> - Changes the RPC mode for the given [code]method[/code] to the given [code]rpc_mode[/code], optionally specifying the [code]transfer_mode[/code] and [code]channel[/code] (on supported peers). See [enum RPCMode] and [enum TransferMode]. An alternative is annotating methods and properties with the corresponding annotation ([code]@rpc(any)[/code], [code]@rpc(authority)[/code]). By default, methods are not exposed to networking (and RPCs). + Changes the RPC mode for the given [code]method[/code] with the given [code]config[/code] which should be [code]null[/code] (to disable) or a [Dictionary] in the form: + [codeblock] + { + rpc_mode = MultiplayerAPI.RPCMode, + transfer_mode = MultiplayerPeer.TranferMode, + call_local = false, + channel = 0, + } + [/codeblock] + See [enum MultiplayerAPI.RPCMode] and [enum MultiplayerPeer.TransferMode]. An alternative is annotating methods and properties with the corresponding annotation ([code]@rpc(any)[/code], [code]@rpc(authority)[/code]). By default, methods are not exposed to networking (and RPCs). </description> </method> <method name="rpc_id" qualifiers="vararg"> - <return type="void" /> + <return type="int" enum="Error" /> <argument index="0" name="peer_id" type="int" /> <argument index="1" name="method" type="StringName" /> <description> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index aaf08dec2f..75cd52787a 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -198,6 +198,17 @@ } [/csharp] [/codeblocks] + [b]Note:[/b] Passing custom user arguments directly is not recommended, as the engine may discard or modify them. Instead, the best way is to use the standard UNIX double dash ([code]--[/code]) and then pass custom arguments, which the engine itself will ignore. These can be read via [method get_cmdline_user_args]. + </description> + </method> + <method name="get_cmdline_user_args"> + <return type="PackedStringArray" /> + <description> + Similar to [method get_cmdline_args], but this returns the user arguments (any argument passed after the double dash [code]--[/code] argument). These are left untouched by Godot for the user. + For example, in the command line below, [code]--fullscreen[/code] will not be returned in [method get_cmdline_user_args] and [code]--level 1[/code] will only be returned in [method get_cmdline_user_args]: + [codeblock] + godot --fullscreen -- --level 1 + [/codeblock] </description> </method> <method name="get_config_dir" qualifiers="const"> @@ -363,6 +374,12 @@ [b]Note:[/b] This method is only implemented on Windows, macOS, Linux and iOS. On Android, HTML5 and UWP, [method get_processor_name] returns an empty string. </description> </method> + <method name="get_restart_on_exit_arguments" qualifiers="const"> + <return type="PackedStringArray" /> + <description> + Returns the list of command line arguments that will be used when the project automatically restarts using [method set_restart_on_exit]. See also [method is_restart_on_exit_set]. + </description> + </method> <method name="get_static_memory_peak_usage" qualifiers="const"> <return type="int" /> <description> @@ -385,6 +402,23 @@ [b]Note:[/b] Shared storage is implemented on Android and allows to differentiate between app specific and shared directories. Shared directories have additional restrictions on Android. </description> </method> + <method name="get_system_font_path" qualifiers="const"> + <return type="String" /> + <argument index="0" name="font_name" type="String" /> + <argument index="1" name="bold" type="bool" default="false" /> + <argument index="2" name="italic" type="bool" default="false" /> + <description> + Returns path to the system font file with [code]font_name[/code] and style. Return empty string if no matching fonts found. + [b]Note:[/b] This method is implemented on iOS, Linux, macOS and Windows. + </description> + </method> + <method name="get_system_fonts" qualifiers="const"> + <return type="PackedStringArray" /> + <description> + Returns list of font family names available. + [b]Note:[/b] This method is implemented on iOS, Linux, macOS and Windows. + </description> + </method> <method name="get_thread_caller_id" qualifiers="const"> <return type="int" /> <description> @@ -453,6 +487,12 @@ [b]Note:[/b] This method is implemented on Android, iOS, Linux, macOS and Windows. </description> </method> + <method name="is_restart_on_exit_set" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if the project will automatically restart when it exits for any reason, [code]false[/code] otherwise. See also [method set_restart_on_exit] and [method get_restart_on_exit_arguments]. + </description> + </method> <method name="is_stdout_verbose" qualifiers="const"> <return type="bool" /> <description> @@ -544,6 +584,17 @@ [b]Note:[/b] Double-check the casing of [code]variable[/code]. Environment variable names are case-sensitive on all platforms except Windows. </description> </method> + <method name="set_restart_on_exit"> + <return type="void" /> + <argument index="0" name="restart" type="bool" /> + <argument index="1" name="arguments" type="PackedStringArray" default="PackedStringArray()" /> + <description> + If [code]restart[/code] is [code]true[/code], restarts the project automatically when it is exited with [method SceneTree.quit] or [constant Node.NOTIFICATION_WM_CLOSE_REQUEST]. Command line [code]arguments[/code] can be supplied. To restart the project with the same command line arguments as originally used to run the project, pass [method get_cmdline_args] as the value for [code]arguments[/code]. + [method set_restart_on_exit] can be used to apply setting changes that require a restart. See also [method is_restart_on_exit_set] and [method get_restart_on_exit_arguments]. + [b]Note:[/b] This method is only effective on desktop platforms, and only when the project isn't started from the editor. It will have no effect on mobile and Web platforms, or when the project is started from the editor. + [b]Note:[/b] If the project process crashes or is [i]killed[/i] by the user (by sending [code]SIGKILL[/code] instead of the usual [code]SIGTERM[/code]), the project won't restart automatically. + </description> + </method> <method name="set_thread_name"> <return type="int" enum="Error" /> <argument index="0" name="name" type="String" /> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 11ae7cc2b0..061b32bfdf 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -152,11 +152,9 @@ <return type="int" enum="Error" /> <argument index="0" name="signal" type="StringName" /> <argument index="1" name="callable" type="Callable" /> - <argument index="2" name="binds" type="Array" default="[]" /> - <argument index="3" name="flags" type="int" default="0" /> + <argument index="2" name="flags" type="int" default="0" /> <description> - Connects a [code]signal[/code] to a [code]callable[/code]. Pass optional [code]binds[/code] to the call as an [Array] of parameters. These parameters will be passed to the [Callable]'s method after any parameter used in the call to [method emit_signal]. Use [code]flags[/code] to set deferred or one-shot connections. See [enum ConnectFlags] constants. - [b]Note:[/b] This method is the legacy implementation for connecting signals. The recommended modern approach is to use [method Signal.connect] and to use [method Callable.bind] to add and validate parameter binds. Both syntaxes are shown below. + Connects a [code]signal[/code] to a [code]callable[/code]. Use [code]flags[/code] to set deferred or one-shot connections. See [enum ConnectFlags] constants. A signal can only be connected once to a [Callable]. It will print an error if already connected, unless the signal was connected with [constant CONNECT_REFERENCE_COUNTED]. To avoid this, first, use [method is_connected] to check for existing connections. If the callable's target is destroyed in the game's lifecycle, the connection will be lost. [b]Examples with recommended syntax:[/b] diff --git a/doc/classes/OccluderInstance3D.xml b/doc/classes/OccluderInstance3D.xml index abd99dd3aa..08d12341cd 100644 --- a/doc/classes/OccluderInstance3D.xml +++ b/doc/classes/OccluderInstance3D.xml @@ -31,7 +31,7 @@ </methods> <members> <member name="bake_mask" type="int" setter="set_bake_mask" getter="get_bake_mask" default="4294967295"> - The visual layers to account for when baking for occluders. Only [MeshInstance3D]s whose [member VisualInstance3D.layers] match with this [member bake_mask] will be included in the generated occluder mesh. By default, all objects are taken into account for the occluder baking. + The visual layers to account for when baking for occluders. Only [MeshInstance3D]s whose [member VisualInstance3D.layers] match with this [member bake_mask] will be included in the generated occluder mesh. By default, all objects with [i]opaque[/i] materials are taken into account for the occluder baking. To improve performance and avoid artifacts, it is recommended to exclude dynamic objects, small objects and fixtures from the baking process by moving them to a separate visual layer and excluding this layer in [member bake_mask]. </member> <member name="bake_simplification_distance" type="float" setter="set_bake_simplification_distance" getter="get_bake_simplification_distance" default="0.1"> diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml index a7b1f0ea33..737662fe69 100644 --- a/doc/classes/OptionButton.xml +++ b/doc/classes/OptionButton.xml @@ -194,6 +194,10 @@ <members> <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" overrides="BaseButton" enum="BaseButton.ActionMode" default="0" /> <member name="alignment" type="int" setter="set_text_alignment" getter="get_text_alignment" overrides="Button" enum="HorizontalAlignment" default="0" /> + <member name="fit_to_longest_item" type="bool" setter="set_fit_to_longest_item" getter="is_fit_to_longest_item" default="true"> + If [code]true[/code], minimum size will be determined by the longest item's text, instead of the currently selected one's. + [b]Note:[/b] For performance reasons, the minimum size doesn't update immediately when adding, removing or modifying items. + </member> <member name="item_count" type="int" setter="set_item_count" getter="get_item_count" default="0"> The number of items to select from. </member> diff --git a/doc/classes/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml index 354fbd462c..7badd826d9 100644 --- a/doc/classes/ParticlesMaterial.xml +++ b/doc/classes/ParticlesMaterial.xml @@ -271,6 +271,42 @@ <member name="tangential_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0"> Minimum equivalent of [member tangential_accel_max]. </member> + <member name="turbulence_enabled" type="bool" setter="set_turbulence_enabled" getter="get_turbulence_enabled" default="false"> + Enables and disables Turbulence for the particle system. + </member> + <member name="turbulence_influence_max" type="float" setter="set_param_max" getter="get_param_max" default="0.1"> + Minimum turbulence influence on each particle. + The actual amount of turbulence influence on each particle is calculated as a random value between [member turbulence_influence_min] and [member turbulence_influence_max] and multiplied by the amount of turbulence influence from [member turbulence_influence_over_life]. + </member> + <member name="turbulence_influence_min" type="float" setter="set_param_min" getter="get_param_min" default="0.1"> + Maximum turbulence influence on each particle. + The actual amount of turbulence influence on each particle is calculated as a random value between [member turbulence_influence_min] and [member turbulence_influence_max] and multiplied by the amount of turbulence influence from [member turbulence_influence_over_life]. + </member> + <member name="turbulence_influence_over_life" type="Texture2D" setter="set_param_texture" getter="get_param_texture"> + Each particle's amount of turbulence will be influenced along this [CurveTexture] over its life time. + </member> + <member name="turbulence_initial_displacement_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0"> + Maximum displacement of each particles spawn position by the turbulence. + The actual amount of displacement will be a factor of the underlying turbulence multiplied by a random value between [member turbulence_initial_displacement_min] and [member turbulence_initial_displacement_max]. + </member> + <member name="turbulence_initial_displacement_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0"> + Minimum displacement of each particles spawn position by the turbulence. + The actual amount of displacement will be a factor of the underlying turbulence multiplied by a random value between [member turbulence_initial_displacement_min] and [member turbulence_initial_displacement_max]. + </member> + <member name="turbulence_noise_scale" type="float" setter="set_turbulence_noise_scale" getter="get_turbulence_noise_scale" default="9.0"> + This value controls the overall scale/frequency of the turbulence noise pattern. + A small scale will result in smaller features with more detail while a high scale will result in smoother noise with larger features. + </member> + <member name="turbulence_noise_speed" type="Vector3" setter="set_turbulence_noise_speed" getter="get_turbulence_noise_speed" default="Vector3(0.5, 0.5, 0.5)"> + The movement speed of the turbulence pattern. This changes how quickly the noise changes over time. + A value of [code]Vector3(0.0, 0.0, 0.0)[/code] will freeze the turbulence pattern in place. + </member> + <member name="turbulence_noise_speed_random" type="float" setter="set_turbulence_noise_speed_random" getter="get_turbulence_noise_speed_random" default="0.0"> + Use to influence the noise speed in a random pattern. This helps to break up visible movement patterns. + </member> + <member name="turbulence_noise_strength" type="float" setter="set_turbulence_noise_strength" getter="get_turbulence_noise_strength" default="1.0"> + The turbulence noise strength. Increasing this will result in a stronger, more contrasting, noise pattern. + </member> </members> <constants> <constant name="PARAM_INITIAL_LINEAR_VELOCITY" value="0" enum="Parameter"> @@ -309,7 +345,7 @@ <constant name="PARAM_ANIM_OFFSET" value="11" enum="Parameter"> Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set animation offset properties. </constant> - <constant name="PARAM_MAX" value="12" enum="Parameter"> + <constant name="PARAM_MAX" value="15" enum="Parameter"> Represents the size of the [enum Parameter] enum. </constant> <constant name="PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="ParticleFlags"> @@ -348,6 +384,15 @@ <constant name="EMISSION_SHAPE_MAX" value="7" enum="EmissionShape"> Represents the size of the [enum EmissionShape] enum. </constant> + <constant name="PARAM_TURB_VEL_INFLUENCE" value="13" enum="Parameter"> + Use with [method set_param_min] and [method set_param_max] to set the turbulence minimum und maximum influence on each particles velocity. + </constant> + <constant name="PARAM_TURB_INIT_DISPLACEMENT" value="14" enum="Parameter"> + Use with [method set_param_min] and [method set_param_max] to set the turbulence minimum and maximum displacement of the particles spawn position. + </constant> + <constant name="PARAM_TURB_INFLUENCE_OVER_LIFE" value="12" enum="Parameter"> + Use with [method set_param_texture] to set the turbulence influence over the particles life time. + </constant> <constant name="SUB_EMITTER_DISABLED" value="0" enum="SubEmitterMode"> </constant> <constant name="SUB_EMITTER_CONSTANT" value="1" enum="SubEmitterMode"> @@ -357,6 +402,7 @@ <constant name="SUB_EMITTER_AT_COLLISION" value="3" enum="SubEmitterMode"> </constant> <constant name="SUB_EMITTER_MAX" value="4" enum="SubEmitterMode"> + Represents the size of the [enum SubEmitterMode] enum. </constant> </constants> </class> diff --git a/doc/classes/PhysicsRayQueryParameters2D.xml b/doc/classes/PhysicsRayQueryParameters2D.xml index 36933ef9a2..1cfc6caadf 100644 --- a/doc/classes/PhysicsRayQueryParameters2D.xml +++ b/doc/classes/PhysicsRayQueryParameters2D.xml @@ -8,6 +8,22 @@ </description> <tutorials> </tutorials> + <methods> + <method name="create" qualifiers="static"> + <return type="PhysicsRayQueryParameters2D" /> + <argument index="0" name="from" type="Vector2" /> + <argument index="1" name="to" type="Vector2" /> + <argument index="2" name="collision_mask" type="int" default="4294967295" /> + <argument index="3" name="exclude" type="Array" default="[]" /> + <description> + Returns a new, pre-configured [PhysicsRayQueryParameters2D] object. Use it to quickly create query parameters using the most common options. + [codeblock] + var query = PhysicsRayQueryParameters2D.create(global_position, global_position + Vector2(0, 100)) + var collision = get_world_2d().direct_space_state.intersect_ray(query) + [/codeblock] + </description> + </method> + </methods> <members> <member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false"> If [code]true[/code], the query will take [Area2D]s into account. diff --git a/doc/classes/PhysicsRayQueryParameters3D.xml b/doc/classes/PhysicsRayQueryParameters3D.xml index 4244ec785f..e9216a8300 100644 --- a/doc/classes/PhysicsRayQueryParameters3D.xml +++ b/doc/classes/PhysicsRayQueryParameters3D.xml @@ -8,6 +8,22 @@ </description> <tutorials> </tutorials> + <methods> + <method name="create" qualifiers="static"> + <return type="PhysicsRayQueryParameters3D" /> + <argument index="0" name="from" type="Vector3" /> + <argument index="1" name="to" type="Vector3" /> + <argument index="2" name="collision_mask" type="int" default="4294967295" /> + <argument index="3" name="exclude" type="Array" default="[]" /> + <description> + Returns a new, pre-configured [PhysicsRayQueryParameters3D] object. Use it to quickly create query parameters using the most common options. + [codeblock] + var query = PhysicsRayQueryParameters3D.create(position, position + Vector3(0, -10, 0)) + var collision = get_world_3d().direct_space_state.intersect_ray(query) + [/codeblock] + </description> + </method> + </methods> <members> <member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false"> If [code]true[/code], the query will take [Area3D]s into account. diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml index 32eb71f1c7..df9d25902b 100644 --- a/doc/classes/Plane.xml +++ b/doc/classes/Plane.xml @@ -179,6 +179,13 @@ [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. </description> </operator> + <operator name="operator *"> + <return type="Plane" /> + <argument index="0" name="right" type="Transform3D" /> + <description> + Inversely transforms (multiplies) the [Plane] by the given [Transform3D] transformation matrix. + </description> + </operator> <operator name="operator =="> <return type="bool" /> <argument index="0" name="right" type="Plane" /> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index f7567133cd..9df8d2df80 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -494,9 +494,39 @@ <member name="debug/shapes/navigation/disabled_geometry_color" type="Color" setter="" getter="" default="Color(1, 0.7, 0.1, 0.4)"> Color of the disabled navigation geometry, visible when "Visible Navigation" is enabled in the Debug menu. </member> + <member name="debug/shapes/navigation/edge_connection_color" type="Color" setter="" getter="" default="Color(1, 0, 1, 1)"> + Color to display edge connections between navigation regions, visible when "Visible Navigation" is enabled in the Debug menu. + </member> + <member name="debug/shapes/navigation/enable_edge_connections" type="bool" setter="" getter="" default="true"> + If enabled, displays edge connections between navigation regions when "Visible Navigation" is enabled in the Debug menu. + </member> + <member name="debug/shapes/navigation/enable_edge_connections_xray" type="bool" setter="" getter="" default="true"> + If enabled, displays edge connections between navigation regions through geometry when "Visible Navigation" is enabled in the Debug menu. + </member> + <member name="debug/shapes/navigation/enable_edge_lines" type="bool" setter="" getter="" default="true"> + If enabled, displays navigation mesh polygon edges when "Visible Navigation" is enabled in the Debug menu. + </member> + <member name="debug/shapes/navigation/enable_edge_lines_xray" type="bool" setter="" getter="" default="true"> + If enabled, displays navigation mesh polygon edges through geometry when "Visible Navigation" is enabled in the Debug menu. + </member> + <member name="debug/shapes/navigation/enable_geometry_face_random_color" type="bool" setter="" getter="" default="true"> + If enabled, colorizes each navigation mesh polygon face with a random color when "Visible Navigation" is enabled in the Debug menu. + </member> <member name="debug/shapes/navigation/geometry_color" type="Color" setter="" getter="" default="Color(0.1, 1, 0.7, 0.4)"> Color of the navigation geometry, visible when "Visible Navigation" is enabled in the Debug menu. </member> + <member name="debug/shapes/navigation/geometry_edge_color" type="Color" setter="" getter="" default="Color(0.5, 1, 1, 1)"> + Color to display enabled navigation mesh polygon edges, visible when "Visible Navigation" is enabled in the Debug menu. + </member> + <member name="debug/shapes/navigation/geometry_edge_disabled_color" type="Color" setter="" getter="" default="Color(0.5, 0.5, 0.5, 1)"> + Color to display disabled navigation mesh polygon edges, visible when "Visible Navigation" is enabled in the Debug menu. + </member> + <member name="debug/shapes/navigation/geometry_face_color" type="Color" setter="" getter="" default="Color(0.5, 1, 1, 0.4)"> + Color to display enabled navigation mesh polygon faces, visible when "Visible Navigation" is enabled in the Debug menu. + </member> + <member name="debug/shapes/navigation/geometry_face_disabled_color" type="Color" setter="" getter="" default="Color(0.5, 0.5, 0.5, 0.4)"> + Color to display disabled navigation mesh polygon faces, visible when "Visible Navigation" is enabled in the Debug menu. + </member> <member name="debug/shapes/paths/geometry_color" type="Color" setter="" getter="" default="Color(0.1, 1, 0.7, 0.4)"> Color of the curve path geometry, visible when "Visible Paths" is enabled in the Debug menu. </member> @@ -519,6 +549,9 @@ <member name="display/window/energy_saving/keep_screen_on" type="bool" setter="" getter="" default="true"> If [code]true[/code], keeps the screen on (even in case of inactivity), so the screensaver does not take over. Works on desktop and mobile platforms. </member> + <member name="display/window/energy_saving/keep_screen_on.editor" type="bool" setter="" getter="" default="false"> + Editor-only override for [member display/window/energy_saving/keep_screen_on]. Does not affect exported projects in debug or release mode. + </member> <member name="display/window/handheld/orientation" type="int" setter="" getter="" default="0"> The default screen orientation to use on mobile devices. See [enum DisplayServer.ScreenOrientation] for possible values. [b]Note:[/b] When set to a portrait orientation, this project setting does not flip the project resolution's width and height automatically. Instead, you have to set [member display/window/size/viewport_width] and [member display/window/size/viewport_height] accordingly. @@ -558,7 +591,7 @@ [b]Note:[/b] By default, or when set to 0, the initial window width is the viewport [member display/window/size/viewport_width]. This setting is ignored on iOS, Android, and HTML5. </member> <member name="display/window/vsync/vsync_mode" type="int" setter="" getter="" default="1"> - Sets the VSync mode for the main game window. + Sets the V-Sync mode for the main game window. See [enum DisplayServer.VSyncMode] for possible values and how they affect the behavior of your application. Depending on the platform and used renderer, the engine will fall back to [code]Enabled[/code], if the desired mode is not supported. </member> @@ -1632,13 +1665,13 @@ Sets the number of MSAA samples to use (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware. See also bilinear scaling 3d [member rendering/scaling_3d/mode] for supersampling, which provides higher quality but is much more expensive. </member> <member name="rendering/anti_aliasing/quality/screen_space_aa" type="int" setter="" getter="" default="0"> - Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. + Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. The blurriness can be counteracted to an extent by using a negative mipmap LOD bias ([member rendering/textures/default_filters/texture_mipmap_bias]). Another way to combat specular aliasing is to enable [member rendering/anti_aliasing/screen_space_roughness_limiter/enabled]. </member> <member name="rendering/anti_aliasing/quality/use_debanding" type="bool" setter="" getter="" default="false"> </member> <member name="rendering/anti_aliasing/quality/use_taa" type="bool" setter="" getter="" default="false"> - Enables Temporal Anti-Aliasing for the default screen [Viewport]. TAA works by jittering the camera and accumulating the images of the last rendered frames, motion vector rendering is used to account for camera and object motion. + Enables Temporal Anti-Aliasing for the default screen [Viewport]. TAA works by jittering the camera and accumulating the images of the last rendered frames, motion vector rendering is used to account for camera and object motion. Enabling TAA can make the image blurrier, which can be counteracted to an extent by using a negative mipmap LOD bias ([member rendering/textures/default_filters/texture_mipmap_bias]). [b]Note:[/b] The implementation is not complete yet, some visual instances such as particles and skinned meshes may show artifacts. </member> <member name="rendering/anti_aliasing/screen_space_roughness_limiter/amount" type="float" setter="" getter="" default="0.25"> @@ -1856,9 +1889,6 @@ <member name="rendering/reflections/sky_reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false"> Lower-end override for [member rendering/reflections/sky_reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/scaling_3d/fsr_mipmap_bias" type="float" setter="" getter="" default="0.0"> - Affects the final texture sharpness by reading from a lower or higher mipmap. Negative values make textures sharper, while positive values make textures blurrier. When using FSR, this value is used to adjust the mipmap bias calculated internally which is based on the selected quality. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code] - </member> <member name="rendering/scaling_3d/fsr_sharpness" type="float" setter="" getter="" default="0.2"> Determines how sharp the upscaled image will be when using the FSR upscaling mode. Sharpness halves with every whole number. Values go from 0.0 (sharpest) to 2.0. Values above 2.0 won't make a visible difference. </member> @@ -1935,16 +1965,24 @@ Lower-end override for [member rendering/shadows/positional_shadow/soft_shadow_filter_quality] on mobile devices, due to performance concerns or driver support. </member> <member name="rendering/textures/decals/filter" type="int" setter="" getter="" default="3"> + The filtering quality to use for [Decal] nodes. When using one of the anisotropic filtering modes, the anisotropic filtering level is controlled by [member rendering/textures/default_filters/anisotropic_filtering_level]. </member> <member name="rendering/textures/default_filters/anisotropic_filtering_level" type="int" setter="" getter="" default="2"> Sets the maximum number of samples to take when using anisotropic filtering on textures (as a power of two). A higher sample count will result in sharper textures at oblique angles, but is more expensive to compute. A value of [code]0[/code] forcibly disables anisotropic filtering, even on materials where it is enabled. + The anisotropic filtering level also affects decals and light projectors if they are configured to use anisotropic filtering. See [member rendering/textures/decals/filter] and [member rendering/textures/light_projectors/filter]. [b]Note:[/b] This property is only read when the project starts. There is currently no way to change this setting at run-time. </member> + <member name="rendering/textures/default_filters/texture_mipmap_bias" type="float" setter="" getter="" default="0.0"> + Affects the final texture sharpness by reading from a lower or higher mipmap (also called "texture LOD bias"). Negative values make mipmapped textures sharper but grainier when viewed at a distance, while positive values make mipmapped textures blurrier (even when up close). To get sharper textures at a distance without introducing too much graininess, set this between [code]-0.75[/code] and [code]0.0[/code]. Enabling temporal antialiasing ([member rendering/anti_aliasing/quality/use_taa]) can help reduce the graininess visible when using negative mipmap bias. + [b]Note:[/b] When the 3D scaling mode is set to FSR 1.0, this value is used to adjust the automatic mipmap bias which is calculated internally based on the scale factor. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code]. + [b]Note:[/b] This property is only read when the project starts. To change the mipmap LOD bias at run-time, set [member Viewport.texture_mipmap_bias] instead. + </member> <member name="rendering/textures/default_filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false"> If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used. [b]Note:[/b] This property is only read when the project starts. There is currently no way to change this setting at run-time. </member> <member name="rendering/textures/light_projectors/filter" type="int" setter="" getter="" default="3"> + The filtering quality to use for [OmniLight3D] and [SpotLight3D] projectors. When using one of the anisotropic filtering modes, the anisotropic filtering level is controlled by [member rendering/textures/default_filters/anisotropic_filtering_level]. </member> <member name="rendering/textures/lossless_compression/force_png" type="bool" setter="" getter="" default="false"> If [code]true[/code], the texture importer will import lossless textures using the PNG format. Otherwise, it will default to using WebP. diff --git a/doc/classes/Projection.xml b/doc/classes/Projection.xml index 115015c2d7..2bbfd04e9e 100644 --- a/doc/classes/Projection.xml +++ b/doc/classes/Projection.xml @@ -211,13 +211,13 @@ </method> </methods> <members> - <member name="w" type="Vector4" setter="" getter="" default="Vector4(0, 0, 0)"> + <member name="w" type="Vector4" setter="" getter="" default="Vector4(0, 0, 0, 1)"> </member> - <member name="x" type="Vector4" setter="" getter="" default="Vector4(1, 0, 0)"> + <member name="x" type="Vector4" setter="" getter="" default="Vector4(1, 0, 0, 0)"> </member> - <member name="y" type="Vector4" setter="" getter="" default="Vector4(0, 1, 0)"> + <member name="y" type="Vector4" setter="" getter="" default="Vector4(0, 1, 0, 0)"> </member> - <member name="z" type="Vector4" setter="" getter="" default="Vector4(0, 0, 1)"> + <member name="z" type="Vector4" setter="" getter="" default="Vector4(0, 0, 1, 0)"> </member> </members> <constants> diff --git a/doc/classes/Quaternion.xml b/doc/classes/Quaternion.xml index 48e6317b11..30e96607da 100644 --- a/doc/classes/Quaternion.xml +++ b/doc/classes/Quaternion.xml @@ -74,16 +74,6 @@ [b]Note:[/b] This method has an abnormally high amount of floating-point error, so methods such as [code]is_zero_approx[/code] will not work reliably. </description> </method> - <method name="cubic_slerp" qualifiers="const"> - <return type="Quaternion" /> - <argument index="0" name="b" type="Quaternion" /> - <argument index="1" name="pre_a" type="Quaternion" /> - <argument index="2" name="post_b" type="Quaternion" /> - <argument index="3" name="weight" type="float" /> - <description> - Performs a cubic spherical interpolation between quaternions [code]pre_a[/code], this vector, [code]b[/code], and [code]post_b[/code], by the given amount [code]weight[/code]. - </description> - </method> <method name="dot" qualifiers="const"> <return type="float" /> <argument index="0" name="with" type="Quaternion" /> @@ -171,6 +161,16 @@ Returns the result of the spherical linear interpolation between this quaternion and [code]to[/code] by amount [code]weight[/code], but without checking if the rotation path is not bigger than 90 degrees. </description> </method> + <method name="spherical_cubic_interpolate" qualifiers="const"> + <return type="Quaternion" /> + <argument index="0" name="b" type="Quaternion" /> + <argument index="1" name="pre_a" type="Quaternion" /> + <argument index="2" name="post_b" type="Quaternion" /> + <argument index="3" name="weight" type="float" /> + <description> + Performs a spherical cubic interpolation between quaternions [code]pre_a[/code], this vector, [code]b[/code], and [code]post_b[/code], by the given amount [code]weight[/code]. + </description> + </method> </methods> <members> <member name="w" type="float" setter="" getter="" default="1.0"> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index 6248394b1a..3962f309de 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -305,6 +305,12 @@ <description> </description> </method> + <method name="framebuffer_is_valid" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="framebuffer" type="RID" /> + <description> + </description> + </method> <method name="free_rid"> <return type="void" /> <argument index="0" name="rid" type="RID" /> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index c2752d9f7b..c06b2e1d98 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1293,45 +1293,45 @@ If [code]half_resolution[/code] is [code]true[/code], renders [VoxelGI] and SDFGI ([member Environment.sdfgi_enabled]) buffers at halved resolution (e.g. 960×540 when the viewport size is 1920×1080). This improves performance significantly when VoxelGI or SDFGI is enabled, at the cost of artifacts that may be visible on polygon edges. The loss in quality becomes less noticeable as the viewport resolution increases. [LightmapGI] rendering is not affected by this setting. See also [member ProjectSettings.rendering/global_illumination/gi/use_half_resolution]. </description> </method> - <method name="global_variable_add"> + <method name="global_shader_uniform_add"> <return type="void" /> <argument index="0" name="name" type="StringName" /> - <argument index="1" name="type" type="int" enum="RenderingServer.GlobalVariableType" /> + <argument index="1" name="type" type="int" enum="RenderingServer.GlobalShaderUniformType" /> <argument index="2" name="default_value" type="Variant" /> <description> </description> </method> - <method name="global_variable_get" qualifiers="const"> + <method name="global_shader_uniform_get" qualifiers="const"> <return type="Variant" /> <argument index="0" name="name" type="StringName" /> <description> </description> </method> - <method name="global_variable_get_list" qualifiers="const"> + <method name="global_shader_uniform_get_list" qualifiers="const"> <return type="PackedStringArray" /> <description> </description> </method> - <method name="global_variable_get_type" qualifiers="const"> - <return type="int" enum="RenderingServer.GlobalVariableType" /> + <method name="global_shader_uniform_get_type" qualifiers="const"> + <return type="int" enum="RenderingServer.GlobalShaderUniformType" /> <argument index="0" name="name" type="StringName" /> <description> </description> </method> - <method name="global_variable_remove"> + <method name="global_shader_uniform_remove"> <return type="void" /> <argument index="0" name="name" type="StringName" /> <description> </description> </method> - <method name="global_variable_set"> + <method name="global_shader_uniform_set"> <return type="void" /> <argument index="0" name="name" type="StringName" /> <argument index="1" name="value" type="Variant" /> <description> </description> </method> - <method name="global_variable_set_override"> + <method name="global_shader_uniform_set_override"> <return type="void" /> <argument index="0" name="name" type="StringName" /> <argument index="1" name="value" type="Variant" /> @@ -1391,21 +1391,21 @@ Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] static method. </description> </method> - <method name="instance_geometry_get_shader_parameter" qualifiers="const"> + <method name="instance_geometry_get_shader_uniform" qualifiers="const"> <return type="Variant" /> <argument index="0" name="instance" type="RID" /> <argument index="1" name="parameter" type="StringName" /> <description> </description> </method> - <method name="instance_geometry_get_shader_parameter_default_value" qualifiers="const"> + <method name="instance_geometry_get_shader_uniform_default_value" qualifiers="const"> <return type="Variant" /> <argument index="0" name="instance" type="RID" /> <argument index="1" name="parameter" type="StringName" /> <description> </description> </method> - <method name="instance_geometry_get_shader_parameter_list" qualifiers="const"> + <method name="instance_geometry_get_shader_uniform_list" qualifiers="const"> <return type="Array" /> <argument index="0" name="instance" type="RID" /> <description> @@ -1460,7 +1460,7 @@ Sets a material that will override the material for all surfaces on the mesh associated with this instance. Equivalent to [member GeometryInstance3D.material_override]. </description> </method> - <method name="instance_geometry_set_shader_parameter"> + <method name="instance_geometry_set_shader_uniform"> <return type="void" /> <argument index="0" name="instance" type="RID" /> <argument index="1" name="parameter" type="StringName" /> @@ -2741,7 +2741,7 @@ <description> </description> </method> - <method name="shader_get_param_list" qualifiers="const"> + <method name="shader_get_shader_uniform_list" qualifiers="const"> <return type="Dictionary[]" /> <argument index="0" name="shader" type="RID" /> <description> @@ -3175,14 +3175,6 @@ If [code]true[/code], rendering of a viewport's environment is disabled. </description> </method> - <method name="viewport_set_fsr_mipmap_bias"> - <return type="void" /> - <argument index="0" name="viewport" type="RID" /> - <argument index="1" name="mipmap_bias" type="float" /> - <description> - Affects the final texture sharpness by reading from a lower or higher mipmap. Negative values make textures sharper, while positive values make textures blurrier. When using FSR, this value is used to adjust the mipmap bias calculated internally which is based on the selected quality. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code] - </description> - </method> <method name="viewport_set_fsr_sharpness"> <return type="void" /> <argument index="0" name="viewport" type="RID" /> @@ -3325,6 +3317,15 @@ <description> </description> </method> + <method name="viewport_set_texture_mipmap_bias"> + <return type="void" /> + <argument index="0" name="viewport" type="RID" /> + <argument index="1" name="mipmap_bias" type="float" /> + <description> + Affects the final texture sharpness by reading from a lower or higher mipmap (also called "texture LOD bias"). Negative values make mipmapped textures sharper but grainier when viewed at a distance, while positive values make mipmapped textures blurrier (even when up close). To get sharper textures at a distance without introducing too much graininess, set this between [code]-0.75[/code] and [code]0.0[/code]. Enabling temporal antialiasing ([member ProjectSettings.rendering/anti_aliasing/quality/use_taa]) can help reduce the graininess visible when using negative mipmap bias. + [b]Note:[/b] When the 3D scaling mode is set to FSR 1.0, this value is used to adjust the automatic mipmap bias which is calculated internally based on the scale factor. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code]. + </description> + </method> <method name="viewport_set_transparent_background"> <return type="void" /> <argument index="0" name="viewport" type="RID" /> @@ -3746,14 +3747,22 @@ Use [Transform3D] to store MultiMesh transform. </constant> <constant name="LIGHT_PROJECTOR_FILTER_NEAREST" value="0" enum="LightProjectorFilter"> + Nearest-neighbor filter for light projectors (use for pixel art light projectors). No mipmaps are used for rendering, which means light projectors at a distance will look sharp but grainy. This has roughly the same performance cost as using mipmaps. </constant> - <constant name="LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS" value="1" enum="LightProjectorFilter"> + <constant name="LIGHT_PROJECTOR_FILTER_LINEAR" value="1" enum="LightProjectorFilter"> + Linear filter for light projectors (use for non-pixel art light projectors). No mipmaps are used for rendering, which means light projectors at a distance will look smooth but blurry. This has roughly the same performance cost as using mipmaps. </constant> - <constant name="LIGHT_PROJECTOR_FILTER_LINEAR" value="2" enum="LightProjectorFilter"> + <constant name="LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS" value="2" enum="LightProjectorFilter"> + Nearest-neighbor filter for light projectors (use for pixel art light projectors). Isotropic mipmaps are used for rendering, which means light projectors at a distance will look smooth but blurry. This has roughly the same performance cost as not using mipmaps. </constant> <constant name="LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS" value="3" enum="LightProjectorFilter"> + Linear filter for light projectors (use for non-pixel art light projectors). Isotropic mipmaps are used for rendering, which means light projectors at a distance will look smooth but blurry. This has roughly the same performance cost as not using mipmaps. </constant> - <constant name="LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC" value="4" enum="LightProjectorFilter"> + <constant name="LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS_ANISOTROPIC" value="4" enum="LightProjectorFilter"> + Nearest-neighbor filter for light projectors (use for pixel art light projectors). Anisotropic mipmaps are used for rendering, which means light projectors at a distance will look smooth and sharp when viewed from oblique angles. This looks better compared to isotropic mipmaps, but is slower. The level of anisotropic filtering is defined by [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level]. + </constant> + <constant name="LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC" value="5" enum="LightProjectorFilter"> + Linear filter for light projectors (use for non-pixel art light projectors). Anisotropic mipmaps are used for rendering, which means light projectors at a distance will look smooth and sharp when viewed from oblique angles. This looks better compared to isotropic mipmaps, but is slower. The level of anisotropic filtering is defined by [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level]. </constant> <constant name="LIGHT_DIRECTIONAL" value="0" enum="LightType"> Is a directional (sun) light. @@ -3768,6 +3777,7 @@ The light's energy. </constant> <constant name="LIGHT_PARAM_INDIRECT_ENERGY" value="1" enum="LightParam"> + The light's indirect energy multiplier (final indirect energy is [constant LIGHT_PARAM_ENERGY] * [constant LIGHT_PARAM_INDIRECT_ENERGY]). </constant> <constant name="LIGHT_PARAM_SPECULAR" value="2" enum="LightParam"> The light's influence on specularity. @@ -3811,14 +3821,17 @@ <constant name="LIGHT_PARAM_SHADOW_PANCAKE_SIZE" value="15" enum="LightParam"> Sets the size of the directional shadow pancake. The pancake offsets the start of the shadow's camera frustum to provide a higher effective depth resolution for the shadow. However, a high pancake size can cause artifacts in the shadows of large objects that are close to the edge of the frustum. Reducing the pancake size can help. Setting the size to [code]0[/code] turns off the pancaking effect. </constant> - <constant name="LIGHT_PARAM_SHADOW_BLUR" value="16" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_OPACITY" value="16" enum="LightParam"> + The light's shadow opacity. Values lower than [code]1.0[/code] make the light appear through shadows. This can be used to fake global illumination at a low performance cost. + </constant> + <constant name="LIGHT_PARAM_SHADOW_BLUR" value="17" enum="LightParam"> Blurs the edges of the shadow. Can be used to hide pixel artifacts in low resolution shadow maps. A high value can make shadows appear grainy and can cause other unwanted artifacts. Try to keep as near default as possible. </constant> - <constant name="LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE" value="17" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE" value="18" enum="LightParam"> </constant> - <constant name="LIGHT_PARAM_TRANSMITTANCE_BIAS" value="18" enum="LightParam"> + <constant name="LIGHT_PARAM_TRANSMITTANCE_BIAS" value="19" enum="LightParam"> </constant> - <constant name="LIGHT_PARAM_MAX" value="19" enum="LightParam"> + <constant name="LIGHT_PARAM_MAX" value="20" enum="LightParam"> Represents the size of the [enum LightParam] enum. </constant> <constant name="LIGHT_BAKE_DISABLED" value="0" enum="LightBakeMode"> @@ -3895,14 +3908,22 @@ <constant name="DECAL_TEXTURE_MAX" value="4" enum="DecalTexture"> </constant> <constant name="DECAL_FILTER_NEAREST" value="0" enum="DecalFilter"> + Nearest-neighbor filter for decals (use for pixel art decals). No mipmaps are used for rendering, which means decals at a distance will look sharp but grainy. This has roughly the same performance cost as using mipmaps. </constant> - <constant name="DECAL_FILTER_NEAREST_MIPMAPS" value="1" enum="DecalFilter"> + <constant name="DECAL_FILTER_LINEAR" value="1" enum="DecalFilter"> + Linear filter for decals (use for non-pixel art decals). No mipmaps are used for rendering, which means decals at a distance will look smooth but blurry. This has roughly the same performance cost as using mipmaps. </constant> - <constant name="DECAL_FILTER_LINEAR" value="2" enum="DecalFilter"> + <constant name="DECAL_FILTER_NEAREST_MIPMAPS" value="2" enum="DecalFilter"> + Nearest-neighbor filter for decals (use for pixel art decals). Isotropic mipmaps are used for rendering, which means decals at a distance will look smooth but blurry. This has roughly the same performance cost as not using mipmaps. </constant> <constant name="DECAL_FILTER_LINEAR_MIPMAPS" value="3" enum="DecalFilter"> + Linear filter for decals (use for non-pixel art decals). Isotropic mipmaps are used for rendering, which means decals at a distance will look smooth but blurry. This has roughly the same performance cost as not using mipmaps. + </constant> + <constant name="DECAL_FILTER_NEAREST_MIPMAPS_ANISOTROPIC" value="4" enum="DecalFilter"> + Nearest-neighbor filter for decals (use for pixel art decals). Anisotropic mipmaps are used for rendering, which means decals at a distance will look smooth and sharp when viewed from oblique angles. This looks better compared to isotropic mipmaps, but is slower. The level of anisotropic filtering is defined by [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level]. </constant> - <constant name="DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC" value="4" enum="DecalFilter"> + <constant name="DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC" value="5" enum="DecalFilter"> + Linear filter for decals (use for non-pixel art decals). Anisotropic mipmaps are used for rendering, which means decals at a distance will look smooth and sharp when viewed from oblique angles. This looks better compared to isotropic mipmaps, but is slower. The level of anisotropic filtering is defined by [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level]. </constant> <constant name="VOXEL_GI_QUALITY_LOW" value="0" enum="VoxelGIQuality"> </constant> @@ -4536,63 +4557,63 @@ <constant name="CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE" value="2" enum="CanvasOccluderPolygonCullMode"> Culling of the canvas occluder is counterclockwise. </constant> - <constant name="GLOBAL_VAR_TYPE_BOOL" value="0" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_BOOL" value="0" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_BVEC2" value="1" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_BVEC2" value="1" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_BVEC3" value="2" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_BVEC3" value="2" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_BVEC4" value="3" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_BVEC4" value="3" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_INT" value="4" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_INT" value="4" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_IVEC2" value="5" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_IVEC2" value="5" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_IVEC3" value="6" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_IVEC3" value="6" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_IVEC4" value="7" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_IVEC4" value="7" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_RECT2I" value="8" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_RECT2I" value="8" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UINT" value="9" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_UINT" value="9" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UVEC2" value="10" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_UVEC2" value="10" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UVEC3" value="11" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_UVEC3" value="11" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UVEC4" value="12" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_UVEC4" value="12" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_FLOAT" value="13" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_FLOAT" value="13" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_VEC2" value="14" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_VEC2" value="14" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_VEC3" value="15" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_VEC3" value="15" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_VEC4" value="16" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_VEC4" value="16" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_COLOR" value="17" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_COLOR" value="17" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_RECT2" value="18" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_RECT2" value="18" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAT2" value="19" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_MAT2" value="19" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAT3" value="20" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_MAT3" value="20" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAT4" value="21" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_MAT4" value="21" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_TRANSFORM_2D" value="22" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_TRANSFORM_2D" value="22" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_TRANSFORM" value="23" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_TRANSFORM" value="23" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLER2D" value="24" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLER2D" value="24" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLER2DARRAY" value="25" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLER2DARRAY" value="25" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLER3D" value="26" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLER3D" value="26" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalShaderUniformType"> </constant> <constant name="RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME" value="0" enum="RenderingInfo"> </constant> diff --git a/doc/classes/ResourceFormatSaver.xml b/doc/classes/ResourceFormatSaver.xml index c156814a1d..f9c4ca0d49 100644 --- a/doc/classes/ResourceFormatSaver.xml +++ b/doc/classes/ResourceFormatSaver.xml @@ -26,8 +26,8 @@ </method> <method name="_save" qualifiers="virtual"> <return type="int" /> - <argument index="0" name="path" type="String" /> - <argument index="1" name="resource" type="Resource" /> + <argument index="0" name="path" type="Resource" /> + <argument index="1" name="resource" type="String" /> <argument index="2" name="flags" type="int" /> <description> Saves the given resource object to a file at the target [code]path[/code]. [code]flags[/code] is a bitmask composed with [enum ResourceSaver.SaverFlags] constants. diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml index dd52d09750..729058c9b3 100644 --- a/doc/classes/ResourceLoader.xml +++ b/doc/classes/ResourceLoader.xml @@ -95,8 +95,10 @@ <argument index="0" name="path" type="String" /> <argument index="1" name="type_hint" type="String" default="""" /> <argument index="2" name="use_sub_threads" type="bool" default="false" /> + <argument index="3" name="cache_mode" type="int" enum="ResourceLoader.CacheMode" default="1" /> <description> Loads the resource using threads. If [code]use_sub_threads[/code] is [code]true[/code], multiple threads will be used to load the resource, which makes loading faster, but may affect the main thread (and thus cause game slowdowns). + The [code]cache_mode[/code] property defines whether and how the cache should be used or updated when loading the resource. See [enum CacheMode] for details. </description> </method> <method name="remove_resource_format_loader"> diff --git a/doc/classes/ResourceSaver.xml b/doc/classes/ResourceSaver.xml index 240c72a131..10387a4f14 100644 --- a/doc/classes/ResourceSaver.xml +++ b/doc/classes/ResourceSaver.xml @@ -35,11 +35,11 @@ </method> <method name="save"> <return type="int" enum="Error" /> - <argument index="0" name="path" type="String" /> - <argument index="1" name="resource" type="Resource" /> + <argument index="0" name="resource" type="Resource" /> + <argument index="1" name="path" type="String" default="""" /> <argument index="2" name="flags" type="int" enum="ResourceSaver.SaverFlags" default="0" /> <description> - Saves a resource to disk to the given path, using a [ResourceFormatSaver] that recognizes the resource object. + Saves a resource to disk to the given path, using a [ResourceFormatSaver] that recognizes the resource object. If [code]path[/code] is empty, [ResourceSaver] will try to use [member Resource.resource_path]. The [code]flags[/code] bitmask can be specified to customize the save behavior using [enum SaverFlags] flags. Returns [constant OK] on success. </description> diff --git a/doc/classes/ResourceUID.xml b/doc/classes/ResourceUID.xml index f91c39b512..782a8a2968 100644 --- a/doc/classes/ResourceUID.xml +++ b/doc/classes/ResourceUID.xml @@ -1,8 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="ResourceUID" inherits="Object" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Singleton for managing a cache of resource UIDs within a project. </brief_description> <description> + Resources can not only be referenced using their resource paths [code]res://[/code], but alternatively through a unique identifier specified via [code]uid://[/code]. + Using UIDs allows for the engine to keep references between resources intact, even if the files get renamed or moved. + This singleton is responsible for keeping track of all registered resource UIDs of a project, generating new UIDs and converting between the string and integer representation. </description> <tutorials> </tutorials> @@ -12,35 +16,45 @@ <argument index="0" name="id" type="int" /> <argument index="1" name="path" type="String" /> <description> + Adds a new UID value which is mapped to the given resource path. + Fails with an error if the UID already exists, so be sure to check [method has_id] beforehand, or use [method set_id] instead. </description> </method> <method name="create_id"> <return type="int" /> <description> + Generates a random resource UID which is guaranteed to be unique within the list of currently loaded UIDs. + In order for this UID to be registered, you must call [method add_id] or [method set_id]. </description> </method> <method name="get_id_path" qualifiers="const"> <return type="String" /> <argument index="0" name="id" type="int" /> <description> + Returns the path that the given UID value refers to. + Fails with an error if the UID does not exist, so be sure to check [method has_id] beforehand. </description> </method> <method name="has_id" qualifiers="const"> <return type="bool" /> <argument index="0" name="id" type="int" /> <description> + Returns whether the given UID value is known to the cache. </description> </method> <method name="id_to_text" qualifiers="const"> <return type="String" /> <argument index="0" name="id" type="int" /> <description> + Converts the given UID to a [code]uid://[/code] string value. </description> </method> <method name="remove_id"> <return type="void" /> <argument index="0" name="id" type="int" /> <description> + Removes a loaded UID value from the cache. + Fails with an error if the UID does not exist, so be sure to check [method has_id] beforehand. </description> </method> <method name="set_id"> @@ -48,17 +62,22 @@ <argument index="0" name="id" type="int" /> <argument index="1" name="path" type="String" /> <description> + Updates the resource path of an existing UID. + Fails with an error if the UID does not exist, so be sure to check [method has_id] beforehand, or use [method add_id] instead. </description> </method> <method name="text_to_id" qualifiers="const"> <return type="int" /> <argument index="0" name="text_id" type="String" /> <description> + Extracts the UID value from the given [code]uid://[/code] string. </description> </method> </methods> <constants> <constant name="INVALID_ID" value="-1"> + The value to use for an invalid UID, for example if the resource could not be loaded. + Its text representation is [code]uid://<invalid>[/code]. </constant> </constants> </class> diff --git a/doc/classes/RootMotionView.xml b/doc/classes/RootMotionView.xml index 88b8f2cd03..3f3b00e2cb 100644 --- a/doc/classes/RootMotionView.xml +++ b/doc/classes/RootMotionView.xml @@ -5,25 +5,25 @@ </brief_description> <description> [i]Root motion[/i] refers to an animation technique where a mesh's skeleton is used to give impulse to a character. When working with 3D animations, a popular technique is for animators to use the root skeleton bone to give motion to the rest of the skeleton. This allows animating characters in a way where steps actually match the floor below. It also allows precise interaction with objects during cinematics. See also [AnimationTree]. - [b]Note:[/b] [RootMotionView] is only visible in the editor. It will be hidden automatically in the running project, and will also be converted to a plain [Node] in the running project. This means a script attached to a [RootMotionView] node [i]must[/i] have [code]extends Node[/code] instead of [code]extends RootMotionView[/code]. Additionally, it must not be a [code]@tool[/code] script. + [b]Note:[/b] [RootMotionView] is only visible in the editor. It will be hidden automatically in the running project. </description> <tutorials> <link title="Using AnimationTree - Root motion">$DOCS_URL/tutorials/animation/animation_tree.html#root-motion</link> </tutorials> <members> - <member name="animation_path" type="NodePath" setter="set_animation_path" getter="get_animation_path"> + <member name="animation_path" type="NodePath" setter="set_animation_path" getter="get_animation_path" default="NodePath("")"> Path to an [AnimationTree] node to use as a basis for root motion. </member> - <member name="cell_size" type="float" setter="set_cell_size" getter="get_cell_size"> + <member name="cell_size" type="float" setter="set_cell_size" getter="get_cell_size" default="1.0"> The grid's cell size in 3D units. </member> - <member name="color" type="Color" setter="set_color" getter="get_color"> + <member name="color" type="Color" setter="set_color" getter="get_color" default="Color(0.5, 0.5, 1, 1)"> The grid's color. </member> - <member name="radius" type="float" setter="set_radius" getter="get_radius"> + <member name="radius" type="float" setter="set_radius" getter="get_radius" default="10.0"> The grid's radius in 3D units. The grid's opacity will fade gradually as the distance from the origin increases until this [member radius] is reached. </member> - <member name="zero_y" type="bool" setter="set_zero_y" getter="get_zero_y"> + <member name="zero_y" type="bool" setter="set_zero_y" getter="get_zero_y" default="true"> If [code]true[/code], the grid's points will all be on the same Y coordinate ([i]local[/i] Y = 0). If [code]false[/code], the points' original Y coordinate is preserved. </member> </members> diff --git a/doc/classes/ScriptExtension.xml b/doc/classes/ScriptExtension.xml index 91fa6206d7..4e432ca9a8 100644 --- a/doc/classes/ScriptExtension.xml +++ b/doc/classes/ScriptExtension.xml @@ -65,8 +65,8 @@ <description> </description> </method> - <method name="_get_rpc_methods" qualifiers="virtual const"> - <return type="Dictionary[]" /> + <method name="_get_rpc_config" qualifiers="virtual const"> + <return type="Variant" /> <description> </description> </method> diff --git a/doc/classes/Shader.xml b/doc/classes/Shader.xml index 10deaf1c41..1921c5b91d 100644 --- a/doc/classes/Shader.xml +++ b/doc/classes/Shader.xml @@ -26,7 +26,7 @@ Returns the shader mode for the shader, either [constant MODE_CANVAS_ITEM], [constant MODE_SPATIAL] or [constant MODE_PARTICLES]. </description> </method> - <method name="has_param" qualifiers="const"> + <method name="has_uniform" qualifiers="const"> <return type="bool" /> <argument index="0" name="name" type="StringName" /> <description> diff --git a/doc/classes/ShaderMaterial.xml b/doc/classes/ShaderMaterial.xml index 672b660c34..1208b93a62 100644 --- a/doc/classes/ShaderMaterial.xml +++ b/doc/classes/ShaderMaterial.xml @@ -10,7 +10,7 @@ <link title="Shaders documentation index">$DOCS_URL/tutorials/shaders/index.html</link> </tutorials> <methods> - <method name="get_shader_param" qualifiers="const"> + <method name="get_shader_uniform" qualifiers="const"> <return type="Variant" /> <argument index="0" name="param" type="StringName" /> <description> @@ -31,7 +31,7 @@ Returns the default value of the material property with given [code]name[/code]. </description> </method> - <method name="set_shader_param"> + <method name="set_shader_uniform"> <return type="void" /> <argument index="0" name="param" type="StringName" /> <argument index="1" name="value" type="Variant" /> diff --git a/doc/classes/ShapeCast2D.xml b/doc/classes/ShapeCast2D.xml index 5fcb60dd09..70da03dc6e 100644 --- a/doc/classes/ShapeCast2D.xml +++ b/doc/classes/ShapeCast2D.xml @@ -6,7 +6,7 @@ <description> Shape casting allows to detect collision objects by sweeping the [member shape] along the cast direction determined by [member target_position] (useful for things like beam weapons). Immediate collision overlaps can be done with the [member target_position] set to [code]Vector2(0, 0)[/code] and by calling [method force_shapecast_update] within the same [b]physics_frame[/b]. This also helps to overcome some limitations of [Area2D] when used as a continuous detection area, often requiring waiting a couple of frames before collision information is available to [Area2D] nodes, and when using the signals creates unnecessary complexity. - The node can detect multiple collision objects, but usually the first detected collision + The node can detect multiple collision objects, but it's usually used to detect the first collision. [b]Note:[/b] shape casting is more computationally expensive compared to ray casting. </description> <tutorials> @@ -42,27 +42,27 @@ <method name="get_closest_collision_safe_fraction" qualifiers="const"> <return type="float" /> <description> - The fraction of the motion (between 0 and 1) of how far the shape can move without triggering a collision. The motion is determined by [member target_position]. + The fraction from the [ShapeCast2D]'s origin to its [member target_position] (between 0 and 1) of how far the shape can move without triggering a collision. </description> </method> <method name="get_closest_collision_unsafe_fraction" qualifiers="const"> <return type="float" /> <description> - The fraction of the motion (between 0 and 1) when the shape triggers a collision. The motion is determined by [member target_position]. + The fraction from the [ShapeCast2D]'s origin to its [member target_position] (between 0 and 1) of how far the shape must move to trigger a collision. </description> </method> <method name="get_collider" qualifiers="const"> <return type="Object" /> <argument index="0" name="index" type="int" /> <description> - Returns the [Object] of one of the multiple collisions at [code]index[/code], or [code]null[/code] if no object is intersecting the shape (i.e. [method is_colliding] returns [code]false[/code]). + Returns the collided [Object] of one of the multiple collisions at [code]index[/code], or [code]null[/code] if no object is intersecting the shape (i.e. [method is_colliding] returns [code]false[/code]). </description> </method> <method name="get_collider_shape" qualifiers="const"> <return type="int" /> <argument index="0" name="index" type="int" /> <description> - Returns the shape ID of one of the multiple collisions at [code]index[/code] that the shape intersects, or [code]0[/code] if no object is intersecting the shape (i.e. [method is_colliding] returns [code]false[/code]). + Returns the shape ID of the colliding shape of one of the multiple collisions at [code]index[/code], or [code]0[/code] if no object is intersecting the shape (i.e. [method is_colliding] returns [code]false[/code]). </description> </method> <method name="get_collision_count" qualifiers="const"> @@ -82,14 +82,14 @@ <return type="Vector2" /> <argument index="0" name="index" type="int" /> <description> - Returns the normal containing one of the multiple collisions at [code]index[/code] of the intersecting object. + Returns the normal of one of the multiple collisions at [code]index[/code] of the intersecting object. </description> </method> <method name="get_collision_point" qualifiers="const"> <return type="Vector2" /> <argument index="0" name="index" type="int" /> <description> - Returns the collision point containing one of the multiple collisions at [code]index[/code] at which the shape intersects the object. + Returns the collision point of one of the multiple collisions at [code]index[/code] where the shape intersects the colliding object. [b]Note:[/b] this point is in the [b]global[/b] coordinate system. </description> </method> @@ -133,7 +133,7 @@ The shape's collision mask. Only objects in at least one collision layer enabled in the mask will be detected. </member> <member name="collision_result" type="Array" setter="" getter="_get_collision_result" default="[]"> - A complete collision information. The data returned is the same as in the [method PhysicsDirectSpaceState2D.get_rest_info] method. + Returns the complete collision information from the collision sweep. The data returned is the same as in the [method PhysicsDirectSpaceState2D.get_rest_info] method. </member> <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true"> If [code]true[/code], collisions will be reported. @@ -148,7 +148,7 @@ The number of intersections can be limited with this parameter, to reduce the processing time. </member> <member name="shape" type="Shape2D" setter="set_shape" getter="get_shape"> - Any [Shape2D] derived shape used for collision queries. + The [Shape2D]-derived shape to be used for collision queries. </member> <member name="target_position" type="Vector2" setter="set_target_position" getter="get_target_position" default="Vector2(0, 50)"> The shape's destination point, relative to this node's [code]position[/code]. diff --git a/doc/classes/ShapeCast3D.xml b/doc/classes/ShapeCast3D.xml new file mode 100644 index 0000000000..085bc9acd1 --- /dev/null +++ b/doc/classes/ShapeCast3D.xml @@ -0,0 +1,168 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="ShapeCast3D" inherits="Node3D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Node for physics collision sweep and immediate overlap queries. Similar to the [RayCast3D] node. + </brief_description> + <description> + Shape casting allows to detect collision objects by sweeping the [member shape] along the cast direction determined by [member target_position] (useful for things like beam weapons). + Immediate collision overlaps can be done with the [member target_position] set to [code]Vector3(0, 0, 0)[/code] and by calling [method force_shapecast_update] within the same [b]physics_frame[/b]. This also helps to overcome some limitations of [Area3D] when used as a continuous detection area, often requiring waiting a couple of frames before collision information is available to [Area3D] nodes, and when using the signals creates unnecessary complexity. + The node can detect multiple collision objects, but it's usually used to detect the first collision. + [b]Note:[/b] Shape casting is more computationally expensive compared to ray casting. + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_exception"> + <return type="void" /> + <argument index="0" name="node" type="Object" /> + <description> + Adds a collision exception so the shape does not report collisions with the specified [CollisionObject3D] node. + </description> + </method> + <method name="add_exception_rid"> + <return type="void" /> + <argument index="0" name="rid" type="RID" /> + <description> + Adds a collision exception so the shape does not report collisions with the specified [RID]. + </description> + </method> + <method name="clear_exceptions"> + <return type="void" /> + <description> + Removes all collision exceptions for this [ShapeCast3D]. + </description> + </method> + <method name="force_shapecast_update"> + <return type="void" /> + <description> + Updates the collision information for the shape. Use this method to update the collision information immediately instead of waiting for the next [code]_physics_process[/code] call, for example if the shape or its parent has changed state. + [b]Note:[/b] [code]enabled == true[/code] is not required for this to work. + </description> + </method> + <method name="get_closest_collision_safe_fraction" qualifiers="const"> + <return type="float" /> + <description> + The fraction from the [ShapeCast3D]'s origin to its [member target_position] (between 0 and 1) of how far the shape can move without triggering a collision. + </description> + </method> + <method name="get_closest_collision_unsafe_fraction" qualifiers="const"> + <return type="float" /> + <description> + The fraction from the [ShapeCast3D]'s origin to its [member target_position] (between 0 and 1) of how far the shape must move to trigger a collision. + </description> + </method> + <method name="get_collider" qualifiers="const"> + <return type="Object" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the collided [Object] of one of the multiple collisions at [code]index[/code], or [code]null[/code] if no object is intersecting the shape (i.e. [method is_colliding] returns [code]false[/code]). + </description> + </method> + <method name="get_collider_shape" qualifiers="const"> + <return type="int" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the shape ID of the colliding shape of one of the multiple collisions at [code]index[/code], or [code]0[/code] if no object is intersecting the shape (i.e. [method is_colliding] returns [code]false[/code]). + </description> + </method> + <method name="get_collision_count" qualifiers="const"> + <return type="int" /> + <description> + The number of collisions detected at the point of impact. Use this to iterate over multiple collisions as provided by [method get_collider], [method get_collider_shape], [method get_collision_point], and [method get_collision_normal] methods. + </description> + </method> + <method name="get_collision_mask_value" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="layer_number" type="int" /> + <description> + Returns whether or not the specified layer of the [member collision_mask] is enabled, given a [code]layer_number[/code] between 1 and 32. + </description> + </method> + <method name="get_collision_normal" qualifiers="const"> + <return type="Vector3" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the normal of one of the multiple collisions at [code]index[/code] of the intersecting object. + </description> + </method> + <method name="get_collision_point" qualifiers="const"> + <return type="Vector3" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the collision point of one of the multiple collisions at [code]index[/code] where the shape intersects the colliding object. + [b]Note:[/b] this point is in the [b]global[/b] coordinate system. + </description> + </method> + <method name="is_colliding" qualifiers="const"> + <return type="bool" /> + <description> + Returns whether any object is intersecting with the shape's vector (considering the vector length). + </description> + </method> + <method name="remove_exception"> + <return type="void" /> + <argument index="0" name="node" type="Object" /> + <description> + Removes a collision exception so the shape does report collisions with the specified [CollisionObject3D] node. + </description> + </method> + <method name="remove_exception_rid"> + <return type="void" /> + <argument index="0" name="rid" type="RID" /> + <description> + Removes a collision exception so the shape does report collisions with the specified [RID]. + </description> + </method> + <method name="resource_changed"> + <return type="void" /> + <argument index="0" name="resource" type="Resource" /> + <description> + This method is used internally to update the debug gizmo in the editor. Any code placed in this function will be called whenever the [member shape] resource is modified. + </description> + </method> + <method name="set_collision_mask_value"> + <return type="void" /> + <argument index="0" name="layer_number" type="int" /> + <argument index="1" name="value" type="bool" /> + <description> + Based on [code]value[/code], enables or disables the specified layer in the [member collision_mask], given a [code]layer_number[/code] between 1 and 32. + </description> + </method> + </methods> + <members> + <member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false"> + If [code]true[/code], collision with [Area3D]s will be reported. + </member> + <member name="collide_with_bodies" type="bool" setter="set_collide_with_bodies" getter="is_collide_with_bodies_enabled" default="true"> + If [code]true[/code], collision with [PhysicsBody3D]s will be reported. + </member> + <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1"> + The shape's collision mask. Only objects in at least one collision layer enabled in the mask will be detected. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. + </member> + <member name="collision_result" type="Array" setter="" getter="_get_collision_result" default="[]"> + Returns the complete collision information from the collision sweep. The data returned is the same as in the [method PhysicsDirectSpaceState3D.get_rest_info] method. + </member> + <member name="debug_shape_custom_color" type="Color" setter="set_debug_shape_custom_color" getter="get_debug_shape_custom_color" default="Color(0, 0, 0, 1)"> + The custom color to use to draw the shape in the editor and at run-time if [b]Visible Collision Shapes[/b] is enabled in the [b]Debug[/b] menu. This color will be highlighted at run-time if the [ShapeCast3D] is colliding with something. + If set to [code]Color(0.0, 0.0, 0.0)[/code] (by default), the color set in [member ProjectSettings.debug/shapes/collision/shape_color] is used. + </member> + <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true"> + If [code]true[/code], collisions will be reported. + </member> + <member name="exclude_parent" type="bool" setter="set_exclude_parent_body" getter="get_exclude_parent_body" default="true"> + If [code]true[/code], the parent node will be excluded from collision detection. + </member> + <member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.0"> + The collision margin for the shape. A larger margin helps detecting collisions more consistently, at the cost of precision. + </member> + <member name="max_results" type="int" setter="set_max_results" getter="get_max_results" default="32"> + The number of intersections can be limited with this parameter, to reduce the processing time. + </member> + <member name="shape" type="Shape3D" setter="set_shape" getter="get_shape"> + The [Shape3D]-derived shape to be used for collision queries. + </member> + <member name="target_position" type="Vector3" setter="set_target_position" getter="get_target_position" default="Vector3(0, -1, 0)"> + The shape's destination point, relative to this node's [code]position[/code]. + </member> + </members> +</class> diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index f271220989..6295724aa2 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -392,6 +392,10 @@ <members> <member name="animate_physical_bones" type="bool" setter="set_animate_physical_bones" getter="get_animate_physical_bones" default="true"> </member> + <member name="motion_scale" type="float" setter="set_motion_scale" getter="get_motion_scale" default="1.0"> + Multiplies the position 3D track animation. + [b]Note:[/b] Unless this value is [code]1.0[/code], the key value in animation will not match the actual position value. + </member> <member name="show_rest_only" type="bool" setter="set_show_rest_only" getter="is_show_rest_only" default="false"> </member> </members> diff --git a/doc/classes/SkeletonProfile.xml b/doc/classes/SkeletonProfile.xml index a7f5f7a0a6..5c2d0eefb4 100644 --- a/doc/classes/SkeletonProfile.xml +++ b/doc/classes/SkeletonProfile.xml @@ -162,12 +162,20 @@ </member> <member name="group_size" type="int" setter="set_group_size" getter="get_group_size" default="0"> </member> + <member name="root_bone" type="StringName" setter="set_root_bone" getter="get_root_bone" default="&"""> + A name of bone that will be used as the root bone in [AnimationTree]. + [b]Note:[/b] In most cases, it is the bone of the parent of the hips that exists at the world origin in the humanoid model. + </member> + <member name="scale_base_bone" type="StringName" setter="set_scale_base_bone" getter="get_scale_base_bone" default="&"""> + A name of bone which height will be used as the coefficient for normalization. + [b]Note:[/b] In most cases, it is hips in the humanoid model. + </member> </members> <signals> <signal name="profile_updated"> <description> This signal is emitted when change the value in profile. This is used to update key name in the [BoneMap] and to redraw the [BoneMap] editor. - [b]Note[/b]: This signal is not connected directly to editor to simplify the reference, instead it is passed on to editor through the [BoneMap]. + [b]Note:[/b] This signal is not connected directly to editor to simplify the reference, instead it is passed on to editor through the [BoneMap]. </description> </signal> </signals> diff --git a/doc/classes/SkeletonProfileHumanoid.xml b/doc/classes/SkeletonProfileHumanoid.xml index 065184244e..11f0521718 100644 --- a/doc/classes/SkeletonProfileHumanoid.xml +++ b/doc/classes/SkeletonProfileHumanoid.xml @@ -10,5 +10,7 @@ <members> <member name="bone_size" type="int" setter="set_bone_size" getter="get_bone_size" overrides="SkeletonProfile" default="56" /> <member name="group_size" type="int" setter="set_group_size" getter="get_group_size" overrides="SkeletonProfile" default="4" /> + <member name="root_bone" type="StringName" setter="set_root_bone" getter="get_root_bone" overrides="SkeletonProfile" default="&"Root"" /> + <member name="scale_base_bone" type="StringName" setter="set_scale_base_bone" getter="get_scale_base_bone" overrides="SkeletonProfile" default="&"Hips"" /> </members> </class> diff --git a/doc/classes/SpinBox.xml b/doc/classes/SpinBox.xml index e84f9c38ff..8df039794a 100644 --- a/doc/classes/SpinBox.xml +++ b/doc/classes/SpinBox.xml @@ -47,6 +47,9 @@ <members> <member name="alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0"> </member> + <member name="custom_arrow_step" type="float" setter="set_custom_arrow_step" getter="get_custom_arrow_step" default="0.0"> + If not [code]0[/code], [code]value[/code] will always be rounded to a multiple of [code]custom_arrow_step[/code] when interacting with the arrow buttons of the [SpinBox]. + </member> <member name="editable" type="bool" setter="set_editable" getter="is_editable" default="true"> If [code]true[/code], the [SpinBox] will be editable. Otherwise, it will be read only. </member> diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml index 41b02b6dc9..bc381578d9 100644 --- a/doc/classes/SpriteBase3D.xml +++ b/doc/classes/SpriteBase3D.xml @@ -77,7 +77,7 @@ </member> <member name="render_priority" type="int" setter="set_render_priority" getter="get_render_priority" default="0"> Sets the render priority for the sprite. Higher priority objects will be sorted in front of lower priority objects. - [b]Node:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). + [b]Note:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). [b]Note:[/b] This only applies to sorting of transparent objects. This will not impact how transparent objects are sorted relative to opaque objects. This is because opaque objects are not sorted, while transparent objects are sorted from back to front (subject to priority). </member> <member name="shaded" type="bool" setter="set_draw_flag" getter="get_draw_flag" default="false"> diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 9f197dae02..35ad5f03ab 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -640,6 +640,7 @@ <description> Splits the string by a [code]delimiter[/code] string and returns an array of the substrings, starting from right. The splits in the returned array are sorted in the same order as the original string, from left to right. + If [code]allow_empty[/code] is [code]true[/code], and there are two adjacent delimiters in the string, it will add an empty string to the array of substrings at this position. If [code]maxsplit[/code] is specified, it defines the number of splits to do from the right up to [code]maxsplit[/code]. The default value of 0 means that all items are split, thus giving the same result as [method split]. Example: [codeblocks] @@ -714,6 +715,7 @@ <argument index="2" name="maxsplit" type="int" default="0" /> <description> Splits the string by a [code]delimiter[/code] string and returns an array of the substrings. The [code]delimiter[/code] can be of any length. + If [code]allow_empty[/code] is [code]true[/code], and there are two adjacent delimiters in the string, it will add an empty string to the array of substrings at this position. If [code]maxsplit[/code] is specified, it defines the number of splits to do from the left up to [code]maxsplit[/code]. The default value of [code]0[/code] means that all items are split. If you need only one element from the array at a specific index, [method get_slice] is a more performant option. Example: @@ -742,6 +744,7 @@ <description> Splits the string in floats by using a delimiter string and returns an array of the substrings. For example, [code]"1,2.5,3"[/code] will return [code][1,2.5,3][/code] if split by [code]","[/code]. + If [code]allow_empty[/code] is [code]true[/code], and there are two adjacent delimiters in the string, it will add an empty string to the array of substrings at this position. </description> </method> <method name="strip_edges" qualifiers="const"> diff --git a/doc/classes/SystemFont.xml b/doc/classes/SystemFont.xml new file mode 100644 index 0000000000..b1b78f1705 --- /dev/null +++ b/doc/classes/SystemFont.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SystemFont" inherits="Font" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Font loaded from a system font. + [b]Note:[/b] This class is implemented on iOS, Linux, macOS and Windows, on other platforms it will fallback to default theme font. + </brief_description> + <description> + [SystemFont] loads a font from a system font with the first matching name from [member font_names]. + It will attempt to match font style, but it's not guaranteed. + The returned font might be part of a font collection or be a variable font with OpenType "weight" and/or "italic" features set. + You can create [FontVariation] of the system font for fine control over its features. + </description> + <tutorials> + </tutorials> + <members> + <member name="antialiased" type="bool" setter="set_antialiased" getter="is_antialiased" default="true"> + If set to [code]true[/code], font 8-bit anitialiased glyph rendering is supported and enabled. + </member> + <member name="fallbacks" type="Font[]" setter="set_fallbacks" getter="get_fallbacks" default="[]"> + Array of fallback [Font]s. + </member> + <member name="font_names" type="PackedStringArray" setter="set_font_names" getter="get_font_names" default="PackedStringArray()"> + Array of font family names to search, first matching font found is used. + </member> + <member name="font_style" type="int" setter="set_font_style" getter="get_font_style" enum="TextServer.FontStyle" default="0"> + Font style flags, see [enum TextServer.FontStyle]. + </member> + <member name="force_autohinter" type="bool" setter="set_force_autohinter" getter="is_force_autohinter" default="false"> + If set to [code]true[/code], auto-hinting is supported and preferred over font built-in hinting. + </member> + <member name="generate_mipmaps" type="bool" setter="set_generate_mipmaps" getter="get_generate_mipmaps" default="false"> + If set to [code]true[/code], generate mipmaps for the font textures. + </member> + <member name="hinting" type="int" setter="set_hinting" getter="get_hinting" enum="TextServer.Hinting" default="1"> + Font hinting mode. + </member> + <member name="oversampling" type="float" setter="set_oversampling" getter="get_oversampling" default="0.0"> + Font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. + </member> + <member name="subpixel_positioning" type="int" setter="set_subpixel_positioning" getter="get_subpixel_positioning" enum="TextServer.SubpixelPositioning" default="1"> + Font glyph sub-pixel positioning mode. Subpixel positioning provides shaper text and better kerning for smaller font sizes, at the cost of memory usage and font rasterization speed. Use [constant TextServer.SUBPIXEL_POSITIONING_AUTO] to automatically enable it based on the font size. + </member> + </members> +</class> diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index e1b676427b..b54536f897 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -937,6 +937,16 @@ Returns [code]true[/code] if the server supports a feature. </description> </method> + <method name="is_confusable" qualifiers="const"> + <return type="int" /> + <argument index="0" name="string" type="String" /> + <argument index="1" name="dict" type="PackedStringArray" /> + <description> + Returns index of the first string in [code]dict[/dict] which is visually confusable with the [code]string[/string], or [code]-1[/code] if none is found. + [b]Note:[/b] This method doesn't detect invisible characters, for spoof detection use it in combination with [method spoof_check]. + [b]Note:[/b] Always returns [code]-1[/code] if the server does not support the [constant FEATURE_UNICODE_SECURITY] feature. + </description> + </method> <method name="is_locale_right_to_left" qualifiers="const"> <return type="bool" /> <argument index="0" name="locale" type="String" /> @@ -944,6 +954,21 @@ Returns [code]true[/code] if locale is right-to-left. </description> </method> + <method name="is_valid_identifier" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="string" type="String" /> + <description> + Returns [code]true[/code] is [code]string[/code] is a valid identifier. + If the text server supports the [constant FEATURE_UNICODE_IDENTIFIERS] feature, a valid identifier must: + - Conform to normalization form C. + - Begin with a Unicode character of class XID_Start or [code]"_"[/code]. + - May contain Unicode characters of class XID_Continue in the other positions. + - Use UAX #31 recommended scripts only (mixed scripts are allowed). + If the [constant FEATURE_UNICODE_IDENTIFIERS] feature is not supported, a valid identifier must: + - Begin with a Unicode character of class XID_Start or [code]"_"[/code]. + - May contain Unicode characters of class XID_Continue in the other positions. + </description> + </method> <method name="load_support_data"> <return type="bool" /> <argument index="0" name="filename" type="String" /> @@ -1461,6 +1486,14 @@ Aligns shaped text to the given tab-stops. </description> </method> + <method name="spoof_check" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="string" type="String" /> + <description> + Returns [code]true[/code] if [code]string[/code] is likely to be an attempt at confusing the reader. + [b]Note:[/b] Always returns [code]false[/code] if the server does not support the [constant FEATURE_UNICODE_SECURITY] feature. + </description> + </method> <method name="string_get_word_breaks" qualifiers="const"> <return type="PackedInt32Array" /> <argument index="0" name="string" type="String" /> @@ -1646,6 +1679,9 @@ <constant name="GRAPHEME_IS_CONNECTED" value="1024" enum="GraphemeFlag" is_bitfield="true"> Grapheme is connected to the previous grapheme. Breaking line before this grapheme is not safe. </constant> + <constant name="GRAPHEME_IS_SAFE_TO_INSERT_TATWEEL" value="2048" enum="GraphemeFlag" is_bitfield="true"> + It is safe to insert a U+0640 before this grapheme for elongation. + </constant> <constant name="HINTING_NONE" value="0" enum="Hinting"> Disables font hinting (smoother but less crisp). </constant> @@ -1713,7 +1749,13 @@ TextServer supports locale dependent and context sensitive case conversion. </constant> <constant name="FEATURE_USE_SUPPORT_DATA" value="4096" enum="Feature"> - TextServer require external data file for some features. + TextServer require external data file for some features, see [method load_support_data]. + </constant> + <constant name="FEATURE_UNICODE_IDENTIFIERS" value="8192" enum="Feature"> + TextServer supports UAX #31 identifier validation, see [method is_valid_identifier]. + </constant> + <constant name="FEATURE_UNICODE_SECURITY" value="16384" enum="Feature"> + TextServer supports [url=https://unicode.org/reports/tr36/]Unicode Technical Report #36[/url] and [url=https://unicode.org/reports/tr39/]Unicode Technical Standard #39[/url] based spoof detection features. </constant> <constant name="CONTOUR_CURVE_TAG_ON" value="1" enum="ContourPointTag"> Contour point is on the curve. diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml index 4501ec744a..c686a06e5e 100644 --- a/doc/classes/TextServerExtension.xml +++ b/doc/classes/TextServerExtension.xml @@ -934,6 +934,14 @@ Returns [code]true[/code] if the server supports a feature. </description> </method> + <method name="is_confusable" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="string" type="String" /> + <argument index="1" name="dict" type="PackedStringArray" /> + <description> + Returns index of the first string in [code]dict[/dict] which is visually confusable with the [code]string[/string], or [code]-1[/code] if none is found. + </description> + </method> <method name="is_locale_right_to_left" qualifiers="virtual const"> <return type="bool" /> <argument index="0" name="locale" type="String" /> @@ -941,6 +949,13 @@ Returns [code]true[/code] if locale is right-to-left. </description> </method> + <method name="is_valid_identifier" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="string" type="String" /> + <description> + Returns [code]true[/code] is [code]string[/code] is a valid identifier. + </description> + </method> <method name="load_support_data" qualifiers="virtual"> <return type="bool" /> <argument index="0" name="filename" type="String" /> @@ -1481,6 +1496,13 @@ [b]Note:[/b] This method is used by default line/word breaking methods, and its implementation might be omitted if custom line breaking in implemented. </description> </method> + <method name="spoof_check" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="string" type="String" /> + <description> + Returns [code]true[/code] if [code]string[/code] is likely to be an attempt at confusing the reader. + </description> + </method> <method name="string_get_word_breaks" qualifiers="virtual const"> <return type="PackedInt32Array" /> <argument index="0" name="string" type="String" /> diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml index ad52b2f2f1..180e868ef8 100644 --- a/doc/classes/TileSet.xml +++ b/doc/classes/TileSet.xml @@ -117,6 +117,27 @@ If the TileSet has no proxy for the given identifiers, returns an empty Array. </description> </method> + <method name="get_custom_data_layer_by_name" qualifiers="const"> + <return type="int" /> + <argument index="0" name="layer_name" type="String" /> + <description> + Returns the index of the custom data layer identified by the given name. + </description> + </method> + <method name="get_custom_data_layer_name" qualifiers="const"> + <return type="String" /> + <argument index="0" name="layer_index" type="int" /> + <description> + Returns the name of the custom data layer identified by the given index. + </description> + </method> + <method name="get_custom_data_layer_type" qualifiers="const"> + <return type="int" enum="Variant.Type" /> + <argument index="0" name="layer_index" type="int" /> + <description> + Returns the type of the custom data layer identified by the given index. + </description> + </method> <method name="get_custom_data_layers_count" qualifiers="const"> <return type="int" /> <description> @@ -464,6 +485,22 @@ Proxied tiles can be automatically replaced in TileMap nodes using the editor. </description> </method> + <method name="set_custom_data_layer_name"> + <return type="void" /> + <argument index="0" name="layer_index" type="int" /> + <argument index="1" name="layer_name" type="String" /> + <description> + Sets the name of the custom data layer identified by the given index. Names are identifiers of the layer therefore if the name is already taken it will fail and raise an error. + </description> + </method> + <method name="set_custom_data_layer_type"> + <return type="void" /> + <argument index="0" name="layer_index" type="int" /> + <argument index="1" name="layer_type" type="int" enum="Variant.Type" /> + <description> + Sets the type of the custom data layer identified by the given index. + </description> + </method> <method name="set_navigation_layer_layers"> <return type="void" /> <argument index="0" name="layer_index" type="int" /> diff --git a/doc/classes/TorusMesh.xml b/doc/classes/TorusMesh.xml new file mode 100644 index 0000000000..6b83152793 --- /dev/null +++ b/doc/classes/TorusMesh.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="TorusMesh" inherits="PrimitiveMesh" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Class representing a torus [PrimitiveMesh]. + </brief_description> + <description> + Class representing a torus [PrimitiveMesh]. + </description> + <tutorials> + </tutorials> + <members> + <member name="inner_radius" type="float" setter="set_inner_radius" getter="get_inner_radius" default="0.5"> + The inner radius of the torus. + </member> + <member name="outer_radius" type="float" setter="set_outer_radius" getter="get_outer_radius" default="1.0"> + The outer radius of the torus. + </member> + <member name="ring_segments" type="int" setter="set_ring_segments" getter="get_ring_segments" default="32"> + The number of edges each ring of the torus is constructed of. + </member> + <member name="rings" type="int" setter="set_rings" getter="get_rings" default="64"> + The number of slices the torus is constructed of. + </member> + </members> +</class> diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index e1f7ff21d0..9979a73527 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -141,14 +141,40 @@ <return type="Transform2D" /> <argument index="0" name="angle" type="float" /> <description> - Returns a copy of the transform rotated by the given [code]angle[/code] (in radians), using matrix multiplication. + Returns a copy of the transform rotated by the given [code]angle[/code] (in radians). + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding rotation transform [code]R[/code] from the left, i.e., [code]R * X[/code]. + This can be seen as transforming with respect to the global/parent frame. + </description> + </method> + <method name="rotated_local" qualifiers="const"> + <return type="Transform2D" /> + <argument index="0" name="angle" type="float" /> + <description> + Returns a copy of the transform rotated by the given [code]angle[/code] (in radians). + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding rotation transform [code]R[/code] from the right, i.e., [code]X * R[/code]. + This can be seen as transforming with respect to the local frame. </description> </method> <method name="scaled" qualifiers="const"> <return type="Transform2D" /> <argument index="0" name="scale" type="Vector2" /> <description> - Returns a copy of the transform scaled by the given [code]scale[/code] factor, using matrix multiplication. + Returns a copy of the transform scaled by the given [code]scale[/code] factor. + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding scaling transform [code]S[/code] from the left, i.e., [code]S * X[/code]. + This can be seen as transforming with respect to the global/parent frame. + </description> + </method> + <method name="scaled_local" qualifiers="const"> + <return type="Transform2D" /> + <argument index="0" name="scale" type="Vector2" /> + <description> + Returns a copy of the transform scaled by the given [code]scale[/code] factor. + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding scaling transform [code]S[/code] from the right, i.e., [code]X * S[/code]. + This can be seen as transforming with respect to the local frame. </description> </method> <method name="set_rotation"> @@ -177,8 +203,20 @@ <return type="Transform2D" /> <argument index="0" name="offset" type="Vector2" /> <description> - Returns a copy of the transform translated by the given [code]offset[/code], relative to the transform's basis vectors. - Unlike [method rotated] and [method scaled], this does not use matrix multiplication. + Returns a copy of the transform translated by the given [code]offset[/code]. + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding translation transform [code]T[/code] from the left, i.e., [code]T * X[/code]. + This can be seen as transforming with respect to the global/parent frame. + </description> + </method> + <method name="translated_local" qualifiers="const"> + <return type="Transform2D" /> + <argument index="0" name="offset" type="Vector2" /> + <description> + Returns a copy of the transform translated by the given [code]offset[/code]. + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding translation transform [code]T[/code] from the right, i.e., [code]X * T[/code]. + This can be seen as transforming with respect to the local frame. </description> </method> </methods> diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml index 147eba9f25..cefc74867c 100644 --- a/doc/classes/Transform3D.xml +++ b/doc/classes/Transform3D.xml @@ -102,17 +102,46 @@ <argument index="0" name="axis" type="Vector3" /> <argument index="1" name="angle" type="float" /> <description> - Returns a copy of the transform rotated around the given [code]axis[/code] by the given [code]angle[/code] (in radians), using matrix multiplication. The [code]axis[/code] must be a normalized vector. + Returns a copy of the transform rotated around the given [code]axis[/code] by the given [code]angle[/code] (in radians). + The [code]axis[/code] must be a normalized vector. + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding rotation transform [code]R[/code] from the left, i.e., [code]R * X[/code]. + This can be seen as transforming with respect to the global/parent frame. + </description> + </method> + <method name="rotated_local" qualifiers="const"> + <return type="Transform3D" /> + <argument index="0" name="axis" type="Vector3" /> + <argument index="1" name="angle" type="float" /> + <description> + Returns a copy of the transform rotated around the given [code]axis[/code] by the given [code]angle[/code] (in radians). + The [code]axis[/code] must be a normalized vector. + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding rotation transform [code]R[/code] from the right, i.e., [code]X * R[/code]. + This can be seen as transforming with respect to the local frame. </description> </method> <method name="scaled" qualifiers="const"> <return type="Transform3D" /> <argument index="0" name="scale" type="Vector3" /> <description> - Returns a copy of the transform with its basis and origin scaled by the given [code]scale[/code] factor, using matrix multiplication. + Returns a copy of the transform scaled by the given [code]scale[/code] factor. + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding scaling transform [code]S[/code] from the left, i.e., [code]S * X[/code]. + This can be seen as transforming with respect to the global/parent frame. + </description> + </method> + <method name="scaled_local" qualifiers="const"> + <return type="Transform3D" /> + <argument index="0" name="scale" type="Vector3" /> + <description> + Returns a copy of the transform scaled by the given [code]scale[/code] factor. + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding scaling transform [code]S[/code] from the right, i.e., [code]X * S[/code]. + This can be seen as transforming with respect to the local frame. </description> </method> - <method name="sphere_interpolate_with" qualifiers="const"> + <method name="spherical_interpolate_with" qualifiers="const"> <return type="Transform3D" /> <argument index="0" name="xform" type="Transform3D" /> <argument index="1" name="weight" type="float" /> @@ -124,8 +153,20 @@ <return type="Transform3D" /> <argument index="0" name="offset" type="Vector3" /> <description> - Returns a copy of the transform translated by the given [code]offset[/code], relative to the transform's basis vectors. - Unlike [method rotated] and [method scaled], this does not use matrix multiplication. + Returns a copy of the transform translated by the given [code]offset[/code]. + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding translation transform [code]T[/code] from the left, i.e., [code]T * X[/code]. + This can be seen as transforming with respect to the global/parent frame. + </description> + </method> + <method name="translated_local" qualifiers="const"> + <return type="Transform3D" /> + <argument index="0" name="offset" type="Vector3" /> + <description> + Returns a copy of the transform translated by the given [code]offset[/code]. + This method is an optimized version of multiplying the given transform [code]X[/code] + with a corresponding translation transform [code]T[/code] from the right, i.e., [code]X * T[/code]. + This can be seen as transforming with respect to the local frame. </description> </method> </methods> @@ -175,6 +216,13 @@ </description> </operator> <operator name="operator *"> + <return type="Plane" /> + <argument index="0" name="right" type="Plane" /> + <description> + Transforms (multiplies) the [Plane] by the given [Transform3D] transformation matrix. + </description> + </operator> + <operator name="operator *"> <return type="Transform3D" /> <argument index="0" name="right" type="Transform3D" /> <description> diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index b06be0cf99..f326948e9c 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -461,7 +461,7 @@ <theme_item name="custom_button_font_highlight" data_type="color" type="Color" default="Color(0.95, 0.95, 0.95, 1)"> Text [Color] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell when it's hovered. </theme_item> - <theme_item name="drop_position_color" data_type="color" type="Color" default="Color(1, 0.3, 0.2, 1)"> + <theme_item name="drop_position_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)"> [Color] used to draw possible drop locations. See [enum DropModeFlags] constants for further description of drop locations. </theme_item> <theme_item name="font_color" data_type="color" type="Color" default="Color(0.7, 0.7, 0.7, 1)"> diff --git a/doc/classes/Vector4.xml b/doc/classes/Vector4.xml index e1175e57bd..ee9d97019e 100644 --- a/doc/classes/Vector4.xml +++ b/doc/classes/Vector4.xml @@ -1,8 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Vector4" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Vector used for 4D math using floating point coordinates. </brief_description> <description> + 4-element structure that can be used to represent any quadruplet of numeric values. + It uses floating-point coordinates. See [Vector4i] for its integer counterpart. + [b]Note:[/b] In a boolean context, a Vector4 will evaluate to [code]false[/code] if it's equal to [code]Vector4(0, 0, 0, 0)[/code]. Otherwise, a Vector4 will always evaluate to [code]true[/code]. </description> <tutorials> </tutorials> @@ -10,18 +14,21 @@ <constructor name="Vector4"> <return type="Vector4" /> <description> + Constructs a default-initialized [Vector4] with all components set to [code]0[/code]. </description> </constructor> <constructor name="Vector4"> <return type="Vector4" /> <argument index="0" name="from" type="Vector4" /> <description> + Constructs a [Vector4] as a copy of the given [Vector4]. </description> </constructor> <constructor name="Vector4"> <return type="Vector4" /> <argument index="0" name="from" type="Vector4i" /> <description> + Constructs a new [Vector4] from [Vector4i]. </description> </constructor> <constructor name="Vector4"> @@ -31,6 +38,7 @@ <argument index="2" name="z" type="float" /> <argument index="3" name="w" type="float" /> <description> + Returns a [Vector4] with the given components. </description> </constructor> </constructors> @@ -38,6 +46,13 @@ <method name="abs" qualifiers="const"> <return type="Vector4" /> <description> + Returns a new vector with all components in absolute values (i.e. positive). + </description> + </method> + <method name="ceil" qualifiers="const"> + <return type="Vector4" /> + <description> + Returns a new vector with all components rounded up (towards positive infinity). </description> </method> <method name="clamp" qualifiers="const"> @@ -45,85 +60,172 @@ <argument index="0" name="min" type="Vector4" /> <argument index="1" name="max" type="Vector4" /> <description> + Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component. + </description> + </method> + <method name="cubic_interpolate" qualifiers="const"> + <return type="Vector4" /> + <argument index="0" name="b" type="Vector4" /> + <argument index="1" name="pre_a" type="Vector4" /> + <argument index="2" name="post_b" type="Vector4" /> + <argument index="3" name="weight" type="float" /> + <description> + Performs a cubic interpolation between this vector and [code]b[/code] using [code]pre_a[/code] and [code]post_b[/code] as handles, and returns the result at position [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation. + </description> + </method> + <method name="direction_to" qualifiers="const"> + <return type="Vector4" /> + <argument index="0" name="to" type="Vector4" /> + <description> + Returns the normalized vector pointing from this vector to [code]to[/code]. This is equivalent to using [code](b - a).normalized()[/code]. + </description> + </method> + <method name="distance_to" qualifiers="const"> + <return type="float" /> + <argument index="0" name="to" type="Vector4" /> + <description> + Returns the distance between this vector and [code]to[/code]. </description> </method> <method name="dot" qualifiers="const"> <return type="float" /> <argument index="0" name="with" type="Vector4" /> <description> + Returns the dot product of this vector and [code]with[/code]. + </description> + </method> + <method name="floor" qualifiers="const"> + <return type="Vector4" /> + <description> + Returns a new vector with all components rounded down (towards negative infinity). </description> </method> <method name="inverse" qualifiers="const"> <return type="Vector4" /> <description> + Returns the inverse of the vector. This is the same as [code]Vector4(1.0 / v.x, 1.0 / v.y, 1.0 / v.z, 1.0 / v.w)[/code]. </description> </method> <method name="is_equal_approx" qualifiers="const"> <return type="bool" /> <argument index="0" name="with" type="Vector4" /> <description> + Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component. </description> </method> <method name="is_normalized" qualifiers="const"> <return type="bool" /> <description> + Returns [code]true[/code] if the vector is normalized, i.e. its length is equal to 1. </description> </method> <method name="length" qualifiers="const"> <return type="float" /> <description> + Returns the length (magnitude) of this vector. </description> </method> <method name="length_squared" qualifiers="const"> <return type="float" /> <description> + Returns the squared length (squared magnitude) of this vector. This method runs faster than [method length]. + </description> + </method> + <method name="lerp" qualifiers="const"> + <return type="Vector4" /> + <argument index="0" name="to" type="Vector4" /> + <argument index="1" name="weight" type="float" /> + <description> + Returns the result of the linear interpolation between this vector and [code]to[/code] by amount [code]weight[/code]. [code]weight[/code] is on the range of [code]0.0[/code] to [code]1.0[/code], representing the amount of interpolation. </description> </method> <method name="max_axis_index" qualifiers="const"> <return type="int" /> <description> + Returns the axis of the vector's highest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_X]. </description> </method> <method name="min_axis_index" qualifiers="const"> <return type="int" /> <description> + Returns the axis of the vector's lowest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_W]. </description> </method> <method name="normalized" qualifiers="const"> <return type="Vector4" /> <description> + Returns the vector scaled to unit length. Equivalent to [code]v / v.length()[/code]. + </description> + </method> + <method name="posmod" qualifiers="const"> + <return type="Vector4" /> + <argument index="0" name="mod" type="float" /> + <description> + Returns a vector composed of the [method @GlobalScope.fposmod] of this vector's components and [code]mod[/code]. + </description> + </method> + <method name="posmodv" qualifiers="const"> + <return type="Vector4" /> + <argument index="0" name="modv" type="Vector4" /> + <description> + Returns a vector composed of the [method @GlobalScope.fposmod] of this vector's components and [code]modv[/code]'s components. + </description> + </method> + <method name="round" qualifiers="const"> + <return type="Vector4" /> + <description> + Returns a new vector with all components rounded to the nearest integer, with halfway cases rounded away from zero. </description> </method> <method name="sign" qualifiers="const"> <return type="Vector4" /> <description> + Returns a new vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component. + </description> + </method> + <method name="snapped" qualifiers="const"> + <return type="Vector4" /> + <argument index="0" name="step" type="Vector4" /> + <description> + Returns this vector with each component snapped to the nearest multiple of [code]step[/code]. This can also be used to round to an arbitrary number of decimals. </description> </method> </methods> <members> <member name="w" type="float" setter="" getter="" default="0.0"> + The vector's W component. Also accessible by using the index position [code][3][/code]. </member> <member name="x" type="float" setter="" getter="" default="0.0"> + The vector's X component. Also accessible by using the index position [code][0][/code]. </member> <member name="y" type="float" setter="" getter="" default="0.0"> + The vector's Y component. Also accessible by using the index position [code][1][/code]. </member> <member name="z" type="float" setter="" getter="" default="0.0"> + The vector's Z component. Also accessible by using the index position [code][2][/code]. </member> </members> <constants> <constant name="AXIS_X" value="0"> + Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index]. </constant> <constant name="AXIS_Y" value="1"> + Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index]. </constant> <constant name="AXIS_Z" value="2"> + Enumerated value for the Z axis. Returned by [method max_axis_index] and [method min_axis_index]. </constant> <constant name="AXIS_W" value="3"> + Enumerated value for the W axis. Returned by [method max_axis_index] and [method min_axis_index]. </constant> - <constant name="ZERO" value="Vector4(0, 0, 0)"> + <constant name="ZERO" value="Vector4(0, 0, 0, 0)"> + Zero vector, a vector with all components set to [code]0[/code]. </constant> - <constant name="ONE" value="Vector4(1, 1, 1)"> + <constant name="ONE" value="Vector4(1, 1, 1, 1)"> + One vector, a vector with all components set to [code]1[/code]. </constant> - <constant name="INF" value="Vector4(inf, inf, inf)"> + <constant name="INF" value="Vector4(inf, inf, inf, inf)"> + Infinity vector, a vector with all components set to [constant @GDScript.INF]. </constant> </constants> <operators> @@ -131,100 +233,144 @@ <return type="bool" /> <argument index="0" name="right" type="Vector4" /> <description> + Returns [code]true[/code] if the vectors are not equal. + [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. </description> </operator> <operator name="operator *"> <return type="Vector4" /> <argument index="0" name="right" type="Projection" /> <description> + Inversely transforms (multiplies) the [Vector4] by the given [Projection] matrix. </description> </operator> <operator name="operator *"> <return type="Vector4" /> <argument index="0" name="right" type="Vector4" /> <description> + Multiplies each component of the [Vector4] by the components of the given [Vector4]. + [codeblock] + print(Vector4(10, 20, 30, 40) * Vector4(3, 4, 5, 6)) # Prints "(30, 80, 150, 240)" + [/codeblock] </description> </operator> <operator name="operator *"> <return type="Vector4" /> <argument index="0" name="right" type="float" /> <description> + Multiplies each component of the [Vector4] by the given [float]. + [codeblock] + print(Vector4(10, 20, 30, 40) * 2) # Prints "(20, 40, 60, 80)" + [/codeblock] </description> </operator> <operator name="operator *"> <return type="Vector4" /> <argument index="0" name="right" type="int" /> <description> + Multiplies each component of the [Vector4] by the given [int]. </description> </operator> <operator name="operator +"> <return type="Vector4" /> <argument index="0" name="right" type="Vector4" /> <description> + Adds each component of the [Vector4] by the components of the given [Vector4]. + [codeblock] + print(Vector4(10, 20, 30, 40) + Vector4(3, 4, 5, 6)) # Prints "(13, 24, 35, 46)" + [/codeblock] </description> </operator> <operator name="operator -"> <return type="Vector4" /> <argument index="0" name="right" type="Vector4" /> <description> + Subtracts each component of the [Vector4] by the components of the given [Vector4]. + [codeblock] + print(Vector4(10, 20, 30, 40) - Vector4(3, 4, 5, 6)) # Prints "(7, 16, 25, 34)" + [/codeblock] </description> </operator> <operator name="operator /"> <return type="Vector4" /> <argument index="0" name="right" type="Vector4" /> <description> + Divides each component of the [Vector4] by the components of the given [Vector4]. + [codeblock] + print(Vector4(10, 20, 30, 40) / Vector4(2, 5, 3, 4)) # Prints "(5, 4, 10, 10)" + [/codeblock] </description> </operator> <operator name="operator /"> <return type="Vector4" /> <argument index="0" name="right" type="float" /> <description> + Divides each component of the [Vector4] by the given [float]. + [codeblock] + print(Vector4(10, 20, 30, 40) / 2 # Prints "(5, 10, 15, 20)" + [/codeblock] </description> </operator> <operator name="operator /"> <return type="Vector4" /> <argument index="0" name="right" type="int" /> <description> + Divides each component of the [Vector4] by the given [int]. </description> </operator> <operator name="operator <"> <return type="bool" /> <argument index="0" name="right" type="Vector4" /> <description> + Compares two [Vector4] vectors by first checking if the X value of the left vector is less than the X value of the [code]right[/code] vector. If the X values are exactly equal, then it repeats this check with the Y values of the two vectors, Z values of the two vectors, and then with the W values. This operator is useful for sorting vectors. </description> </operator> <operator name="operator <="> <return type="bool" /> <argument index="0" name="right" type="Vector4" /> <description> + Compares two [Vector4] vectors by first checking if the X value of the left vector is less than or equal to the X value of the [code]right[/code] vector. If the X values are exactly equal, then it repeats this check with the Y values of the two vectors, Z values of the two vectors, and then with the W values. This operator is useful for sorting vectors. </description> </operator> <operator name="operator =="> <return type="bool" /> <argument index="0" name="right" type="Vector4" /> <description> + Returns [code]true[/code] if the vectors are exactly equal. + [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. </description> </operator> <operator name="operator >"> <return type="bool" /> <argument index="0" name="right" type="Vector4" /> <description> + Compares two [Vector4] vectors by first checking if the X value of the left vector is greater than the X value of the [code]right[/code] vector. If the X values are exactly equal, then it repeats this check with the Y values of the two vectors, Z values of the two vectors, and then with the W values. This operator is useful for sorting vectors. </description> </operator> <operator name="operator >="> <return type="bool" /> <argument index="0" name="right" type="Vector4" /> <description> + Access vector components using their index. [code]v[0][/code] is equivalent to [code]v.x[/code], [code]v[1][/code] is equivalent to [code]v.y[/code], and [code]v[2][/code] is equivalent to [code]v.z[/code]. + </description> + </operator> + <operator name="operator []"> + <return type="float" /> + <argument index="0" name="index" type="int" /> + <description> + Access vector components using their index. [code]v[0][/code] is equivalent to [code]v.x[/code], [code]v[1][/code] is equivalent to [code]v.y[/code], [code]v[2][/code] is equivalent to [code]v.z[/code], and [code]v[3][/code] is equivalent to [code]v.w[/code]. </description> </operator> <operator name="operator unary+"> <return type="Vector4" /> <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> </operator> <operator name="operator unary-"> <return type="Vector4" /> <description> + Returns the negative value of the [Vector4]. This is the same as writing [code]Vector4(-v.x, -v.y, -v.z, -v.w)[/code]. This operation flips the direction of the vector while keeping the same magnitude. With floats, the number zero can be either positive or negative. </description> </operator> </operators> diff --git a/doc/classes/Vector4i.xml b/doc/classes/Vector4i.xml index c3114e20e2..6acce12e9f 100644 --- a/doc/classes/Vector4i.xml +++ b/doc/classes/Vector4i.xml @@ -92,9 +92,9 @@ </constant> <constant name="AXIS_W" value="3"> </constant> - <constant name="ZERO" value="Vector4i(0, 0, 0)"> + <constant name="ZERO" value="Vector4i(0, 0, 0, 0)"> </constant> - <constant name="ONE" value="Vector4i(1, 1, 1)"> + <constant name="ONE" value="Vector4i(1, 1, 1, 1)"> </constant> </constants> <operators> @@ -194,6 +194,12 @@ <description> </description> </operator> + <operator name="operator []"> + <return type="int" /> + <argument index="0" name="index" type="int" /> + <description> + </description> + </operator> <operator name="operator unary+"> <return type="Vector4i" /> <description> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 53603b5356..0808a8f1cf 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -196,10 +196,6 @@ <member name="disable_3d" type="bool" setter="set_disable_3d" getter="is_3d_disabled" default="false"> Disable 3D rendering (but keep 2D rendering). </member> - <member name="fsr_mipmap_bias" type="float" setter="set_fsr_mipmap_bias" getter="get_fsr_mipmap_bias" default="0.0"> - Affects the final texture sharpness by reading from a lower or higher mipmap when using FSR. Mipmap bias does nothing when FSR is not being used. Negative values make textures sharper, while positive values make textures blurrier. This value is used to adjust the mipmap bias calculated internally which is based on the selected quality. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code]. This updates the rendering server's mipmap bias when called - To control this property on the root viewport, set the [member ProjectSettings.rendering/scaling_3d/fsr_mipmap_bias] project setting. - </member> <member name="fsr_sharpness" type="float" setter="set_fsr_sharpness" getter="get_fsr_sharpness" default="0.2"> Determines how sharp the upscaled image will be when using the FSR upscaling mode. Sharpness halves with every whole number. Values go from 0.0 (sharpest) to 2.0. Values above 2.0 won't make a visible difference. To control this property on the root viewport, set the [member ProjectSettings.rendering/scaling_3d/fsr_sharpness] project setting. @@ -270,6 +266,11 @@ </member> <member name="snap_2d_vertices_to_pixel" type="bool" setter="set_snap_2d_vertices_to_pixel" getter="is_snap_2d_vertices_to_pixel_enabled" default="false"> </member> + <member name="texture_mipmap_bias" type="float" setter="set_texture_mipmap_bias" getter="get_texture_mipmap_bias" default="0.0"> + Affects the final texture sharpness by reading from a lower or higher mipmap (also called "texture LOD bias"). Negative values make mipmapped textures sharper but grainier when viewed at a distance, while positive values make mipmapped textures blurrier (even when up close). To get sharper textures at a distance without introducing too much graininess, set this between [code]-0.75[/code] and [code]0.0[/code]. Enabling temporal antialiasing ([member ProjectSettings.rendering/anti_aliasing/quality/use_taa]) can help reduce the graininess visible when using negative mipmap bias. + [b]Note:[/b] When the 3D scaling mode is set to FSR 1.0, this value is used to adjust the automatic mipmap bias which is calculated internally based on the scale factor. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code]. + To control this property on the root viewport, set the [member ProjectSettings.rendering/textures/default_filters/texture_mipmap_bias] project setting. + </member> <member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background" default="false"> If [code]true[/code], the viewport should render its background as transparent. </member> diff --git a/doc/classes/VisualShaderNodeTextureUniform.xml b/doc/classes/VisualShaderNodeTextureUniform.xml index bff6f2015d..9014f79f54 100644 --- a/doc/classes/VisualShaderNodeTextureUniform.xml +++ b/doc/classes/VisualShaderNodeTextureUniform.xml @@ -39,12 +39,15 @@ Represents the size of the [enum TextureType] enum. </constant> <constant name="COLOR_DEFAULT_WHITE" value="0" enum="ColorDefault"> - Defaults to white color. + Defaults to fully opaque white color. </constant> <constant name="COLOR_DEFAULT_BLACK" value="1" enum="ColorDefault"> - Defaults to black color. + Defaults to fully opaque black color. </constant> - <constant name="COLOR_DEFAULT_MAX" value="2" enum="ColorDefault"> + <constant name="COLOR_DEFAULT_TRANSPARENT" value="2" enum="ColorDefault"> + Defaults to fully transparent black color. + </constant> + <constant name="COLOR_DEFAULT_MAX" value="3" enum="ColorDefault"> Represents the size of the [enum ColorDefault] enum. </constant> <constant name="FILTER_DEFAULT" value="0" enum="TextureFilter"> diff --git a/doc/classes/VisualShaderNodeVectorRefract.xml b/doc/classes/VisualShaderNodeVectorRefract.xml index d12188ea55..003b505671 100644 --- a/doc/classes/VisualShaderNodeVectorRefract.xml +++ b/doc/classes/VisualShaderNodeVectorRefract.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorRefract" inherits="VisualShaderNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeVectorRefract" inherits="VisualShaderNodeVectorBase" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - Returns the [Vector3] that points in the direction of refraction. For use within the visual shader graph. + Returns the vector that points in the direction of refraction. For use within the visual shader graph. </brief_description> <description> Translated to [code]refract(I, N, eta)[/code] in the shader language, where [code]I[/code] is the incident vector, [code]N[/code] is the normal vector and [code]eta[/code] is the ratio of the indices of the refraction. diff --git a/doc/classes/VoxelGIData.xml b/doc/classes/VoxelGIData.xml index b8d424b5fe..9198da4bc6 100644 --- a/doc/classes/VoxelGIData.xml +++ b/doc/classes/VoxelGIData.xml @@ -72,10 +72,10 @@ <member name="normal_bias" type="float" setter="set_normal_bias" getter="get_normal_bias" default="0.0"> The normal bias to use for indirect lighting and reflections. Higher values reduce self-reflections visible in non-rough materials, at the cost of more visible light leaking and flatter-looking indirect lighting. See also [member bias]. To prioritize hiding self-reflections over lighting quality, set [member bias] to [code]0.0[/code] and [member normal_bias] to a value between [code]1.0[/code] and [code]2.0[/code]. </member> - <member name="propagation" type="float" setter="set_propagation" getter="get_propagation" default="0.7"> - If indirect lighting looks too flat, try decreasing [member propagation] while increasing [member energy] at the same time. See also [member use_two_bounces] which influences the indirect lighting's effective brightness. + <member name="propagation" type="float" setter="set_propagation" getter="get_propagation" default="0.5"> + The multiplier to use when light bounces off a surface. Higher values result in brighter indirect lighting. If indirect lighting looks too flat, try decreasing [member propagation] while increasing [member energy] at the same time. See also [member use_two_bounces] which influences the indirect lighting's effective brightness. </member> - <member name="use_two_bounces" type="bool" setter="set_use_two_bounces" getter="is_using_two_bounces" default="false"> + <member name="use_two_bounces" type="bool" setter="set_use_two_bounces" getter="is_using_two_bounces" default="true"> If [code]true[/code], performs two bounces of indirect lighting instead of one. This makes indirect lighting look more natural and brighter at a small performance cost. The second bounce is also visible in reflections. If the scene appears too bright after enabling [member use_two_bounces], adjust [member propagation] and [member energy]. </member> </members> diff --git a/doc/classes/WeakRef.xml b/doc/classes/WeakRef.xml index f80381acda..ea520178c7 100644 --- a/doc/classes/WeakRef.xml +++ b/doc/classes/WeakRef.xml @@ -12,7 +12,7 @@ <method name="get_ref" qualifiers="const"> <return type="Variant" /> <description> - Returns the [Object] this weakref is referring to. + Returns the [Object] this weakref is referring to. Returns [code]null[/code] if that object no longer exists. </description> </method> </methods> diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index f4eaaac2e1..84f3b6a4b1 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -344,9 +344,11 @@ </member> <member name="max_size" type="Vector2i" setter="set_max_size" getter="get_max_size" default="Vector2i(0, 0)"> If non-zero, the [Window] can't be resized to be bigger than this size. + [b]Note:[/b] This property will be ignored if the value is lower than [member min_size]. </member> <member name="min_size" type="Vector2i" setter="set_min_size" getter="get_min_size" default="Vector2i(0, 0)"> If non-zero, the [Window] can't be resized to be smaller than this size. + [b]Note:[/b] This property will be ignored in favor of [method get_contents_minimum_size] if [member wrap_controls] is enabled and if its size is bigger. </member> <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="Window.Mode" default="0"> Set's the window's current mode. @@ -388,7 +390,7 @@ If [code]true[/code], the window is visible. </member> <member name="wrap_controls" type="bool" setter="set_wrap_controls" getter="is_wrapping_controls" default="false"> - If [code]true[/code], the window's size will automatically update when a child node is added or removed. + If [code]true[/code], the window's size will automatically update when a child node is added or removed, ignoring [member min_size] if the new size is bigger. If [code]false[/code], you need to call [method child_controls_changed] manually. </member> </members> diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py index 312dffc7ee..196a26ef77 100755 --- a/doc/tools/make_rst.py +++ b/doc/tools/make_rst.py @@ -9,9 +9,12 @@ import re import sys import xml.etree.ElementTree as ET from collections import OrderedDict +from typing import List, Dict, TextIO, Tuple, Optional, Any, Union -# Uncomment to do type checks. I have it commented out so it works below Python 3.5 -# from typing import List, Dict, TextIO, Tuple, Iterable, Optional, DefaultDict, Any, Union +# Import hardcoded version information from version.py +root_directory = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../") +sys.path.append(root_directory) # Include the root directory +import version # $DOCS_URL/path/to/page.html(#fragment-tag) GODOT_DOCS_PATTERN = re.compile(r"^\$DOCS_URL/(.*)\.html(#.*)?$") @@ -56,126 +59,18 @@ BASE_STRINGS = [ "This method doesn't need an instance to be called, so it can be called directly using the class name.", "This method describes a valid operator to use with this type as left-hand operand.", ] -strings_l10n = {} +strings_l10n: Dict[str, str] = {} -STYLES = {} - - -def print_error(error, state): # type: (str, State) -> None - print("{}{}ERROR:{} {}{}".format(STYLES["red"], STYLES["bold"], STYLES["regular"], error, STYLES["reset"])) - state.num_errors += 1 - - -class TypeName: - def __init__(self, type_name, enum=None): # type: (str, Optional[str]) -> None - self.type_name = type_name - self.enum = enum - - def to_rst(self, state): # type: ("State") -> str - if self.enum is not None: - return make_enum(self.enum, state) - elif self.type_name == "void": - return "void" - else: - return make_type(self.type_name, state) - - @classmethod - def from_element(cls, element): # type: (ET.Element) -> "TypeName" - return cls(element.attrib["type"], element.get("enum")) - - -class PropertyDef: - def __init__( - self, name, type_name, setter, getter, text, default_value, overrides - ): # type: (str, TypeName, Optional[str], Optional[str], Optional[str], Optional[str], Optional[str]) -> None - self.name = name - self.type_name = type_name - self.setter = setter - self.getter = getter - self.text = text - self.default_value = default_value - self.overrides = overrides - - -class ParameterDef: - def __init__(self, name, type_name, default_value): # type: (str, TypeName, Optional[str]) -> None - self.name = name - self.type_name = type_name - self.default_value = default_value - - -class SignalDef: - def __init__(self, name, parameters, description): # type: (str, List[ParameterDef], Optional[str]) -> None - self.name = name - self.parameters = parameters - self.description = description - - -class MethodDef: - def __init__( - self, name, return_type, parameters, description, qualifiers - ): # type: (str, TypeName, List[ParameterDef], Optional[str], Optional[str]) -> None - self.name = name - self.return_type = return_type - self.parameters = parameters - self.description = description - self.qualifiers = qualifiers - - -class ConstantDef: - def __init__(self, name, value, text, bitfield): # type: (str, str, Optional[str], Optional[bool]) -> None - self.name = name - self.value = value - self.text = text - self.is_bitfield = bitfield - - -class EnumDef: - def __init__(self, name, bitfield): # type: (str, Optional[bool]) -> None - self.name = name - self.values = OrderedDict() # type: OrderedDict[str, ConstantDef] - self.is_bitfield = bitfield - - -class ThemeItemDef: - def __init__( - self, name, type_name, data_name, text, default_value - ): # type: (str, TypeName, str, Optional[str], Optional[str]) -> None - self.name = name - self.type_name = type_name - self.data_name = data_name - self.text = text - self.default_value = default_value - - -class ClassDef: - def __init__(self, name): # type: (str) -> None - self.name = name - self.constants = OrderedDict() # type: OrderedDict[str, ConstantDef] - self.enums = OrderedDict() # type: OrderedDict[str, EnumDef] - self.properties = OrderedDict() # type: OrderedDict[str, PropertyDef] - self.constructors = OrderedDict() # type: OrderedDict[str, List[MethodDef]] - self.methods = OrderedDict() # type: OrderedDict[str, List[MethodDef]] - self.operators = OrderedDict() # type: OrderedDict[str, List[MethodDef]] - self.signals = OrderedDict() # type: OrderedDict[str, SignalDef] - self.annotations = OrderedDict() # type: OrderedDict[str, List[MethodDef]] - self.theme_items = OrderedDict() # type: OrderedDict[str, ThemeItemDef] - self.inherits = None # type: Optional[str] - self.brief_description = None # type: Optional[str] - self.description = None # type: Optional[str] - self.tutorials = [] # type: List[Tuple[str, str]] - - # Used to match the class with XML source for output filtering purposes. - self.filepath = "" # type: str +STYLES: Dict[str, str] = {} class State: - def __init__(self): # type: () -> None + def __init__(self) -> None: self.num_errors = 0 - self.classes = OrderedDict() # type: OrderedDict[str, ClassDef] - self.current_class = "" # type: str + self.classes: OrderedDict[str, ClassDef] = OrderedDict() + self.current_class: str = "" - def parse_class(self, class_root, filepath): # type: (ET.Element, str) -> None + def parse_class(self, class_root: ET.Element, filepath: str) -> None: class_name = class_root.attrib["name"] class_def = ClassDef(class_name) @@ -228,7 +123,6 @@ class State: return_element = constructor.find("return") if return_element is not None: return_type = TypeName.from_element(return_element) - else: return_type = TypeName("void") @@ -309,7 +203,7 @@ class State: constant_name = constant.attrib["name"] value = constant.attrib["value"] enum = constant.get("enum") - is_bitfield = constant.get("is_bitfield") or False + is_bitfield = constant.get("is_bitfield") == "true" constant_def = ConstantDef(constant_name, value, constant.text, is_bitfield) if enum is None: if constant_name in class_def.constants: @@ -343,7 +237,7 @@ class State: if desc_element is not None: annotation_desc = desc_element.text - annotation_def = MethodDef(annotation_name, return_type, params, annotation_desc, qualifiers) + annotation_def = AnnotationDef(annotation_name, params, annotation_desc, qualifiers) if annotation_name not in class_def.annotations: class_def.annotations[annotation_name] = [] @@ -408,13 +302,147 @@ class State: if link.text is not None: class_def.tutorials.append((link.text.strip(), link.get("title", ""))) - def sort_classes(self): # type: () -> None + def sort_classes(self) -> None: self.classes = OrderedDict(sorted(self.classes.items(), key=lambda t: t[0])) -def parse_arguments(root): # type: (ET.Element) -> List[ParameterDef] +class TypeName: + def __init__(self, type_name: str, enum: Optional[str] = None) -> None: + self.type_name = type_name + self.enum = enum + + def to_rst(self, state: State) -> str: + if self.enum is not None: + return make_enum(self.enum, state) + elif self.type_name == "void": + return "void" + else: + return make_type(self.type_name, state) + + @classmethod + def from_element(cls, element: ET.Element) -> "TypeName": + return cls(element.attrib["type"], element.get("enum")) + + +class PropertyDef: + def __init__( + self, + name: str, + type_name: TypeName, + setter: Optional[str], + getter: Optional[str], + text: Optional[str], + default_value: Optional[str], + overrides: Optional[str], + ) -> None: + self.name = name + self.type_name = type_name + self.setter = setter + self.getter = getter + self.text = text + self.default_value = default_value + self.overrides = overrides + + +class ParameterDef: + def __init__(self, name: str, type_name: TypeName, default_value: Optional[str]) -> None: + self.name = name + self.type_name = type_name + self.default_value = default_value + + +class SignalDef: + def __init__(self, name: str, parameters: List[ParameterDef], description: Optional[str]) -> None: + self.name = name + self.parameters = parameters + self.description = description + + +class AnnotationDef: + def __init__( + self, + name: str, + parameters: List[ParameterDef], + description: Optional[str], + qualifiers: Optional[str], + ) -> None: + self.name = name + self.parameters = parameters + self.description = description + self.qualifiers = qualifiers + + +class MethodDef: + def __init__( + self, + name: str, + return_type: TypeName, + parameters: List[ParameterDef], + description: Optional[str], + qualifiers: Optional[str], + ) -> None: + self.name = name + self.return_type = return_type + self.parameters = parameters + self.description = description + self.qualifiers = qualifiers + + +class ConstantDef: + def __init__(self, name: str, value: str, text: Optional[str], bitfield: bool) -> None: + self.name = name + self.value = value + self.text = text + self.is_bitfield = bitfield + + +class EnumDef: + def __init__(self, name: str, bitfield: bool) -> None: + self.name = name + self.values: OrderedDict[str, ConstantDef] = OrderedDict() + self.is_bitfield = bitfield + + +class ThemeItemDef: + def __init__( + self, name: str, type_name: TypeName, data_name: str, text: Optional[str], default_value: Optional[str] + ) -> None: + self.name = name + self.type_name = type_name + self.data_name = data_name + self.text = text + self.default_value = default_value + + +class ClassDef: + def __init__(self, name: str) -> None: + self.name = name + self.constants: OrderedDict[str, ConstantDef] = OrderedDict() + self.enums: OrderedDict[str, EnumDef] = OrderedDict() + self.properties: OrderedDict[str, PropertyDef] = OrderedDict() + self.constructors: OrderedDict[str, List[MethodDef]] = OrderedDict() + self.methods: OrderedDict[str, List[MethodDef]] = OrderedDict() + self.operators: OrderedDict[str, List[MethodDef]] = OrderedDict() + self.signals: OrderedDict[str, SignalDef] = OrderedDict() + self.annotations: OrderedDict[str, List[AnnotationDef]] = OrderedDict() + self.theme_items: OrderedDict[str, ThemeItemDef] = OrderedDict() + self.inherits: Optional[str] = None + self.brief_description: Optional[str] = None + self.description: Optional[str] = None + self.tutorials: List[Tuple[str, str]] = [] + + # Used to match the class with XML source for output filtering purposes. + self.filepath: str = "" + + +def print_error(error: str, state: State) -> None: + print("{}{}ERROR:{} {}{}".format(STYLES["red"], STYLES["bold"], STYLES["regular"], error, STYLES["reset"])) + state.num_errors += 1 + + +def parse_arguments(root: ET.Element) -> List[ParameterDef]: param_elements = root.findall("argument") - params = [None] * len(param_elements) # type: Any + params: Any = [None] * len(param_elements) for param_element in param_elements: param_name = param_element.attrib["name"] index = int(param_element.attrib["index"]) @@ -423,16 +451,16 @@ def parse_arguments(root): # type: (ET.Element) -> List[ParameterDef] params[index] = ParameterDef(param_name, type_name, default) - cast = params # type: List[ParameterDef] + cast: List[ParameterDef] = params return cast -def main(): # type: () -> None +def main() -> None: # Enable ANSI escape code support on Windows 10 and later (for colored console output). # <https://bugs.python.org/issue29059> if platform.system().lower() == "windows": - from ctypes import windll, c_int, byref + from ctypes import windll, c_int, byref # type: ignore stdout_handle = windll.kernel32.GetStdHandle(c_int(-11)) mode = c_int(0) @@ -486,7 +514,7 @@ def main(): # type: () -> None print("Checking for errors in the XML class reference...") - file_list = [] # type: List[str] + file_list: List[str] = [] for path in args.path: # Cut off trailing slashes so os.path.basename doesn't choke. @@ -510,7 +538,7 @@ def main(): # type: () -> None file_list.append(path) - classes = {} # type: Dict[str, ET.Element] + classes: Dict[str, Tuple[ET.Element, str]] = {} state = State() for cur_file in file_list: @@ -571,7 +599,7 @@ def main(): # type: () -> None exit(1) -def translate(string): # type: (str) -> str +def translate(string: str) -> str: """Translate a string based on translations sourced from `doc/translations/*.po` for a language if defined via the --lang command line argument. Returns the original string if no translation exists. @@ -579,7 +607,7 @@ def translate(string): # type: (str) -> str return strings_l10n.get(string, string) -def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, State, bool, str) -> None +def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir: str) -> None: class_name = class_def.name if dry_run: @@ -587,12 +615,26 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S else: f = open(os.path.join(output_dir, "class_" + class_name.lower() + ".rst"), "w", encoding="utf-8") - # Warn contributors not to edit this file directly + # Remove the "Edit on Github" button from the online docs page. f.write(":github_url: hide\n\n") - f.write(".. Generated automatically by doc/tools/make_rst.py in Godot's source tree.\n") - f.write(".. DO NOT EDIT THIS FILE, but the " + class_name + ".xml source instead.\n") - f.write(".. The source is found in doc/classes or modules/<name>/doc_classes.\n\n") + # Warn contributors not to edit this file directly. + # Also provide links to the source files for reference. + + git_branch = "master" + if hasattr(version, "docs") and version.docs != "latest": + git_branch = version.docs + + source_xml_path = os.path.relpath(class_def.filepath, root_directory).replace("\\", "/") + source_github_url = "https://github.com/godotengine/godot/tree/{}/{}".format(git_branch, source_xml_path) + generator_github_url = "https://github.com/godotengine/godot/tree/{}/doc/tools/make_rst.py".format(git_branch) + + f.write(".. DO NOT EDIT THIS FILE!!!\n") + f.write(".. Generated automatically from Godot engine sources.\n") + f.write(".. Generator: " + generator_github_url + ".\n") + f.write(".. XML source: " + source_github_url + ".\n\n") + + # Document reference id and header. f.write(".. _class_" + class_name + ":\n\n") f.write(make_heading(class_name, "=", False)) @@ -616,8 +658,8 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S break f.write("\n\n") - # Descendents - inherited = [] + # Descendants + inherited: List[str] = [] for c in state.classes.values(): if c.inherits and c.inherits.strip() == class_name: inherited.append(c.name) @@ -648,7 +690,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S # Properties overview if len(class_def.properties) > 0: f.write(make_heading("Properties", "-")) - ml = [] # type: List[Tuple[str, str, str]] + ml: List[Tuple[Optional[str], ...]] = [] for property_def in class_def.properties.values(): type_rst = property_def.type_name.to_rst(state) default = property_def.default_value @@ -664,7 +706,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S # Constructors, Methods, Operators overview if len(class_def.constructors) > 0: f.write(make_heading("Constructors", "-")) - ml = [] + ml: List[Tuple[Optional[str], ...]] = [] for method_list in class_def.constructors.values(): for m in method_list: ml.append(make_method_signature(class_def, m, "constructor", state)) @@ -672,7 +714,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S if len(class_def.methods) > 0: f.write(make_heading("Methods", "-")) - ml = [] + ml: List[Tuple[Optional[str], ...]] = [] for method_list in class_def.methods.values(): for m in method_list: ml.append(make_method_signature(class_def, m, "method", state)) @@ -680,7 +722,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S if len(class_def.operators) > 0: f.write(make_heading("Operators", "-")) - ml = [] + ml: List[Tuple[Optional[str], ...]] = [] for method_list in class_def.operators.values(): for m in method_list: ml.append(make_method_signature(class_def, m, "operator", state)) @@ -689,7 +731,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S # Theme properties if len(class_def.theme_items) > 0: f.write(make_heading("Theme Properties", "-")) - pl = [] + pl: List[Tuple[Optional[str], ...]] = [] for theme_item_def in class_def.theme_items.values(): ref = ":ref:`{0}<class_{2}_theme_{1}_{0}>`".format( theme_item_def.name, theme_item_def.data_name, class_name @@ -762,6 +804,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S f.write("\n\n") + # Annotations if len(class_def.annotations) > 0: f.write(make_heading("Annotations", "-")) index = 0 @@ -774,8 +817,8 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S if i == 0: f.write(".. _class_{}_annotation_{}:\n\n".format(class_name, m.name.strip("@"))) - ret_type, signature = make_method_signature(class_def, m, "", state) - f.write("- {} {}\n\n".format(ret_type, signature)) + _, signature = make_method_signature(class_def, m, "", state) + f.write("- {}\n\n".format(signature)) if m.description is not None and m.description.strip() != "": f.write(rstize_text(m.description.strip(), state) + "\n\n") @@ -797,7 +840,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S f.write(".. _class_{}_property_{}:\n\n".format(class_name, property_def.name)) f.write("- {} **{}**\n\n".format(property_def.type_name.to_rst(state), property_def.name)) - info = [] + info: List[Tuple[Optional[str], ...]] = [] # Not using translate() for now as it breaks table formatting. if property_def.default_value is not None: info.append(("*" + "Default" + "*", property_def.default_value)) @@ -907,7 +950,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S f.write(make_footer()) -def escape_rst(text, until_pos=-1): # type: (str) -> str +def escape_rst(text: str, until_pos: int = -1) -> str: # Escape \ character, otherwise it ends up as an escape character in rst pos = 0 while True: @@ -941,7 +984,7 @@ def escape_rst(text, until_pos=-1): # type: (str) -> str return text -def format_codeblock(code_type, post_text, indent_level, state): # types: str, str, int, state +def format_codeblock(code_type: str, post_text: str, indent_level: int, state: State) -> Union[Tuple[str, int], None]: end_pos = post_text.find("[/" + code_type + "]") if end_pos == -1: print_error("{}.xml: [" + code_type + "] without a closing tag.".format(state.current_class), state) @@ -975,10 +1018,10 @@ def format_codeblock(code_type, post_text, indent_level, state): # types: str, else: code_text = code_text[:code_pos] + "\n " + code_text[code_pos + to_skip + 1 :] code_pos += 5 - to_skip - return ["\n[" + code_type + "]" + code_text + post_text, len("\n[" + code_type + "]" + code_text)] + return ("\n[" + code_type + "]" + code_text + post_text, len("\n[" + code_type + "]" + code_text)) -def rstize_text(text, state): # type: (str, State) -> str +def rstize_text(text: str, state: State) -> str: # Linebreak + tabs in the XML should become two line breaks unless in a "codeblock" pos = 0 while True: @@ -1018,7 +1061,6 @@ def rstize_text(text, state): # type: (str, State) -> str inside_code = False pos = 0 tag_depth = 0 - previous_pos = 0 while True: pos = text.find("[", pos) if pos == -1: @@ -1185,7 +1227,6 @@ def rstize_text(text, state): # type: (str, State) -> str text = pre_text + tag_text + post_text pos = len(pre_text) + len(tag_text) - previous_pos = pos continue elif cmd == "center": tag_depth += 1 @@ -1291,7 +1332,6 @@ def rstize_text(text, state): # type: (str, State) -> str text = pre_text + tag_text + post_text pos = len(pre_text) + len(tag_text) - previous_pos = pos if tag_depth > 0: print_error( @@ -1301,7 +1341,7 @@ def rstize_text(text, state): # type: (str, State) -> str return text -def format_table(f, data, remove_empty_columns=False): # type: (TextIO, Iterable[Tuple[str, ...]]) -> None +def format_table(f: TextIO, data: List[Tuple[Optional[str], ...]], remove_empty_columns: bool = False) -> None: if len(data) == 0: return @@ -1332,7 +1372,7 @@ def format_table(f, data, remove_empty_columns=False): # type: (TextIO, Iterabl f.write("\n") -def make_type(klass, state): # type: (str, State) -> str +def make_type(klass: str, state: State) -> str: if klass.find("*") != -1: # Pointer, ignore return klass link_type = klass @@ -1344,7 +1384,7 @@ def make_type(klass, state): # type: (str, State) -> str return klass -def make_enum(t, state): # type: (str, State) -> str +def make_enum(t: str, state: State) -> str: p = t.find(".") if p >= 0: c = t[0:p] @@ -1370,31 +1410,36 @@ def make_enum(t, state): # type: (str, State) -> str def make_method_signature( - class_def, method_def, ref_type, state -): # type: (ClassDef, Union[MethodDef, SignalDef], str, State) -> Tuple[str, str] - ret_type = " " + class_def: ClassDef, definition: Union[AnnotationDef, MethodDef, SignalDef], ref_type: str, state: State +) -> Tuple[str, str]: + ret_type = "" + + is_method_def = isinstance(definition, MethodDef) + if is_method_def: + ret_type = definition.return_type.to_rst(state) - if isinstance(method_def, MethodDef): - ret_type = method_def.return_type.to_rst(state) + qualifiers = None + if is_method_def or isinstance(definition, AnnotationDef): + qualifiers = definition.qualifiers out = "" - if ref_type != "": + if is_method_def and ref_type != "": if ref_type == "operator": out += ":ref:`{0}<class_{1}_{2}_{3}_{4}>` ".format( - method_def.name, + definition.name.replace("<", "\\<"), # So operator "<" gets correctly displayed. class_def.name, ref_type, - sanitize_operator_name(method_def.name, state), - method_def.return_type.type_name, + sanitize_operator_name(definition.name, state), + definition.return_type.type_name, ) else: - out += ":ref:`{0}<class_{1}_{2}_{0}>` ".format(method_def.name, class_def.name, ref_type) + out += ":ref:`{0}<class_{1}_{2}_{0}>` ".format(definition.name, class_def.name, ref_type) else: - out += "**{}** ".format(method_def.name) + out += "**{}** ".format(definition.name) out += "**(**" - for i, arg in enumerate(method_def.parameters): + for i, arg in enumerate(definition.parameters): if i > 0: out += ", " else: @@ -1405,24 +1450,24 @@ def make_method_signature( if arg.default_value is not None: out += "=" + arg.default_value - if isinstance(method_def, MethodDef) and method_def.qualifiers is not None and "vararg" in method_def.qualifiers: - if len(method_def.parameters) > 0: + if qualifiers is not None and "vararg" in qualifiers: + if len(definition.parameters) > 0: out += ", ..." else: out += " ..." out += " **)**" - if isinstance(method_def, MethodDef) and method_def.qualifiers is not None: + if qualifiers is not None: # Use substitutions for abbreviations. This is used to display tooltips on hover. # See `make_footer()` for descriptions. - for qualifier in method_def.qualifiers.split(): + for qualifier in qualifiers.split(): out += " |" + qualifier + "|" return ret_type, out -def make_heading(title, underline, l10n=True): # type: (str, str, bool) -> str +def make_heading(title: str, underline: str, l10n: bool = True) -> str: if l10n: new_title = translate(title) if new_title != title: @@ -1431,7 +1476,7 @@ def make_heading(title, underline, l10n=True): # type: (str, str, bool) -> str return title + "\n" + (underline * len(title)) + "\n\n" -def make_footer(): # type: () -> str +def make_footer() -> str: # Generate reusable abbreviation substitutions. # This way, we avoid bloating the generated rST with duplicate abbreviations. # fmt: off @@ -1446,7 +1491,7 @@ def make_footer(): # type: () -> str # fmt: on -def make_link(url, title): # type: (str, str) -> str +def make_link(url: str, title: str) -> str: match = GODOT_DOCS_PATTERN.search(url) if match: groups = match.groups() @@ -1463,15 +1508,15 @@ def make_link(url, title): # type: (str, str) -> str if title != "": return ":doc:`" + title + " <../" + groups[0] + ">`" return ":doc:`../" + groups[0] + "`" - else: - # External link, for example: - # `http://enet.bespin.org/usergroup0.html` - if title != "": - return "`" + title + " <" + url + ">`__" - return "`" + url + " <" + url + ">`__" + + # External link, for example: + # `http://enet.bespin.org/usergroup0.html` + if title != "": + return "`" + title + " <" + url + ">`__" + return "`" + url + " <" + url + ">`__" -def sanitize_operator_name(dirty_name, state): # type: (str, State) -> str +def sanitize_operator_name(dirty_name: str, state: State) -> str: clear_name = dirty_name.replace("operator ", "") if clear_name == "!=": @@ -1529,7 +1574,7 @@ def sanitize_operator_name(dirty_name, state): # type: (str, State) -> str return clear_name -def indent_bullets(text): # type: (str) -> str +def indent_bullets(text: str) -> str: # Take the text and check each line for a bullet point represented by "-". # Where found, indent the given line by a further "\t". # Used to properly indent bullet points contained in the description for enum values. diff --git a/doc/translations/ar.po b/doc/translations/ar.po index a4488f3339..43e62ecab2 100644 --- a/doc/translations/ar.po +++ b/doc/translations/ar.po @@ -19,12 +19,14 @@ # Hamza Kalash <mogo.gogo170@gmail.com>, 2022. # ywmaa <ywmaa.personal@gmail.com>, 2022. # TabbyDev <Mandomody25@gmail.com>, 2022. +# عبد الرحمن أبو سعدة ||Abd Alrahman abo saada <abdalrahmanabs2005@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-05-31 22:35+0000\n" -"Last-Translator: TabbyDev <Mandomody25@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:56+0000\n" +"Last-Translator: عبد الرحمن أبو سعدة ||Abd Alrahman abo saada " +"<abdalrahmanabs2005@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/ar/>\n" "Language: ar\n" @@ -33,7 +35,7 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Weblate 4.13-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -1004,7 +1006,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7850,8 +7859,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11922,7 +11931,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20347,7 +20361,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23739,7 +23753,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25576,7 +25590,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32679,7 +32693,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32695,7 +32709,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32725,7 +32739,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36859,7 +36873,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37122,7 +37136,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37240,6 +37254,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -37794,7 +37854,7 @@ msgstr "" #: doc/classes/Node.xml msgid "Nodes and Scenes" -msgstr "" +msgstr "العقد و المشاهد" #: doc/classes/Node.xml msgid "All Demos" @@ -39937,7 +39997,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39949,7 +40015,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57735,7 +57802,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60636,8 +60703,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64269,13 +64336,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64287,13 +64355,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71202,7 +71271,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71287,6 +71360,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ca.po b/doc/translations/ca.po index bd84c415cc..2fce9a4d08 100644 --- a/doc/translations/ca.po +++ b/doc/translations/ca.po @@ -960,7 +960,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7797,8 +7804,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11866,7 +11873,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20277,7 +20289,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23666,7 +23678,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25497,7 +25509,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32593,7 +32605,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32609,7 +32621,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32639,7 +32651,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36739,7 +36751,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37000,7 +37012,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37114,6 +37126,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39811,7 +39869,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39823,7 +39887,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57577,7 +57642,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60468,8 +60533,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64092,13 +64157,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64110,13 +64176,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71002,7 +71069,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71087,6 +71158,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/classes.pot b/doc/translations/classes.pot index 90ebdbf9f3..b8187d24d5 100644 --- a/doc/translations/classes.pot +++ b/doc/translations/classes.pot @@ -840,7 +840,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7677,8 +7684,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11746,7 +11753,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20157,7 +20169,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23543,7 +23555,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25374,7 +25386,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32470,7 +32482,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32486,7 +32498,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32516,7 +32528,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36616,7 +36628,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36877,7 +36889,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36991,6 +37003,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39688,7 +39746,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39700,7 +39764,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57454,7 +57519,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60345,8 +60410,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63969,13 +64034,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63987,13 +64053,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -65801,11 +65868,11 @@ msgstr "" #: doc/classes/VehicleBody.xml msgid "" "Accelerates the vehicle by applying an engine force. The vehicle is only " -"sped up if the wheels that have [member VehicleWheel.use_as_traction] set " -"to [code]true[/code] and are in contact with a surface. The [member " -"RigidBody.mass] of the vehicle has an effect on the acceleration of the " -"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 " -"range for acceleration.\n" +"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to " +"[code]true[/code] and are in contact with a surface. The [member RigidBody." +"mass] of the vehicle has an effect on the acceleration of the vehicle. For a " +"vehicle with a mass set to 1000, try a value in the 25 - 50 range for " +"acceleration.\n" "[b]Note:[/b] The simulation does not take the effect of gears into account, " "you will need to add logic for this if you wish to simulate gears.\n" "A negative value will result in the vehicle reversing." @@ -65885,8 +65952,8 @@ msgstr "" #: doc/classes/VehicleWheel.xml msgid "" -"Accelerates the wheel by applying an engine force. The wheel is only sped " -"up if it is in contact with a surface. The [member RigidBody.mass] of the " +"Accelerates the wheel by applying an engine force. The wheel is only sped up " +"if it is in contact with a surface. The [member RigidBody.mass] of the " "vehicle has an effect on the acceleration of the vehicle. For a vehicle with " "a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n" "[b]Note:[/b] The simulation does not take the effect of gears into account, " @@ -70879,7 +70946,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70964,6 +71035,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/cs.po b/doc/translations/cs.po index 48a79d9ec3..878b7e9aae 100644 --- a/doc/translations/cs.po +++ b/doc/translations/cs.po @@ -1230,8 +1230,15 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "Jako [method print], ale tiskne pouze pokud je použita v debug módu." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8187,8 +8194,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12266,7 +12273,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20725,7 +20737,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24123,7 +24135,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25960,7 +25972,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33074,7 +33086,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33090,7 +33102,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33121,7 +33133,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37264,7 +37276,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37527,7 +37539,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37645,6 +37657,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40345,7 +40403,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40357,7 +40421,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58166,7 +58231,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61082,8 +61147,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64740,13 +64805,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64758,13 +64824,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71688,9 +71755,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Vrátí [code] true [/code], pokud je vektor normalizován, jinak false." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -71774,6 +71844,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/de.po b/doc/translations/de.po index ba4e24c02b..0cf8d9ae17 100644 --- a/doc/translations/de.po +++ b/doc/translations/de.po @@ -35,7 +35,7 @@ # spoadr <spoadr@gmx.ch>, 2021. # Tim <tim14speckenwirth@gmail.com>, 2021. # user <online141@gmx.de>, 2021. -# Jummit <jummit@web.de>, 2021. +# Jummit <jummit@web.de>, 2021, 2022. # Bastian <bastian.ike@gmail.com>, 2021. # KuhnChris <kuhnchris@kuhnchris.eu>, 2021. # Rémi Verschelde <remi@godotengine.org>, 2021. @@ -52,7 +52,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-06-22 23:17+0000\n" +"PO-Revision-Date: 2022-07-23 03:56+0000\n" "Last-Translator: Hans Peter <figefi6308@runqx.com>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/de/>\n" @@ -61,7 +61,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -534,7 +534,6 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml -#, fuzzy msgid "" "Compares two values by checking their actual contents, recursing into any " "[Array] or [Dictionary] up to its deepest level.\n" @@ -566,9 +565,9 @@ msgstr "" "- Für [code]Array[/code]s, [code]==[/code] werden die Arrays elementweise " "mit [code]==[/code] verglichen. Der Elemente-Vergleich ist also wieder " "einfach, nicht tief.\n" -"Zusammengefasst, immer wenn ein [code]Dictionary[/code] potentiell " -"involviert ist, und du einen wahren Inhaltsvergleich brauchst, musst du " -"[code]deep_equal[/code] verwenden." +"Zusammengefasst, immer wenn möglicherweise ein [code]Dictionary[/code] " +"involviert ist und du einen echten Inhaltsvergleich brauchst, verwende " +"[code]deep_equal[/code]." #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -969,7 +968,6 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml -#, fuzzy msgid "" "Linearly interpolates between two values by the factor defined in " "[code]weight[/code]. To perform interpolation, [code]weight[/code] should be " @@ -989,17 +987,24 @@ msgid "" "To perform eased interpolation with [method lerp], combine it with [method " "ease] or [method smoothstep]." msgstr "" -"Interpoliert einen normalisierten Wert linear zwischen zwei Grenzwerten. " -"Dies entspricht der Umkehrfunktion von [method inverse_lerp].\n" -"Wenn die [code]from[/code] und [code]to[/code] Argumente vom Typ [int] oder " -"[float] sind, dann ist der Rückgabewert ein [float].\n" -"Sind beide Argumente vom gleichen Typ ([Vector2], [Vector3] oder [Color]), " -"dann ist der Rückgabewert auch von diesem Typ ([code]lerp[/code] ruft dann " -"die Methode [code]lerp[/code] dieses Vektortyps auf).\n" +"Interpoliert linear zwischen zwei Werten mit dem in [code]weight[/code] " +"definierten Faktor. Um eine Interpolation durchzuführen, sollte " +"[code]Gewicht[/code] zwischen [code]0.0[/code] und [code]1.0[/code] " +"(einschließlich) liegen. Werte außerhalb dieses Bereichs sind jedoch " +"zulässig und können verwendet werden, um [i]Extrapolation[/i] " +"durchzuführen.\n" +"Wenn die Argumente [code]von[/code] und [code]bis[/code] vom Typ [int] oder " +"[float] sind, ist der Rückgabewert ein [float].\n" +"Wenn beide vom gleichen Vektortyp sind ([Vector2], [Vector3] oder [Color]), " +"ist der Rückgabewert vom gleichen Typ ([code]lerp[/code] ruft dann die " +"Methode [code]linear_interpolate[/code] des Vektortyps auf).\n" "[codeblock]\n" -"lerp(0, 4, 0.75) # Returns 3.0\n" -"lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Returns Vector2(2, 3.5)\n" -"[/codeblock]" +"lerp(0, 4, 0.75) # Gibt 3.0 zurück\n" +"lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Liefert Vector2(2, 3.5)\n" +"[/codeblock]\n" +"Siehe auch [method inverse_lerp], die die Umkehrung dieser Operation " +"durchführt. Um eine Interpolation mit [method lerp] durchzuführen, " +"kombiniere sie mit [method ease] oder [method smoothstep]." #: modules/gdscript/doc_classes/@GDScript.xml #, fuzzy @@ -1398,9 +1403,22 @@ msgstr "" "Trace aus." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Funktioniert wie [method print], gibt jedoch nur im Debug Modues Text aus." +"Gibt einen Stacktrace zum Quelltextort aus, funktioniert nur wenn das " +"\"Ausführen mit Debugger\" aktiviert ist.\n" +"Die Ausgabe in der Konsole würde ungefähr so aussehen:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -1660,6 +1678,45 @@ msgid "" "3\n" "[/codeblock]" msgstr "" +"Gibt ein Array mit dem angegebenen Bereich zurück. Die [Methode range] kann " +"auf drei Arten aufgerufen werden:\n" +"[code]range(n: int)[/code]: Beginnt bei 0, erhöht sich in Schritten von 1 " +"und endet [i]vor[/i] [code]n[/code]. Das Argument [code]n[/code] ist " +"[b]exklusiv[/b].\n" +"[code]range(b: int, n: int)[/code]: Beginnt bei [code]b[/code], erhöht sich " +"in Schritten von 1 und endet [i]vor[/i] [code]n[/code]. Die Argumente " +"[code]b[/code] und [code]n[/code] sind [b]inklusive[/b] bzw. [b]exklusive[/" +"b].\n" +"[code]bereich(b: int, n: int, s: int)[/code]: Beginnt bei [code]b[/code], " +"erhöht/verringert sich um Schritte von [code]s[/code] und endet [i]vor[/i] " +"[code]n[/code]. Die Argumente [code]b[/code] und [code]n[/code] sind " +"[b]inklusive[/b] bzw. [b]exklusive[/b]. Das Argument [code]s[/code] [b]kann[/" +"b] negativ sein, aber nicht [code]0[/code]. Wenn [code]s[/code] [code]0[/" +"code] ist, wird eine Fehlermeldung ausgegeben.\n" +"Der [Methodenbereich] wandelt alle Argumente vor der Verarbeitung in [int] " +"um.\n" +"[b]Hinweis:[/b] Gibt ein leeres Array zurück, wenn kein Wert die " +"Werteinschränkung erfüllt (z. B. [code]range(2, 5, -1)[/code] oder " +"[code]range(5, 5, 1)[/code]).\n" +"Beispiele:\n" +"[codeblock]\n" +"print(bereich(4)) # Gibt [0, 1, 2, 3] aus\n" +"print(bereich(2, 5)) # Gibt [2, 3, 4] aus\n" +"print(range(0, 6, 2)) # Gibt [0, 2, 4] aus\n" +"print(range(4, 1, -1)) # Gibt [4, 3, 2] aus\n" +"[/codeblock]\n" +"Um rückwärts über ein [Array] zu iterieren, benutze:\n" +"[codeblock]\n" +"var array = [3, 6, 9]\n" +"for i in range(array.size(), 0, -1):\n" +" print(array[i - 1])\n" +"[/codeblock]\n" +"Ausgabe:\n" +"[codeblock]\n" +"9\n" +"6\n" +"3\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -2194,6 +2251,50 @@ msgid "" "[code]GDScriptFunctionState[/code]. Notice [code]yield(get_tree(), " "\"idle_frame\")[/code] from the above example." msgstr "" +"Stoppt die Ausführung der Funktion und gibt den aktuellen angehaltenen " +"Zustand an die aufrufende Funktion zurück.\n" +"Rufe vom Aufrufer [Methode GDScriptFunctionState.resume] von dem Zustand " +"auf, um die Ausführung wieder aufzunehmen. Dadurch wird der Zustand " +"ungültig. Innerhalb der wiederaufgenommenen Funktion gibt [code]yield()[/" +"code] das zurück, was an den Funktionsaufruf [code]resume()[/code] übergeben " +"wurde.\n" +"Wenn ein Objekt und ein Signal übergeben werden, wird die Ausführung " +"fortgesetzt, wenn das Objekt das angegebene Signal aussendet. In diesem Fall " +"gibt [code]yield()[/code] das an [code]emit_signal()[/code] übergebene " +"Argument zurück, wenn das Signal nur ein Argument benötigt, oder ein Array " +"mit allen an [code]emit_signal()[/code] übergebenen Argumenten, wenn das " +"Signal mehrere Argumente benötigt.\n" +"[code]yield[/code] kann auch verwendet werden um auf das Ende einer Funktion " +"zu warten:\n" +"[codeblock]\n" +"func _ready():\n" +" yield(countdown(), \"completed\") # Warten auf die Beendigung der " +"Funktion countdown()\n" +" print('Fertig')\n" +"\n" +"func countdown():\n" +" yield(get_tree(), \"idle_frame\") # gibt ein GDScriptFunctionState " +"Objekt an _ready() zurück\n" +" print(3)\n" +" yield(get_tree().create_timer(1.0), \"timeout\")\n" +" print(2)\n" +" yield(get_tree().create_timer(1.0), \"timeout\")\n" +" print(1)\n" +" yield(get_tree().create_timer(1.0), \"timeout\")\n" +"\n" +"# gibt aus:\n" +"# 3\n" +"# 2\n" +"# 1\n" +"# bereit\n" +"[/codeblock]\n" +"Beim Yielding einer Funktion wird das Signal [code]completed[/code] " +"automatisch ausgegeben, wenn die Funktion zurückkehrt. Es kann daher als " +"[code]signal[/code] Parameter der [code]yield[/code] Methode verwendet " +"werden, um fortzufahren.\n" +"Um eine Funktion zu beenden, sollte die resultierende Funktion auch einen " +"[code]GDScriptFunctionState[/code] zurückgeben. Beachte " +"[code]yield(get_tree(), \"idle_frame\")[/code] aus dem obigen Beispiel." #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -3946,6 +4047,8 @@ msgid "" "MIDI aftertouch message. This message is most often sent by pressing down on " "the key after it \"bottoms out\"." msgstr "" +"MIDI-Aftertouch-Meldung. Diese Meldung wird meistens durch Drücken der Taste " +"nachdem sie den Tiefpunkt erreicht hat gesendet." #: doc/classes/@GlobalScope.xml msgid "" @@ -3961,6 +4064,8 @@ msgid "" "MIDI program change message. This message sent when the program patch number " "changes." msgstr "" +"MIDI-Programmwechselmeldung. Diese Meldung wird gesendet, wenn sich die " +"Programm-Patch-Nummer ändert." #: doc/classes/@GlobalScope.xml msgid "" @@ -3968,12 +4073,18 @@ msgid "" "down on the key after it \"bottoms out\". This message is different from " "polyphonic after-touch as it indicates the highest pressure across all keys." msgstr "" +"MIDI-Kanal-Druckmeldung. Diese Meldung wird meistens durch Drücken der Taste " +"nachdem sie den Tiefpunkt erreicht hat gesendet.Diese Meldung unterscheidet " +"sich von der polyphonen Aftertouch-Meldung, da sie den höchsten Druck über " +"alle Tasten hinweg anzeigt." #: doc/classes/@GlobalScope.xml msgid "" "MIDI pitch bend message. This message is sent to indicate a change in the " "pitch bender (wheel or lever, typically)." msgstr "" +"MIDI-Pitch-Bend-Meldung. Diese Meldung wird gesendet, um eine Änderung des " +"Pitch-Benders (typischerweise Rad oder Hebel) anzuzeigen." #: doc/classes/@GlobalScope.xml msgid "" @@ -9731,8 +9842,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -13833,7 +13944,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -22443,7 +22559,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -25861,7 +25977,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -27703,7 +27819,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -31788,7 +31904,7 @@ msgstr "" #: doc/classes/Input.xml msgid "A singleton that deals with inputs." -msgstr "" +msgstr "Ein Singleton, der sich mit Inputs befasst." #: doc/classes/Input.xml msgid "" @@ -31797,6 +31913,11 @@ msgid "" "set in the [b]Input Map[/b] tab in the [b]Project > Project Settings[/b], or " "with the [InputMap] class." msgstr "" +"Ein Singleton, das sich mit Inputs befasst. Dazu gehören Tastendrucke, " +"Maustasten und -bewegungen, Joypads und Eingabeaktionen. Aktionen und ihre " +"Ereignisse können auf der Registerkarte [b]Eingabe-Zuordnung[/b] unter " +"[b]Projekt > Projekteinstellungen[/b] oder mit der Klasse [InputMap] " +"festgelegt werden." #: doc/classes/Input.xml msgid "Inputs tutorial index" @@ -32028,6 +32149,20 @@ msgid "" "[url=$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input " "examples[/url] in the documentation for more information." msgstr "" +"Gibt [code]true[/code] aus, wenn Sie das Aktionsereignis drücken. Beachten " +"Sie, dass, wenn einer Aktion mehrere Tasten zugewiesen sind und mehr als " +"eine von ihnen gedrückt wird, das Loslassen einer Taste die Aktion auslöst, " +"selbst wenn eine andere Taste, die dieser Aktion zugewiesen ist, noch " +"gedrückt ist.\n" +"Wenn [code]exact[/code] [code] false[/code] ist, werden zusätzliche " +"Eingabemodifikatoren für die Ereignisse [InputEventKey] und " +"[InputEventMouseButton] sowie die Richtung für die Ereignisse " +"[InputEventJoypadMotion] ignoriert.\n" +"[b]Hinweis:[/b] Aufgrund von Tastatur-Ghosting kann [method " +"is_action_pressed] [code]false[/code] zurückgeben, auch wenn eine der Tasten " +"der Aktion gedrückt ist. Siehe [url=$DOCS_URL/tutorials/inputs/" +"input_examples.html#keyboard-events]Eingabebeispiele[/url] in der " +"Dokumentation für weitere Informationen." #: doc/classes/Input.xml #, fuzzy @@ -34911,7 +35046,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -34927,7 +35062,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -34963,7 +35098,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -39140,7 +39275,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -39407,7 +39542,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -39528,6 +39663,53 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "Set the max packet size that this peer can handle." +msgstr "Gibt das AnimationNode mit dem gegebenen Namen zurück." + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -42231,7 +42413,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -42243,7 +42431,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -60237,7 +60426,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -63197,8 +63386,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -66895,13 +67084,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -66913,13 +67103,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -74065,9 +74256,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Wenn [code]true[/code], wird die Textur zentriert." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -74151,6 +74345,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/el.po b/doc/translations/el.po index c7236b41df..87eee32604 100644 --- a/doc/translations/el.po +++ b/doc/translations/el.po @@ -855,7 +855,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7694,8 +7701,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11766,7 +11773,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20192,7 +20204,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23584,7 +23596,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25421,7 +25433,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32524,7 +32536,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32540,7 +32552,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32570,7 +32582,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36698,7 +36710,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36961,7 +36973,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37079,6 +37091,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39776,7 +39834,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39788,7 +39852,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57561,7 +57626,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60462,8 +60527,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64095,13 +64160,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64113,13 +64179,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71028,7 +71095,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71113,6 +71184,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/es.po b/doc/translations/es.po index 50425a97d9..f9d008c41a 100644 --- a/doc/translations/es.po +++ b/doc/translations/es.po @@ -1380,9 +1380,22 @@ msgstr "" "mientras muestra un trazo de cuando un error o advertencia se muestra." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Como [method print], pero imprime sólo cuando se usa en modo de depuración." +"Imprime una registro de la pila en la ubicación del código, sólo funciona " +"cuando se ejecuta con el depurador activado.\n" +"La salida en la consola se vería algo así:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -10108,8 +10121,8 @@ msgstr "" #, fuzzy msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -15375,10 +15388,13 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" -"Si [code]true[/code], el ancestro [Viewport] está actualmente usando esta " -"cámara." #: doc/classes/Camera.xml msgid "" @@ -26618,10 +26634,11 @@ msgstr "" "save_to_file]." #: doc/classes/EditorFeatureProfile.xml +#, fuzzy msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" "Guarda el perfil de características del editor en un archivo en formato " "JSON. Luego puede ser importado usando el botón [b]Import[/b] del " @@ -31150,9 +31167,10 @@ msgid "The default exposure used for tonemapping." msgstr "La exposición predeterminada que se utiliza para el mapeo de tonos." #: doc/classes/Environment.xml +#, fuzzy msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" "El modo de mapeo de tonos a utilizar. El \"tonemapping\" es el proceso que " @@ -33579,9 +33597,10 @@ msgstr "" "puntos finales." #: doc/classes/Geometry.xml +#, fuzzy msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -43052,7 +43071,7 @@ msgstr "La altura del cilindro." msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -43078,7 +43097,7 @@ msgstr "El tamaño del ancho de un píxel en el sprite para escalarlo en 3D." msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -43125,7 +43144,7 @@ msgstr "Si se ajusta, las luces del entorno afectan al sprite." #: doc/classes/Label3D.xml #, fuzzy msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" "Si se fija, la textura puede ser vista desde atrás también, si no, es " @@ -48253,7 +48272,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -48576,7 +48595,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -48702,6 +48721,54 @@ msgstr "" msgid "Control activation of this server." msgstr "Traducción local de este nodo." +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "Devuelve el estado actual de la conexión. Ver [enum ConnectionStatus]." + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "Set the max packet size that this peer can handle." +msgstr "Establece la piel que se utilizará en esta instancia." + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -52624,8 +52691,14 @@ msgid "See [enum ShadowDetail]." msgstr "Ver [enum ShadowMode]." #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." -msgstr "Ver [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." +msgstr "" #: doc/classes/OmniLight.xml msgid "" @@ -52636,9 +52709,11 @@ msgstr "" "que [constant SHADOW_CUBE], pero de menor calidad." #: doc/classes/OmniLight.xml +#, fuzzy msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" "Las sombras se representan en un mapa de cubos. Más lento que [constant " "SHADOW_DUAL_PARABOLOID], pero de mayor calidad." @@ -75508,7 +75583,7 @@ msgstr "El tamaño del ancho de un píxel en el sprite para escalarlo en 3D." msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -79211,8 +79286,8 @@ msgstr "Establece el texto para una línea específica." #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -83834,15 +83909,18 @@ msgstr "" "elementos pueden establecerse utilizando [method set_item_metadata]." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" "Devuelve el siguiente TreeItem del árbol o un objeto nulo si no hay ninguno." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -83858,15 +83936,18 @@ msgid "Returns the parent TreeItem or a null object if there is none." msgstr "Devuelve el TreeItem padre o un objeto nulo si no hay ninguno." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" "Devuelve el TreeItem anterior del árbol o un objeto nulo si no hay ninguno." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -93040,9 +93121,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "Establece la matriz de transformación global del Viewport." #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Si [code]true[/code], el canvas del viewport no se renderiza." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -93150,6 +93234,15 @@ msgstr "" "ViewportUpdateMode] para las opciones." #: doc/classes/VisualServer.xml +msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml #, fuzzy msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " diff --git a/doc/translations/fa.po b/doc/translations/fa.po index 5f170b2b28..7416d80072 100644 --- a/doc/translations/fa.po +++ b/doc/translations/fa.po @@ -1269,8 +1269,15 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "شبیه متد چاپ، اما چاپ کردن تنها در حالت اشکال زدایی استفاده میشود." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8118,8 +8125,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12187,7 +12194,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20598,7 +20610,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23987,7 +23999,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25818,7 +25830,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32914,7 +32926,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32930,7 +32942,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32960,7 +32972,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37066,7 +37078,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37327,7 +37339,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37441,6 +37453,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40138,7 +40196,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40150,7 +40214,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57920,7 +57985,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60811,8 +60876,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64435,13 +64500,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64453,13 +64519,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71345,7 +71412,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71430,6 +71501,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/fi.po b/doc/translations/fi.po index 0ab098fd33..b1d940aa14 100644 --- a/doc/translations/fi.po +++ b/doc/translations/fi.po @@ -922,7 +922,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7767,8 +7774,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11840,7 +11847,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20268,7 +20280,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23660,7 +23672,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25497,7 +25509,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32607,7 +32619,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32623,7 +32635,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32653,7 +32665,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36783,7 +36795,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37046,7 +37058,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37164,6 +37176,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39861,7 +39919,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39873,7 +39937,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57648,7 +57713,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60550,8 +60615,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64185,13 +64250,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64203,13 +64269,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71123,7 +71190,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71208,6 +71279,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/fil.po b/doc/translations/fil.po index 2dabe612e9..42ab5537f4 100644 --- a/doc/translations/fil.po +++ b/doc/translations/fil.po @@ -856,7 +856,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7693,8 +7700,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11762,7 +11769,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20173,7 +20185,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23562,7 +23574,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25393,7 +25405,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32489,7 +32501,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32505,7 +32517,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32535,7 +32547,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36635,7 +36647,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36896,7 +36908,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37010,6 +37022,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39707,7 +39765,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39719,7 +39783,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57473,7 +57538,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60364,8 +60429,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63988,13 +64053,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64006,13 +64072,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70898,7 +70965,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70983,6 +71054,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/fr.po b/doc/translations/fr.po index 9d5c5f4a01..44d40e1bd5 100644 --- a/doc/translations/fr.po +++ b/doc/translations/fr.po @@ -61,7 +61,7 @@ msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-18 08:12+0000\n" +"PO-Revision-Date: 2022-08-04 05:23+0000\n" "Last-Translator: Maxime Leroy <lisacintosh@gmail.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/fr/>\n" @@ -548,7 +548,6 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml -#, fuzzy msgid "" "Compares two values by checking their actual contents, recursing into any " "[Array] or [Dictionary] up to its deepest level.\n" @@ -574,15 +573,15 @@ msgstr "" "- Pour [code]null[/code], [code]int[/code], [code]float[/code], " "[code]String[/code], [code]Object[/code] et [code]RID[/code], les résultats " "de [code]deep_equal[/code] et [code]==[/code] sont les mêmes.\n" -"- Pour [code]Dictionary[/code], [code]==[/code] considère que l'égalité est " -"respéctée si et seulement si les deux variables pointent vers le même " -"[code]Dictionary[/code], sans recursion ou connaissance du contenu des " +"- Pour les [code]Dictionary[/code], [code]==[/code] considère que l'égalité " +"est respectée si et seulement si les deux variables pointent vers le même " +"[code]Dictionary[/code], sans récursion ou comparaison du contenu des " "variables.\n" -"- For [code]Array[/code], [code]==[/code] considère que l'égalité est " -"respéctée si et seulement si chaque élement du premier [code]Tableau[/code] " +"- Pour les [code]Array[/code], [code]==[/code] considère que l'égalité est " +"respectée si et seulement si chaque élément du premier [code]Array[/code] " "est égal à l'élément au même index du second [code]Array[/code], évalué par " -"[code]==[/code] lui même. Cela implique que [code]==[/code] recurses dans un " -"[code]Array[/code], mais pas dans un [code]Dictionary[/code].\n" +"[code]==[/code] lui-même. Cela implique un récursion avec [code]==[/code] " +"pour les [code]Array[/code], mais pas les [code]Dictionary[/code].\n" "Rapidement, dès qu'un [code]Dictionary[/code] est potentiellement impliqué, " "si une vraie comparaison du contenu est souhaité, il faut utiliser " "[code]deep_equal[/code]." @@ -608,7 +607,6 @@ msgstr "" "nouveau en une instance. Utile pour la désérialisation." #: modules/gdscript/doc_classes/@GDScript.xml -#, fuzzy msgid "" "Returns an \"eased\" value of [code]x[/code] based on an easing function " "defined with [code]curve[/code]. This easing function is based on an " @@ -634,13 +632,15 @@ msgstr "" "nombre à virgule flottante, avec des valeurs spécifiques conduisant aux " "comportements suivants:\n" "[codeblock]\n" -"- Inférieur à -1.0 (exclusif): Ease in-out\n" -"- 1.0: Linéaire\n" -"- Entre -1.0 et 0.0 (exclusif): Ease out-in\n" -"- 0.0: Constante\n" -"- Entre 0.0 et 1.0 (exclusif): Ease in\n" -"- 1.0: Linéaire\n" -"- Supérieur à 1.0 (exclusif): Ease out\n" +"- Inférieur à -1.0 (exclus) : Plus lent au début et à la fin (\"ease in-out\"" +")\n" +"- 1.0 : Linéaire\n" +"- Entre -1.0 et 0.0 (exclus) : Plus rapide au début et à la fin (\"ease out-" +"in\")\n" +"- 0.0 : Constante\n" +"- Entre 0.0 et 1.0 (exclus) : Plus lent au début (\"ease in\")\n" +"- 1.0 : Linéaire\n" +"- Supérieur à 1.0 (exclus) : Plus lent à la fin (\"ease out\")\n" "[/codeblock]\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/" "ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n" @@ -1423,9 +1423,22 @@ msgstr "" "ou un avertissement est affiché." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Comme [method print], mais ne s'affiche que lorsqu'utilisé en mode débogage." +"Comme [method prunt], mais inclus la frame de la pile actuelle quand le " +"débogueur est activé.\n" +"La sortie dans la console ressemblerait à ceci :\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -1811,7 +1824,6 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml -#, fuzzy msgid "" "Returns the result of smoothly interpolating the value of [code]s[/code] " "between [code]0[/code] and [code]1[/code], based on the where [code]s[/code] " @@ -1837,25 +1849,26 @@ msgid "" "-1.6521) return values[/url]" msgstr "" "Retourne le résultat de l'interpolation douce de la valeur [code]s[/code] " -"entre [code]0[/code] et [code]1[/code], basée sur la position de [code]s[/" -"code] entre [code]from[/code] et [code]to[/code].\n" -"La valeur de retour est [code]0[/code] si [code]s <= from[/code], et " +"entre [code]0[/code] et [code]1[/code], basée sur la position de " +"[code]s[/code] entre [code]from[/code] et [code]to[/code].\n" +"La valeur retournée est [code]0[/code] si [code]s <= from[/code], et " "[code]1[/code] si [code]s >= to[/code]. Si [code]s[/code] se trouve entre " "[code]from[/code] et [code]to[/code], la valeur retournée suit une courbe en " -"S qui représente les positions de [code]s[/code] entre[code]0[/code] and " +"S qui représente les positions de [code]s[/code] entre[code]0[/code] et " "[code]1[/code].\n" -"Cette courbe en S est l'interpolateur cubique d'Hermite, obtenu par " -"[code]f(y) = 3*y^2 - 2*y^3[/code] où [code]y = (x-from) / (to-from)[/code].\n" -"[codeblock]\n" -"smoothstep(0, 2, -5.0) # Renvoie 0.0\n" -"smoothstep(0, 2, 0.5) # Renvoie 0.15625\n" -"smoothstep(0, 2, 1.0) # Renvoie 0.5\n" -"smoothstep(0, 2, 2.0) # Renvoie 1.0\n" +"Cette courbe en S est l'interpolation cubique d'Hermite, obtenu par la " +"fonction mathématique [code]f(y) = 3*y^2 - 2*y^3[/code] où [code]y = (x-from)" +" / (to-from)[/code].\n" +"[codeblock]\n" +"smoothstep(0, 2, -5.0) # Retourne 0.0\n" +"smoothstep(0, 2, 0.5) # Retourne 0.15625\n" +"smoothstep(0, 2, 1.0) # Retourne 0.5\n" +"smoothstep(0, 2, 2.0) # Retourne 1.0\n" "[/codeblock]\n" -"Comparé à [method ease] avec une valeur de courbe de [code]-1.6521[/code], " -"[method smoothstep] retourne la courbe la plus douce possible sans change " -"brusque dans la dérivée. Si vous avez besoin d'effectuer des transitions " -"plus avancées, utilisez [Tween] ou [AnimationPlayer].\n" +"Comparé à l'utilisateur [method ease] avec une valeur de courbe de [code]-1." +"6521[/code], [method smoothstep] retourne la courbe la plus douce possible, " +"sans changement brusque de dérivée. Si vous avez besoin d'effectuer des " +"transitions plus avancées, utilisez [Tween] ou [AnimationPlayer].\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/" "smoothstep_ease_comparison.png]Comparaison entre les valeurs retournées par " "smoothstep() et ease(x, -1.6521)[/url]" @@ -4497,13 +4510,12 @@ msgstr "" "les couches de physique 2D optionnellement nommées." #: doc/classes/@GlobalScope.xml -#, fuzzy msgid "" "Hints that an integer property is a bitmask using the optionally named 2D " "navigation layers." msgstr "" -"Indique qu'une propriété nombre entier est un masque de bits utilisant les " -"couches de rendu 2D optionnellement nommées." +"Indique qu'une propriété de nombre entier est un masque de bits indiquant " +"des calques de navigation 2D, qui peuvent être nommées." #: doc/classes/@GlobalScope.xml msgid "" @@ -4522,13 +4534,12 @@ msgstr "" "couches de physique 3D optionnellement nommées." #: doc/classes/@GlobalScope.xml -#, fuzzy msgid "" "Hints that an integer property is a bitmask using the optionally named 3D " "navigation layers." msgstr "" -"Indique qu'une propriété nombre entier est un masque de bits utilisant les " -"couches de rendu 2D optionnellement nommées." +"Indique qu'une propriété de nombre entier est un masque de bits indiquant " +"des calques de navigation 3D, qui peuvent être nommées." #: doc/classes/@GlobalScope.xml msgid "" @@ -4647,9 +4658,10 @@ msgid "The property is a translatable string." msgstr "La propriété est une chaîne de caractères traduisible." #: doc/classes/@GlobalScope.xml -#, fuzzy msgid "Used to group properties together in the editor. See [EditorInspector]." -msgstr "Utilisé pour rassembler des propriétés ensemble dans l'éditeur." +msgstr "" +"Utilisé pour rassembler des propriétés ensemble dans l'éditeur. Voir " +"[EditorInspector]." #: doc/classes/@GlobalScope.xml msgid "Used to categorize properties together in the editor." @@ -5430,10 +5442,11 @@ msgid "Maximum value for the mode enum." msgstr "Valeur maximale pour le mode énumeration." #: doc/classes/AnimatedSprite.xml -#, fuzzy msgid "" "Sprite node that contains multiple textures as frames to play for animation." -msgstr "Nœud de sprite qui peut utiliser plusieurs textures pour l'animation." +msgstr "" +"Le nœud de sprite qui peut utiliser plusieurs textures pour jouer une " +"animation." #: doc/classes/AnimatedSprite.xml msgid "" @@ -7359,7 +7372,7 @@ msgstr "Le type de transition." #: doc/classes/AnimationNodeStateMachineTransition.xml msgid "The time to cross-fade between this state and the next." -msgstr "" +msgstr "La durée du fondu entre cet état et le suivant." #: doc/classes/AnimationNodeStateMachineTransition.xml msgid "Emitted when [member advance_condition] is changed." @@ -7502,9 +7515,8 @@ msgstr "" "processus." #: doc/classes/AnimationPlayer.xml -#, fuzzy msgid "Animation tutorial index" -msgstr "Nœud d'animation." +msgstr "" #: doc/classes/AnimationPlayer.xml msgid "" @@ -8086,9 +8098,8 @@ msgstr "" "connectés à l'emplacement spécifié.." #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "Returns the blend amount of a Blend2 node given its name." -msgstr "Retourne le nombre de clés d'une piste donnée." +msgstr "" #: doc/classes/AnimationTreePlayer.xml msgid "" @@ -8116,9 +8127,8 @@ msgstr "" "code]. Les enfants modifiés du node's continuent d'être animés." #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "Returns the blend amount of a Blend3 node given its name." -msgstr "Retourne le nombre de clés d'une piste donnée." +msgstr "" #: doc/classes/AnimationTreePlayer.xml msgid "" @@ -8139,9 +8149,8 @@ msgstr "" "de B+ est à 0. À 1, la sortie est l'entrée B+." #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "Returns the blend amount of a Blend4 node given its name." -msgstr "Retourne le nombre de clés d'une piste donnée." +msgstr "" #: doc/classes/AnimationTreePlayer.xml msgid "" @@ -8173,9 +8182,8 @@ msgid "Returns a [PoolStringArray] containing the name of all nodes." msgstr "Retourne un [PoolStringArray] contenant le nom de tous les nœuds." #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "Returns the mix amount of a Mix node given its name." -msgstr "Retourne le nombre de clés d'une piste donnée." +msgstr "" #: doc/classes/AnimationTreePlayer.xml msgid "" @@ -8221,23 +8229,20 @@ msgstr "" "position." #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "Returns the autostart delay of a OneShot node given its name." -msgstr "Retourne la valeur d'une clé donnée dans une piste donnée." +msgstr "" #: doc/classes/AnimationTreePlayer.xml msgid "Returns the autostart random delay of a OneShot node given its name." msgstr "" #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "Returns the fade in time of a OneShot node given its name." -msgstr "Retourne le nom du nœud d'animation donné." +msgstr "" #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "Returns the fade out time of a OneShot node given its name." -msgstr "Retourne la valeur d'une clé donnée dans une piste donnée." +msgstr "" #: doc/classes/AnimationTreePlayer.xml msgid "Returns whether a OneShot node will auto restart given its name." @@ -8351,13 +8356,10 @@ msgstr "" "transition nommé [code]id[/code]." #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "" "Returns the index of the currently evaluated input for the transition node " "with name [code]id[/code]." msgstr "" -"Retourne la distance la plus courte de l'avion à la position [code]point [/" -"code]." #: doc/classes/AnimationTreePlayer.xml msgid "" @@ -8369,11 +8371,10 @@ msgstr "" "de transition." #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "" "Returns the cross fade time for the transition node with name [code]id[/" "code]." -msgstr "Retourne le nom du nœud à [code]idx[/code]." +msgstr "" #: doc/classes/AnimationTreePlayer.xml msgid "" @@ -8386,13 +8387,10 @@ msgstr "" "vers la prochaine entrée dès que la transition se termine." #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "" "The transition node with name [code]id[/code] sets its current input at " "[code]input_idx[/code]." msgstr "" -"Change la position de l'index de la piste [code]idx[/code] à celui définie " -"par [code]to_idx[/code]." #: doc/classes/AnimationTreePlayer.xml msgid "" @@ -8411,13 +8409,10 @@ msgstr "" "nommé [code]id[/code]." #: doc/classes/AnimationTreePlayer.xml -#, fuzzy msgid "" "The transition node with name [code]id[/code] sets its cross fade time to " "[code]time_sec[/code]." msgstr "" -"Change la position de l'index de la piste [code]idx[/code] à celui définie " -"par [code]to_idx[/code]." #: doc/classes/AnimationTreePlayer.xml msgid "" @@ -9577,7 +9572,7 @@ msgid "" "element, the slower [method pop_at] will be." msgstr "" "Retire et retourne l'élément du tableau à la [code]position[/code]. Si " -"négatif, [code]position[/code] part de la la fin du tableau vers le début. " +"négatif, [code]position[/code] part de la fin du tableau vers le début. " "Laisse le tableau intact et retourne [code]null[/code] si le tableau est " "vide ou s'il la position est en dehors des limites du tableau. Un message " "d'erreur est affiché lorsque la position est en dehors des limites du " @@ -9919,7 +9914,7 @@ msgid "" "(see [method add_surface_from_arrays])." msgstr "" "Retourne la longueur des indices du tableau d'indices pour la surface " -"spécifiée (voir [method add_surface_from_arrays].)" +"spécifiée (voir [method add_surface_from_arrays])." #: doc/classes/ArrayMesh.xml msgid "" @@ -9927,7 +9922,7 @@ msgid "" "(see [method add_surface_from_arrays])." msgstr "" "Retourne la longueur des sommets du tableau des sommets dans la surface " -"spécifiée (voir [method add_surface_from_arrays].)" +"spécifiée (voir [method add_surface_from_arrays])." #: doc/classes/ArrayMesh.xml msgid "" @@ -9975,7 +9970,7 @@ msgstr "" #: doc/classes/ArrayMesh.xml msgid "Sets the blend shape mode to one of [enum Mesh.BlendShapeMode]." -msgstr "Définit le mode de forme de mélange avec [enum Mesh.BlendShapeMode]" +msgstr "Définit le mode de forme de mélange avec [enum Mesh.BlendShapeMode]." #: doc/classes/ArrayMesh.xml doc/classes/PrimitiveMesh.xml msgid "" @@ -9988,10 +9983,8 @@ msgstr "" "lors de l'utilisation d'un shader qui décale les sommets." #: doc/classes/ArrayMesh.xml -#, fuzzy msgid "Value used internally when no indices are present." -msgstr "" -"La valeur par défaut utilisée pour index_array_len quand il n'y pas d'indice." +msgstr "La valeur par défaut utilisée en interne quand il n'y pas d'indice." #: doc/classes/ArrayMesh.xml msgid "Amount of weights/bone indices per vertex (always 4)." @@ -10214,7 +10207,6 @@ msgstr "" "constamment mise à jour [code]mesh_updated[/code]." #: doc/classes/ARVRCamera.xml -#, fuzzy msgid "" "A camera node with a few overrules for AR/VR applied, such as location " "tracking." @@ -10373,14 +10365,14 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" "L'intensité de vibration du contrôleur. L'intervalle va de [code]0.0[/code] " -"à [code]1.0[/code] avec une précision de [code]0.01[/code]. Si changé, met à " -"jour [membrez ARVRPositionalTracker.rumble] en conséquence.\n" +"à [code]1.0[/code]. Si changé, [member ARVRPositionalTracker.rumble] sera " +"mis à jour en conséquence.\n" "C'est une propriété utile à animer si vous souhaitez que le contrôleur vibre " "pendant une durée limitée." @@ -10550,6 +10542,7 @@ msgstr "Cette interface est compatible avec le rendu stéréoscopique." #: doc/classes/ARVRInterface.xml msgid "This interface supports AR (video background and real world tracking)." msgstr "" +"Cette interface supporte la AR (arrière-plan vidéo et suivi du monde réel)." #: doc/classes/ARVRInterface.xml msgid "" @@ -10626,9 +10619,8 @@ msgstr "" "lumières sont éteintes, etc.)." #: modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml -#, fuzzy msgid "GDNative wrapper for an ARVR interface." -msgstr "Classe de base pour une implémentation d’interface AR / VR." +msgstr "L'encapsulation GDNative pour les interfaces ARVR." #: modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml msgid "" @@ -11060,7 +11052,6 @@ msgstr "" "position du joueur." #: doc/classes/AspectRatioContainer.xml -#, fuzzy msgid "Container that preserves its child controls' aspect ratio." msgstr "Un conteneur qui préserve le ratio d'aspect des contrôles enfants." @@ -11083,19 +11074,16 @@ msgstr "" #: doc/classes/PanelContainer.xml doc/classes/ScrollContainer.xml #: doc/classes/SplitContainer.xml doc/classes/TabContainer.xml #: doc/classes/VBoxContainer.xml doc/classes/VSplitContainer.xml -#, fuzzy msgid "GUI containers" -msgstr "Conteneur à onglets." +msgstr "Conteneurs d'interface" #: doc/classes/AspectRatioContainer.xml -#, fuzzy msgid "Specifies the horizontal relative position of child controls." -msgstr "La séparation horizontale des nœuds enfants." +msgstr "Définit la position horizontale relative des nœuds enfants." #: doc/classes/AspectRatioContainer.xml -#, fuzzy msgid "Specifies the vertical relative position of child controls." -msgstr "La séparation verticale des nœuds enfants." +msgstr "Définit la position verticale relative des nœuds enfants." #: doc/classes/AspectRatioContainer.xml msgid "" @@ -11146,19 +11134,17 @@ msgstr "" "de limiter la visibilité à seulement la taille du conteneur." #: doc/classes/AspectRatioContainer.xml -#, fuzzy msgid "" "Aligns child controls with the beginning (left or top) of the container." -msgstr "Aligne les enfants avec le début du conteneur." +msgstr "Aligne les enfants au début (à gauche ou en haut) du conteneur." #: doc/classes/AspectRatioContainer.xml msgid "Aligns child controls with the center of the container." msgstr "Aligne les contrôles enfants au centre du conteneur." #: doc/classes/AspectRatioContainer.xml -#, fuzzy msgid "Aligns child controls with the end (right or bottom) of the container." -msgstr "Aligne les enfants avec le centre du conteneur." +msgstr "Aligne les enfants à la fin (à droite ou en-bas) du conteneur." #: doc/classes/AStar.xml msgid "" @@ -11643,14 +11629,13 @@ msgstr "" "position et sont facteur de poids seront mis à jour avec la valeur donnée." #: doc/classes/AStar2D.xml -#, fuzzy msgid "" "Returns whether there is a connection/segment between the given points. If " "[code]bidirectional[/code] is [code]false[/code], returns whether movement " "from [code]id[/code] to [code]to_id[/code] is possible through this segment." msgstr "" "Retourne si les deux points donnés sont directement reliés par un segment. " -"Si [code]bidirectionnel[/code] est [code]false[/code], retourne si le " +"Si [code]bidirectional[/code] est [code]false[/code], retourne si le " "mouvement d'identifiant [code]id[/code] vers l'autre identifiant " "[code]to_id[/code] est possible par ce segment." @@ -11838,11 +11823,10 @@ msgstr "" "sont ignorés pour les AtlasTexture." #: doc/classes/AtlasTexture.xml -#, fuzzy msgid "The texture that contains the atlas. Can be any [Texture] subtype." msgstr "" -"La texture qui contient l'atlas. Peut être de n'importe quel sous-type " -"[Texture2D]." +"La texture qui contient l'atlas. Peut être de n'importe quel sous-type de " +"[Texture]." #: doc/classes/AtlasTexture.xml msgid "" @@ -11977,9 +11961,8 @@ msgstr "" "pas assez de données disponibles." #: doc/classes/AudioEffectCapture.xml -#, fuzzy msgid "Returns the total size of the internal ring buffer in frames." -msgstr "Renvoie le reste de deux vecteurs." +msgstr "" #: doc/classes/AudioEffectCapture.xml msgid "" @@ -11990,15 +11973,13 @@ msgstr "" "mémoire est pleine." #: doc/classes/AudioEffectCapture.xml -#, fuzzy msgid "" "Returns the number of frames available to read using [method get_buffer]." -msgstr "Retourne le nombre de formes assignées à une zone." +msgstr "" #: doc/classes/AudioEffectCapture.xml -#, fuzzy msgid "Returns the number of audio frames inserted from the audio bus." -msgstr "Renvoie le nombre de points sur l'axe de mélange." +msgstr "" #: doc/classes/AudioEffectCapture.xml msgid "" @@ -12999,7 +12980,6 @@ msgid "Returns the names of all audio devices detected on the system." msgstr "Retourne les noms de tous les appareils audio détectés sur le système." #: doc/classes/AudioServer.xml -#, fuzzy msgid "Returns the sample rate at the output of the [AudioServer]." msgstr "Retourne le débit de sortie du [AudioServer]." @@ -13284,14 +13264,11 @@ msgstr "" "pour lire l'audio généré en temps réel." #: doc/classes/AudioStreamGeneratorPlayback.xml -#, fuzzy msgid "" "Returns [code]true[/code] if a buffer of the size [code]amount[/code] can be " "pushed to the audio sample data buffer without overflowing it, [code]false[/" "code] otherwise." msgstr "" -"Retourne [code]true[/code] si le paramètre spécifié par [code]name[/code] " -"existe, [code]false[/code] autrement." #: doc/classes/AudioStreamGeneratorPlayback.xml msgid "Clears the audio sample data buffer." @@ -13333,9 +13310,8 @@ msgstr "" "[i]moins[/i] efficace avec GDScript." #: modules/minimp3/doc_classes/AudioStreamMP3.xml -#, fuzzy msgid "MP3 audio stream driver." -msgstr "Pilote de flux audio OGG Vorbis." +msgstr "Le pilote de flux audio MP3." #: modules/minimp3/doc_classes/AudioStreamMP3.xml #: modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml @@ -14135,9 +14111,8 @@ msgstr "" "[constant ENVIRONMENT_MODE_CUSTOM_SKY]." #: doc/classes/BakedLightmap.xml -#, fuzzy msgid "The rotation of the baked custom sky." -msgstr "La racine de la scène éditée." +msgstr "" #: doc/classes/BakedLightmap.xml msgid "" @@ -14246,9 +14221,8 @@ msgid "Currently unused." msgstr "Actuellement inutilisé." #: doc/classes/BakedLightmap.xml -#, fuzzy msgid "Returns when the baker cannot save per-mesh textures to file." -msgstr "Renvoie l'arc tangente des paramètres." +msgstr "" #: doc/classes/BakedLightmap.xml msgid "The size of the generated lightmaps is too large." @@ -14349,7 +14323,6 @@ msgstr "" "défini par l'enumération [enum DrawMode]." #: doc/classes/BaseButton.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the mouse has entered the button and has not " "left it yet." @@ -15483,14 +15456,12 @@ msgid "Returns the current pressed button." msgstr "Renvoie le bouton actuellement enfoncé." #: doc/classes/ButtonGroup.xml -#, fuzzy msgid "Emitted when one of the buttons of the group is pressed." -msgstr "Émis lorsqu’un bouton de ce contrôleur est appuyé." +msgstr "Émis lorsqu’un des boutons de ce groupe est appuyé." #: doc/classes/CallbackTweener.xml -#, fuzzy msgid "Calls the specified method after optional delay." -msgstr "Verrouille l'axe linéaire et de rotation spécifié." +msgstr "Appelle la méthode spécifiée après un délai optionnel." #: doc/classes/CallbackTweener.xml msgid "" @@ -15718,9 +15689,13 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" -"Si [code]true[/code], l’ancêtre [Viewport] utilise actuellement cette caméra." #: doc/classes/Camera.xml msgid "" @@ -16070,7 +16045,7 @@ msgid "" "Left margin needed to drag the camera. A value of [code]1[/code] makes the " "camera move only when reaching the edge of the screen." msgstr "" -"La marge gauche nécessaire pour pour glisser la caméra. Une valeur de " +"La marge gauche nécessaire pour glisser la caméra. Une valeur de " "[code]1[/code] ne déplace la caméra que lorsqu'elle atteint le bord de " "l'écran." @@ -16079,7 +16054,7 @@ msgid "" "Right margin needed to drag the camera. A value of [code]1[/code] makes the " "camera move only when reaching the edge of the screen." msgstr "" -"La marge droite nécessaire pour pour glisser la caméra. Une valeur de " +"La marge droite nécessaire pour glisser la caméra. Une valeur de " "[code]1[/code] ne déplace la caméra que lorsqu'elle atteint le bord de " "l'écran." @@ -16088,7 +16063,7 @@ msgid "" "Top margin needed to drag the camera. A value of [code]1[/code] makes the " "camera move only when reaching the edge of the screen." msgstr "" -"La marge supérieure nécessaire pour pour glisser la caméra. Une valeur de " +"La marge supérieure nécessaire pour glisser la caméra. Une valeur de " "[code]1[/code] ne déplacer la caméra que lorsqu'elle atteint le bord de " "l'écran." @@ -16204,9 +16179,8 @@ msgstr "" "La méthode de mise à jour de la camera. Voir [enum Camera2DProcessMode]." #: doc/classes/Camera2D.xml -#, fuzzy msgid "If [code]true[/code], the camera view rotates with the target." -msgstr "Si [code]true[/code], le bouton \"add preset\" est activé." +msgstr "" #: doc/classes/Camera2D.xml msgid "" @@ -16294,9 +16268,8 @@ msgid "Returns the unique ID for this feed." msgstr "Retourne l'identifiant unique de ce flux." #: doc/classes/CameraFeed.xml -#, fuzzy msgid "Returns the camera's name." -msgstr "Renvoie le nom de l'élément." +msgstr "Retourne le nom de la caméra." #: doc/classes/CameraFeed.xml msgid "Returns the position of camera on the device." @@ -16366,20 +16339,18 @@ msgstr "" "iOS. Sur les autres plates-formes, aucun [CameraFeed] ne sera disponible." #: doc/classes/CameraServer.xml -#, fuzzy msgid "Adds the camera [code]feed[/code] to the camera server." -msgstr "Ajoute un [Shape2D] au propriétaire de la forme." +msgstr "" #: doc/classes/CameraServer.xml msgid "Returns an array of [CameraFeed]s." msgstr "Retourne un tableau de [CameraFeed]s." #: doc/classes/CameraServer.xml -#, fuzzy msgid "" "Returns the [CameraFeed] corresponding to the camera with the given " "[code]index[/code]." -msgstr "Retourne la position du point à l'index [code]point[/code]." +msgstr "" #: doc/classes/CameraServer.xml msgid "Returns the number of [CameraFeed]s registered." @@ -16390,14 +16361,12 @@ msgid "Removes the specified camera [code]feed[/code]." msgstr "Supprime le flux de caméra [code]feed[/code] spécifié." #: doc/classes/CameraServer.xml -#, fuzzy msgid "Emitted when a [CameraFeed] is added (e.g. a webcam is plugged in)." -msgstr "Émis lorsqu'une interface est supprimée." +msgstr "" #: doc/classes/CameraServer.xml -#, fuzzy msgid "Emitted when a [CameraFeed] is removed (e.g. a webcam is unplugged)." -msgstr "Émis lorsqu'une interface est supprimée." +msgstr "" #: doc/classes/CameraServer.xml msgid "The RGBA camera image." @@ -17433,9 +17402,8 @@ msgstr "" "[CanvasLayer] n'est pas propagée aux calques enfants." #: doc/classes/CanvasLayer.xml -#, fuzzy msgid "Emitted when visibility of the layer is changed. See [member visible]." -msgstr "Émis lorsque le VisibilityNotifier3D quitte la vue d'un [Camera3D]." +msgstr "" #: doc/classes/CanvasModulate.xml msgid "Tint the entire canvas." @@ -17530,13 +17498,12 @@ msgstr "" "contrôler le rendu de caractères individuels dans un [RichTextEffect]." #: doc/classes/CharFXTransform.xml -#, fuzzy msgid "" "The index of the current character (starting from 0) for the " "[RichTextLabel]'s BBCode text. Setting this property won't affect drawing." msgstr "" -"L'index du caractère actuel (commence à 0). Régler cette propriété n'affecte " -"pas l'affichage." +"L'index du caractère actuel (commence à 0) pour le texte BBCode du " +"[RichTextLabel]. Régler cette propriété n'affecte pas l'affichage." #: doc/classes/CharFXTransform.xml msgid "" @@ -17615,13 +17582,12 @@ msgstr "" "pixels)." #: doc/classes/CharFXTransform.xml -#, fuzzy msgid "" "The index of the current character (starting from 0) for this " "[RichTextEffect] custom block. Setting this property won't affect drawing." msgstr "" -"L'index du caractère actuel (commence à 0). Régler cette propriété n'affecte " -"pas l'affichage." +"L'index du caractère actuel (commence à 0) pour le bloc personnalisé du " +"[RichTextEffect]. Régler cette propriété n'affecte pas l'affichage." #: doc/classes/CharFXTransform.xml msgid "" @@ -17739,10 +17705,9 @@ msgid "The check icon to display when the [CheckBox] is unchecked." msgstr "L'icône de la coche à afficher quand la [CheckBox] est décochée." #: doc/classes/CheckBox.xml -#, fuzzy msgid "" "The check icon to display when the [CheckBox] is unchecked and disabled." -msgstr "Icône à afficher lorsque le [CheckButton] est coché et désactivé." +msgstr "L'icône à afficher lorsque le [CheckBox] est décoché et désactivé." #: doc/classes/CheckBox.xml msgid "" @@ -17959,10 +17924,9 @@ msgstr "" "code] de la [code]class[/code] ou de ses parents." #: doc/classes/ClassDB.xml -#, fuzzy msgid "" "Returns an array with all the enums of [code]class[/code] or its ancestry." -msgstr "Retourne si la [code]class[/code] spécifiée est disponible ou non." +msgstr "" #: doc/classes/ClassDB.xml msgid "" @@ -18234,7 +18198,7 @@ msgid "" msgstr "" "CollisionObject est la classe de base pour les objets physiques. Il peut " "contenir n'importe quel nombre de formes [Shape] de collision. Chaque forme " -"doit être assignée à un [i]propriétaire de forme[ /i]. Le CollisionObject " +"doit être assignée à un [i]propriétaire de forme[/i]. Le CollisionObject " "peut avoir n'importe quel nombre de propriétaires de forme. Les " "propriétaires de forme ne sont pas des nœuds et ne apparaissent pas dans " "l'éditeur, mais sont accessibles par le code en utilisant les méthodes " @@ -18343,20 +18307,18 @@ msgid "Returns the parent object of the given shape owner." msgstr "Retourne l'objet parent du propriétaire de la forme spécifié." #: doc/classes/CollisionObject.xml -#, fuzzy msgid "Returns the [Shape] with the given id from the given shape owner." -msgstr "Retourne le [RID] de la énième forme d'une zone." +msgstr "" #: doc/classes/CollisionObject.xml doc/classes/CollisionObject2D.xml msgid "Returns the number of shapes the given shape owner contains." msgstr "Retourne le nombre de formes que le propriétaire de forme contient." #: doc/classes/CollisionObject.xml -#, fuzzy msgid "" "Returns the child index of the [Shape] with the given id from the given " "shape owner." -msgstr "Retourne la liste de tous les nœuds du shader avec le type spécifié." +msgstr "" #: doc/classes/CollisionObject.xml msgid "Returns the shape owner's [Transform]." @@ -18821,11 +18783,12 @@ msgid "2D Kinematic Character Demo" msgstr "Démo de caractère cinétique 2D" #: doc/classes/CollisionShape2D.xml -#, fuzzy msgid "" "A disabled collision shape has no effect in the world. This property should " "be changed with [method Object.set_deferred]." -msgstr "Une forme de collision désactivée n’a aucun effet dans le monde." +msgstr "" +"Une forme de collision désactivée n’a aucun effet dans le monde. Cette " +"propriété devrait être modifiée avec [method Object.set_deferred]." #: doc/classes/CollisionShape2D.xml msgid "" @@ -19958,9 +19921,8 @@ msgstr "" "performance)." #: doc/classes/ColorPicker.xml -#, fuzzy msgid "If [code]true[/code], shows an alpha channel slider (opacity)." -msgstr "Si [code]true[/code], le GraphNode est sélectionné." +msgstr "" #: doc/classes/ColorPicker.xml msgid "" @@ -20985,15 +20947,12 @@ msgstr "" "[/codeblock]" #: doc/classes/Control.xml -#, fuzzy msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " "the control.\n" "See also [method get_constant], [method remove_constant_override]." msgstr "" -"Retourne [code]true[/code] si le paramètre spécifié par [code]name[/code] " -"existe, [code]false[/code] autrement." #: doc/classes/Control.xml msgid "" @@ -21375,9 +21334,8 @@ msgstr "" "Retourne la taille minimale de ce contrôle. Voir [member rect_min_size]." #: doc/classes/Control.xml -#, fuzzy msgid "Returns the width/height occupied in the parent control." -msgstr "Renvoie la largeur / hauteur occupée dans le contrôle du parent." +msgstr "Retourne la largeur / hauteur occupée dans le contrôle du parent." #: doc/classes/Control.xml msgid "Returns the parent control node." @@ -21482,7 +21440,7 @@ msgid "" "See [method get_color] for details." msgstr "" "Retourne [code]true[/code] s'il y a un [Theme] correspondant dans " -"l'arborescence qui a une propriété de constante nommée [/code]name[/code] et " +"l'arborescence qui a une propriété de constante nommée [code]name[/code] et " "du type de thème [code]theme_type[/code].\n" "Voir [method get_color] pour plus de détails." @@ -21626,37 +21584,31 @@ msgstr "" "clavier." #: doc/classes/Control.xml -#, fuzzy msgid "" "Removes a theme override for a [Color] with the given [code]name[/code]." -msgstr "Supprime l’animation avec la touche [code]name[/code]." +msgstr "" #: doc/classes/Control.xml -#, fuzzy msgid "" "Removes a theme override for a constant with the given [code]name[/code]." -msgstr "Supprime l’animation avec la touche [code]name[/code]." +msgstr "" #: doc/classes/Control.xml -#, fuzzy msgid "Removes a theme override for a [Font] with the given [code]name[/code]." -msgstr "Supprime l’animation avec la touche [code]name[/code]." +msgstr "" #: doc/classes/Control.xml -#, fuzzy msgid "Removes a theme override for an icon with the given [code]name[/code]." -msgstr "Supprime l’animation avec la touche [code]name[/code]." +msgstr "" #: doc/classes/Control.xml -#, fuzzy msgid "Removes a theme override for a shader with the given [code]name[/code]." -msgstr "Retourne la position du point à l'index [code]point[/code]." +msgstr "" #: doc/classes/Control.xml -#, fuzzy msgid "" "Removes a theme override for a [StyleBox] with the given [code]name[/code]." -msgstr "Supprime l’animation avec la touche [code]name[/code]." +msgstr "" #: doc/classes/Control.xml msgid "" @@ -22609,20 +22561,20 @@ msgstr "" "Affiche le curseur en croix du système quand l'utilisateur survole ce nœud." #: doc/classes/Control.xml -#, fuzzy msgid "" "Show the system's wait mouse cursor when the user hovers the node. Often an " "hourglass." msgstr "" -"Affiche le curseur en croix du système quand l'utilisateur survole ce nœud." +"Affiche le curseur d'attente du système quand l'utilisateur survole ce nœud. " +"Souvent un sablier." #: doc/classes/Control.xml -#, fuzzy msgid "" "Show the system's busy mouse cursor when the user hovers the node. Often an " "arrow with a small hourglass." msgstr "" -"Affiche le curseur en croix du système quand l'utilisateur survole ce nœud." +"Affiche le curseur d'occupation du système quand l'utilisateur survole ce " +"nœud. Souvent une flèche avec un petit sablier." #: doc/classes/Control.xml msgid "" @@ -23038,10 +22990,10 @@ msgid "" "variables, like [member anchor_left]. To change all 4 anchors at once, use " "[method set_anchors_preset]." msgstr "" -"Magnétise l'un des 4 côtés d'ancrage à l'origine de l'ancrage [code]Rect[/" -"code], en haut à gauche. Utilisez-le avec l'une des variables membres " -"[code]anchor_[* /code], comme [member anchor_left]. Pour modifier les 4 " -"ancres à la fois, utilisez [method set_anchors_preset]." +"Magnétise l'un des 4 côtés d'ancrage à l'origine de l'ancrage " +"[code]Rect[/code], en haut à gauche. Utilisez-le avec l'une des variables " +"membres [code]anchor_*[/code], comme [member anchor_left]. Pour modifier les " +"4 ancres à la fois, utilisez [method set_anchors_preset]." #: doc/classes/Control.xml msgid "" @@ -23052,18 +23004,19 @@ msgid "" msgstr "" "Magnétise l'un des 4 côtés d'ancrage à l'extrémité de l'extrémité " "[code]Rect[/code], en bas à droite. Utilisez-le avec l'une des variables " -"membres [code]anchor_[* /code], comme [member anchor_left]. Pour modifier " -"les 4 ancres à la fois, utilisez [method set_anchors_preset]." +"membres [code]anchor_*[/code], comme [member anchor_left]. Pour modifier les " +"4 ancres à la fois, utilisez [method set_anchors_preset]." #: doc/classes/ConvexPolygonShape.xml msgid "Convex polygon shape for 3D physics." msgstr "Forme de polygone convexe pour la physique 3D." #: doc/classes/ConvexPolygonShape.xml -#, fuzzy msgid "" "Convex polygon shape resource, which can be added to a [PhysicsBody] or area." -msgstr "Ressource de forme de polygone concave 2D pour la physique." +msgstr "" +"Un ressource de forme de polygone convexe, qui peut être ajoutée à un " +"[PhysicsBody] ou une aire." #: doc/classes/ConvexPolygonShape.xml msgid "The list of 3D points forming the convex polygon shape." @@ -24330,7 +24283,6 @@ msgid "" msgstr "" #: modules/csg/doc_classes/CSGCylinder.xml -#, fuzzy msgid "" "If [code]true[/code] a cone is created, the [member radius] will only apply " "to one side." @@ -24533,9 +24485,8 @@ msgstr "" "aucun maillage ne sera généré." #: modules/csg/doc_classes/CSGPolygon.xml -#, fuzzy msgid "If [code]true[/code], applies smooth shading to the extrusions." -msgstr "Si [code]true[/code], l’audio est stéréo." +msgstr "" #: modules/csg/doc_classes/CSGPolygon.xml msgid "" @@ -24767,7 +24718,6 @@ msgid "Only intersecting geometry remains, the rest is removed." msgstr "Il ne reste que la géométrie d'intersection, le reste est supprimé." #: modules/csg/doc_classes/CSGShape.xml -#, fuzzy msgid "" "The second shape is subtracted from the first, leaving a dent with its shape." msgstr "" @@ -24856,13 +24806,12 @@ msgstr "" "le tore aura un aspect de rendu plat." #: modules/mono/doc_classes/CSharpScript.xml -#, fuzzy msgid "" "A script implemented in the C# programming language (Mono-enabled builds " "only)." msgstr "" -"Un script implémenté dans le langage de programmation C# (uniquement des " -"compilations Mono-activé)." +"Un script implémenté en langage C# (uniquement pour les versions où Mono est " +"activé)." #: modules/mono/doc_classes/CSharpScript.xml msgid "" @@ -24891,9 +24840,8 @@ msgid "" msgstr "" #: doc/classes/CubeMap.xml -#, fuzzy msgid "Returns the [CubeMap]'s height." -msgstr "Retourne la hauteur de texture." +msgstr "Retourne la hauteur du [CubeMap]." #: doc/classes/CubeMap.xml msgid "" @@ -24904,9 +24852,8 @@ msgstr "" "constantes [enum Side]." #: doc/classes/CubeMap.xml -#, fuzzy msgid "Returns the [CubeMap]'s width." -msgstr "Renvoie la largeur de texture." +msgstr "Renvoie la largeur du [CubeMap]." #: doc/classes/CubeMap.xml msgid "" @@ -24933,9 +24880,8 @@ msgstr "" "défini à [constant STORAGE_COMPRESS_LOSSY]." #: doc/classes/CubeMap.xml -#, fuzzy msgid "The [CubeMap]'s storage mode. See [enum Storage] constants." -msgstr "Convertit le format de l’image. Voir les constantes [enum Format]." +msgstr "" #: doc/classes/CubeMap.xml msgid "Store the [CubeMap] without any compression." @@ -25352,13 +25298,13 @@ msgid "" "list." msgstr "" "Ajoute un point à une courbe à la [code]position[/code] par rapport à la " -"position de la [Curve2D], avec des points de contrôle d'entrée [code]in[/" -"code] et de sortie [code]out[/code].\n" +"position de la [Curve2D], avec des points de contrôle d'entrée " +"[code]in[/code] et de sortie [code]out[/code].\n" "Si [code]at_position[/code] est spécifié, le point est inséré juste avant ce " "numéro de point [code]at_position[/code], en déplaçant ce point (et tous les " -"autres points qui suivent) après le point inséré. Si [code]at_position[/" -"code] n'est pas donné, ou est une valeur invalide ([code]at_position < 0[/" -"code] ou [code]at_position >= [method get_point_count][/code,) le point sera " +"autres points qui suivent) après le point inséré. Si [code]at_position[/code]" +" n'est pas donné, ou est une valeur invalide ([code]at_position < 0[/code] " +"ou [code]at_position >= [method get_point_count][/code]), le point sera " "ajouté en dernier." #: doc/classes/Curve2D.xml doc/classes/Curve3D.xml @@ -25778,9 +25724,8 @@ msgstr "" "courbes et/ou de les enregistrer dans des fichiers d'image." #: doc/classes/CurveTexture.xml -#, fuzzy msgid "The [Curve] that is rendered onto the texture." -msgstr "La [code]curve[/code] rendue sur la texture." +msgstr "La [Curve] qui est rendue dans la texture." #: doc/classes/CurveTexture.xml msgid "" @@ -25860,9 +25805,8 @@ msgid "The cylinder's radius." msgstr "Le rayon du cylindre." #: doc/classes/DampedSpringJoint2D.xml -#, fuzzy msgid "Damped spring constraint for 2D physics." -msgstr "Contrainte de ressort amortie pour la physique 2D." +msgstr "Une contrainte de ressort avec amortissement pour la physique 2D." #: doc/classes/DampedSpringJoint2D.xml msgid "" @@ -26473,9 +26417,9 @@ msgid "" msgstr "" "Change le dossier actuellement ouvert par celui donné en argument. " "L'argument peut être relatif au répertoire actuel (par exemple " -"[code]nouveau_dossier[/code] ou [code]./dossier[ /code,)] ou être un chemin " +"[code]nouveau_dossier[/code] ou [code]./dossier[/code]), ou être un chemin " "absolu (par exemple [code]/tmp/dossier[/code] ou [code]res://parent/" -"dossier[ /code)].\n" +"dossier[/code]).\n" "Retourne une des constantes de code [enum Error] (et [code]OK[/code] en cas " "de succès)." @@ -27098,9 +27042,8 @@ msgid "Disables font hinting (smoother but less crisp)." msgstr "" #: doc/classes/DynamicFontData.xml -#, fuzzy msgid "Use the light font hinting mode." -msgstr "Utilisez le mode d’allusion de police de lumière." +msgstr "Utilise le mode d'indice de police légère." #: doc/classes/DynamicFontData.xml msgid "Use the default font hinting mode (crisper but less smooth)." @@ -27364,11 +27307,12 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" "Enregistre le profil de fonctionnalité de l'éditeur dans un fichier au " -"format JSON. Il peut ensuite être importé en utilisant le bouton [b]Import[/" -"b] ou la méthode [method load_from_file]." +"format JSON. Il peut ensuite être importé en utilisant le bouton " +"[b]Importer[/b] du gestionnaire de profils ou via la méthode [method " +"load_from_file]." #: doc/classes/EditorFeatureProfile.xml msgid "" @@ -27527,7 +27471,7 @@ msgid "" "code], [code]user://[/code], and the local file system." msgstr "" "L'emplacement à partir duquel l'utilisateur peut sélectionner un fichier, y " -"compris [code]res://[/code], [code]user://[code], et le système de fichiers " +"compris [code]res://[/code], [code]user://[/code], et le système de fichiers " "local." #: doc/classes/EditorFileDialog.xml @@ -27667,7 +27611,7 @@ msgstr "" "fichiers, leurs types, etc.\n" "[b]Note :[/b] Cette classe ne devrait pas être instanciée directement. " "Accédez plutôt à l'instance unique avec [method EditorInterface." -"get_resource_filesystem]" +"get_resource_filesystem]." #: doc/classes/EditorFileSystem.xml msgid "" @@ -27697,7 +27641,6 @@ msgstr "" "en train d'être scanné." #: doc/classes/EditorFileSystem.xml -#, fuzzy msgid "Returns [code]true[/code] if the filesystem is being scanned." msgstr "Retourne [code]true[/code] si le système de fichier a été scanné." @@ -27908,8 +27851,8 @@ msgid "" msgstr "" "Les [EditorImportPlugin] fournissent un moyen d'étendre la fonctionnalité " "d'importation des ressources dans l'éditeur. Utilisez-les pour importer des " -"ressources depuis des formats de de fichier personnalisés ou pour proposer " -"une alternative aux importateurs existants de l'éditeur.\n" +"ressources depuis des formats de fichier personnalisés ou pour proposer une " +"alternative aux importateurs existants de l'éditeur.\n" "Les EditorImportPlugins fonctionnent pas associés certaines extensions de " "fichiers avec un type de ressource. Voir [method get_recognized_extensions] " "et [method get_resource_type]. Ils peuvent aussi spécifier des préréglages " @@ -28103,10 +28046,8 @@ msgstr "" "surcharge de cette méthode." #: doc/classes/EditorInspector.xml -#, fuzzy msgid "A control used to edit properties of an object." -msgstr "" -"Contrôle personnalisé pour modifier les propriétés à ajouter à l’inspecteur." +msgstr "Un contrôle pour modifier les propriétés d'un objet." #: doc/classes/EditorInspector.xml msgid "" @@ -28501,22 +28442,16 @@ msgstr "" "[code]object[/code]." #: doc/classes/EditorInterface.xml -#, fuzzy msgid "" "Returns [code]true[/code] if a scene is currently being played, [code]false[/" "code] otherwise. Paused scenes are considered as being played." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères commence par la chaîne " -"de caractères donnée, ou [code]false[/code] le cas échéant." #: doc/classes/EditorInterface.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the specified [code]plugin[/code] is enabled. " "The plugin name is the same as its directory name." msgstr "" -"Renvoie [code]true[/code] (vrai) si [code]s[/code] vaut zéro ou quasiment " -"zéro." #: doc/classes/EditorInterface.xml msgid "" @@ -29296,29 +29231,25 @@ msgid "Removes a custom type added by [method add_custom_type]." msgstr "Supprime un type personnalisé ajouté par [method add_custom_type]." #: doc/classes/EditorPlugin.xml -#, fuzzy msgid "Removes an export plugin registered by [method add_export_plugin]." -msgstr "Supprime un type personnalisé ajouté par [method add_custom_type]." +msgstr "" #: doc/classes/EditorPlugin.xml -#, fuzzy msgid "Removes an import plugin registered by [method add_import_plugin]." -msgstr "Supprime un type personnalisé ajouté par [method add_custom_type]." +msgstr "" #: doc/classes/EditorPlugin.xml msgid "Removes an inspector plugin registered by [method add_import_plugin]" msgstr "Supprime un type personnalisé ajouté par [method add_custom_type]" #: doc/classes/EditorPlugin.xml -#, fuzzy msgid "" "Removes a scene importer registered by [method add_scene_import_plugin]." -msgstr "Supprime un type personnalisé ajouté par [method add_custom_type]." +msgstr "" #: doc/classes/EditorPlugin.xml -#, fuzzy msgid "Removes a gizmo plugin registered by [method add_spatial_gizmo_plugin]." -msgstr "Supprime un type personnalisé ajouté par [method add_custom_type]." +msgstr "" #: doc/classes/EditorPlugin.xml msgid "Removes a menu [code]name[/code] from [b]Project > Tools[/b]." @@ -29509,7 +29440,7 @@ msgid "" "must be previously added using [method Node.add_child]." msgstr "" "Place le contrôle [code]editor[/code] sous le label de la propriété. Le " -"contrôle doit d'abord être ajouté avec [method Node.add_child]" +"contrôle doit d'abord être ajouté avec [method Node.add_child]." #: doc/classes/EditorProperty.xml msgid "When this virtual function is called, you must update your editor." @@ -29569,9 +29500,9 @@ msgid "" "Emit it if you want multiple properties modified at the same time. Do not " "use if added via [method EditorInspectorPlugin.parse_property]." msgstr "" -"Emettez-le si vous voulez plusieurs propriétés modifiées en même temps. Ne " +"Émettez-le si vous voulez plusieurs propriétés modifiées en même temps. Ne " "pas utiliser s'il a été ajouté avec [method EditorInspectorPlugin." -"parse_property]" +"parse_property]." #: doc/classes/EditorProperty.xml msgid "Used by sub-inspectors. Emit it if what was selected was an Object ID." @@ -29720,9 +29651,8 @@ msgstr "" "set_toggle_pressed] pour définir manuellement cet état." #: doc/classes/EditorResourcePicker.xml -#, fuzzy msgid "Emitted when the value of the edited resource was changed." -msgstr "Émis à chaque fois que la ressource change." +msgstr "Émis quand le valeur d'une ressource modifiée a été changée." #: doc/classes/EditorResourcePicker.xml msgid "" @@ -29748,7 +29678,7 @@ msgstr "" "fichiers.\n" "[b]Note :[/b] Cette classe ne devrait pas être instanciée directement. " "Accédez plutôt à l'instance unique en utilisant [method EditorInterface." -"get_resource_previewer]" +"get_resource_previewer]." #: doc/classes/EditorResourcePreview.xml msgid "Create an own, custom preview generator." @@ -30155,7 +30085,7 @@ msgstr "" "Cet objet gère la sélection dans le SceneTree dans l'éditeur.\n" "[b]Note :[/b] Cette classe ne devrait pas être instanciée directement. " "Accédez plutôt à l'instance unique en utilisant [method EditorInterface." -"get_selection]" +"get_selection]." #: doc/classes/EditorSelection.xml msgid "" @@ -30553,12 +30483,11 @@ msgid "" msgstr "" "Retourne le [EditorSpatialGizmoPlugin] qui possède ce manipulateur. Il est " "utile de récupérer les matériaux en utilisant [method " -"EditorSpatialGizmoPlugin.get_material]" +"EditorSpatialGizmoPlugin.get_material]." #: doc/classes/EditorSpatialGizmo.xml -#, fuzzy msgid "Returns the Spatial node associated with this gizmo." -msgstr "Retourne le chemin d’accès au nœud associé à l’os spécifié." +msgstr "" #: doc/classes/EditorSpatialGizmo.xml msgid "" @@ -30759,9 +30688,8 @@ msgid "" msgstr "" #: doc/classes/EditorSpinSlider.xml -#, fuzzy msgid "If [code]true[/code], the slider is hidden." -msgstr "Si [code]true[/code], la flèche de réduction est masquée." +msgstr "Si [code]true[/code], le glisseur est masqué." #: doc/classes/EditorVCSInterface.xml msgid "" @@ -30790,10 +30718,8 @@ msgstr "" "hériter de [EditorVCSInterface] et surcharger ces fonctions virtuelles." #: doc/classes/EditorVCSInterface.xml -#, fuzzy msgid "Checks out a [code]branch_name[/code] in the VCS." msgstr "" -"Supprime un [code]name[/code] de chargement automatique à partir de la liste." #: doc/classes/EditorVCSInterface.xml msgid "" @@ -30802,9 +30728,8 @@ msgid "" msgstr "" #: doc/classes/EditorVCSInterface.xml -#, fuzzy msgid "Creates a new branch named [code]branch_name[/code] in the VCS." -msgstr "Crée une instance de [code]class[/code]." +msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" @@ -30835,9 +30760,8 @@ msgid "" msgstr "" #: doc/classes/EditorVCSInterface.xml -#, fuzzy msgid "Gets the current branch name defined in the VCS." -msgstr "Définit le trame présentement visible de l'animation." +msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" @@ -30901,9 +30825,8 @@ msgid "" msgstr "" #: doc/classes/EditorVCSInterface.xml -#, fuzzy msgid "Remove a branch from the local VCS." -msgstr "Supprime un nœud de la sélection." +msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "Remove a remote from the local VCS." @@ -30925,9 +30848,8 @@ msgid "" msgstr "" #: doc/classes/EditorVCSInterface.xml -#, fuzzy msgid "Stages the file present at [code]file_path[/code] to the staged area." -msgstr "Ajoute un [Shape2D] au propriétaire de la forme." +msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" @@ -31037,9 +30959,8 @@ msgid "A commit is encountered from the commit area." msgstr "" #: doc/classes/EditorVCSInterface.xml -#, fuzzy msgid "A file is encountered from the staged area." -msgstr "Statut : Déconnecté du serveur." +msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "A file is encountered from the unstaged area." @@ -31559,14 +31480,12 @@ msgid "The [Sky] resource's rotation expressed as a [Basis]." msgstr "La rotation du [Sky] exprimée par un [Basis]." #: doc/classes/Environment.xml -#, fuzzy msgid "The [Sky] resource's rotation expressed as Euler angles in radians." -msgstr "La rotation de la texture en radians." +msgstr "" #: doc/classes/Environment.xml -#, fuzzy msgid "The [Sky] resource's rotation expressed as Euler angles in degrees." -msgstr "La rotation de la texture en degrés." +msgstr "" #: doc/classes/Environment.xml msgid "The amount of far blur for the depth-of-field effect." @@ -31580,9 +31499,8 @@ msgstr "" "rendu." #: doc/classes/Environment.xml -#, fuzzy msgid "If [code]true[/code], enables the depth-of-field far blur effect." -msgstr "Si [code]true[/code], active le drapeau spécifié." +msgstr "Si [code]true[/code], active l'effet de flou de profondeur lointain." #: doc/classes/Environment.xml msgid "" @@ -31902,11 +31820,10 @@ msgid "" msgstr "" #: doc/classes/Environment.xml -#, fuzzy msgid "" "The secondary screen-space ambient occlusion intensity. See also [member " "ssao_radius2]." -msgstr "Le rayon d'occlusion ambiante de l'espace de l'écran primaire." +msgstr "" #: doc/classes/Environment.xml msgid "" @@ -31942,7 +31859,7 @@ msgstr "L’exposition par défaut utilisée pour tonifier." #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -33044,7 +32961,7 @@ msgstr "" #: doc/classes/FlowContainer.xml #, fuzzy msgid "Base class for flow containers." -msgstr "Classe de base pour les conteneurs de boîtes." +msgstr "La classe de base pour les conteneurs de flux." #: doc/classes/FlowContainer.xml msgid "" @@ -33055,7 +32972,6 @@ msgid "" msgstr "" #: doc/classes/FlowContainer.xml -#, fuzzy msgid "Returns the current line count." msgstr "Retourne le numéro de la ligne actuelle." @@ -33125,30 +33041,24 @@ msgid "" msgstr "" #: doc/classes/Font.xml -#, fuzzy msgid "Returns resource id of the cache texture containing the char." -msgstr "Retourne l'identifiant OpenGL de l'image de cette texture." +msgstr "" #: doc/classes/Font.xml -#, fuzzy msgid "Returns size of the cache texture containing the char." -msgstr "Retourne la position du contact sur le collisionneur." +msgstr "" #: doc/classes/Font.xml -#, fuzzy msgid "Returns char offset from the baseline." -msgstr "Retourne le décalage de la texture de la tuile." +msgstr "" #: doc/classes/Font.xml -#, fuzzy msgid "Returns size of the char." -msgstr "Renvoie le sinus du paramètre." +msgstr "Retourne la taille du caractère." #: doc/classes/Font.xml -#, fuzzy msgid "Returns rectangle in the cache texture containing the char." msgstr "" -"Retourne un rectangle englobant les tuiles utilisées (non vides) de la carte." #: doc/classes/Font.xml msgid "Returns the font descent (number of pixels below the baseline)." @@ -33184,9 +33094,8 @@ msgid "" msgstr "" #: doc/classes/Font.xml -#, fuzzy msgid "Contour point is on the curve." -msgstr "Supprime tous les points de la courbe." +msgstr "" #: doc/classes/Font.xml msgid "" @@ -34022,15 +33931,15 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" -"À partir d'un tableau de [Vector2] représentant des tuiles, construit un " +"À partir d'un tableau de [Vector2] représentant des tuiles, ça construit un " "atlas. Le dictionnaire retourné a deux clés : [code]points[/code] est un " "tableau de [Vector2] qui précise les positions de chaque tuile, et " -"[code]size[/code] contient la taille globale de l'atlas entier sous forme de " -"[Vector2]." +"[code]size[/code] contient la taille globale de l'atlas en entier sous forme " +"d'un [Vector2]." #: doc/classes/Geometry.xml msgid "" @@ -34075,19 +33984,20 @@ msgid "" msgstr "" "Gonfle ou dégonfle [code]polygon[/code] par la quantité [code]delta[/code] " "unités (pixels) dans toutes les directions. Si [code]delta[/code] est " -"positif, le polygone décale chaque sommet vers l'extérieur. Si [code]delta[/" -"code] est négatif, décale chaque sommet vers l'intérieur. Retourne une liste " -"des polygones parce que gonflage/dégonflage peut produire plusieurs " -"polygones distinctes. Retourne un tableau vide si [code]delta[/code] est " -"négatif et la valeur absolue de celui-ci dépasse approximativement les " -"dimensions du rectangle minimal englobant du polygone.\n" +"positif, le polygone décale chaque sommet vers l'extérieur. Si " +"[code]delta[/code] est négatif, décale chaque sommet vers l'intérieur. " +"Retourne une liste des polygones parce que gonflage/dégonflage peut produire " +"plusieurs polygones distinctes. Retourne un tableau vide si " +"[code]delta[/code] est négatif et la valeur absolue de celui-ci dépasse " +"approximativement les dimensions du rectangle minimal englobant du polygone." +"\n" "Les sommets de chaque polygone sont arrondis suivant [code]join_type[/code], " "voir [enum PolyJoinType].\n" "L'opération peut fournir un polygone extérieur (la limite extérieure) et " "plusieurs polygones à intérieur (représentant les trous) qui pourraient être " -"distingués en appelant [méthode is_polygon_clockwise].\n" -"[b]Note :[/b] Pour transformer les sommets en polygone, utilisez la méthode " -"[méthode Transform2D.xform]:\n" +"distingués en appelant [method is_polygon_clockwise].\n" +"[b]Note :[/b] Pour transformer les sommets en polygone, utilisez la méthode [" +"method Transform2D.xform]:\n" "[codeblock]\n" "var polygon = PoolVector2Array([Vector2(0, 0), Vector2(100, 0), Vector2(100, " "100), Vector2(0, 100)])\n" @@ -34112,15 +34022,16 @@ msgid "" "(hole) produced which could be distinguished by calling [method " "is_polygon_clockwise]." msgstr "" -"par la quantité [code]delta[/code] unités (pixels) dans toutes les " -"directions. Si [code]delta[/code] est positif, le polygone décale chaque " -"sommet vers l'extérieur. Retourne une liste des polygones parce que gonflage/" -"dégonflage peut produire plusieurs polygones distinctes. Si [code]delta[/" -"code] est négatif, retourne un tableau vide.\n" +"Gonfle ou dégonfle [code]polyline[/code] par la quantité [code]delta[/code] " +"d'unités (pixels) dans toutes les directions. Si [code]delta[/code] est " +"positif, le polygone décale chaque sommet vers l'extérieur. Retourne une " +"liste des polygones parce que gonflage/dégonflage peut produire plusieurs " +"polygones distinctes. Si [code]delta[/code] est négatif, retourne un tableau " +"vide.\n" "Les sommets de chaque polygone sont arrondis suivant [code]join_type[/code], " "voir [enum PolyJoinType].\n" -"Chaque point d'extrémité du polygone sera arrondi suivant [code]end_type[/" -"code], voir [enum PolyEndType].\n" +"Chaque point d'extrémité du polygone sera arrondi suivant " +"[code]end_type[/code], voir [enum PolyEndType].\n" "L'opération peut fournir un polygone extérieur (la limite extérieur) et " "plusieurs polygones à intérieur (représentant les trous) qui pourraient être " "distingués en appelant [method is_polygon_clockwise]." @@ -34363,39 +34274,35 @@ msgid "" msgstr "" #: doc/classes/GeometryInstance.xml -#, fuzzy msgid "" "The GeometryInstance's max LOD distance.\n" "[b]Note:[/b] This property currently has no effect." msgstr "" -"La distance min LOD de GeometryInstance3D.\n" +"La distance maximale pour ce LOD de la GeometryInstance.\n" "[b]Remarque :[/b] Cette propriété n’a actuellement aucun effet." #: doc/classes/GeometryInstance.xml -#, fuzzy msgid "" "The GeometryInstance's max LOD margin.\n" "[b]Note:[/b] This property currently has no effect." msgstr "" -"La distance min LOD de GeometryInstance3D.\n" +"La marge maximale pour ce LOD de la GeometryInstance.\n" "[b]Remarque :[/b] Cette propriété n’a actuellement aucun effet." #: doc/classes/GeometryInstance.xml -#, fuzzy msgid "" "The GeometryInstance's min LOD distance.\n" "[b]Note:[/b] This property currently has no effect." msgstr "" -"La distance min LOD de GeometryInstance3D.\n" +"La distance minimale pour ce LOD de la GeometryInstance.\n" "[b]Remarque :[/b] Cette propriété n’a actuellement aucun effet." #: doc/classes/GeometryInstance.xml -#, fuzzy msgid "" "The GeometryInstance's min LOD margin.\n" "[b]Note:[/b] This property currently has no effect." msgstr "" -"La distance min LOD de GeometryInstance3D.\n" +"La marge minimale pour ce LOD de la GeometryInstance.\n" "[b]Remarque :[/b] Cette propriété n’a actuellement aucun effet." #: doc/classes/GeometryInstance.xml @@ -34932,13 +34839,10 @@ msgstr "" "[code]false[/code] sinon." #: modules/mono/doc_classes/GodotSharp.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the Mono runtime is shutting down, [code]false[/" "code] otherwise." msgstr "" -"Renvoie [code]true[/code] (vrai) si [code]s[/code] vaut zéro ou quasiment " -"zéro." #: modules/mono/doc_classes/GodotSharp.xml msgid "" @@ -35620,14 +35524,12 @@ msgid "Returns the type of the output connection [code]idx[/code]." msgstr "Retourne le type de connexion pour la sortie [code]idx[/code]." #: doc/classes/GraphNode.xml -#, fuzzy msgid "Returns the left (input) [Color] of the slot [code]idx[/code]." -msgstr "Retourne le type du nœud à [code]idx[/code]." +msgstr "" #: doc/classes/GraphNode.xml -#, fuzzy msgid "Returns the right (output) [Color] of the slot [code]idx[/code]." -msgstr "Retourne le type du nœud à [code]idx[/code]." +msgstr "" #: doc/classes/GraphNode.xml msgid "Returns the left (input) type of the slot [code]idx[/code]." @@ -35670,17 +35572,17 @@ msgid "" "methods. You must enable at least one side of the slot to do so." msgstr "" "Définit les propriétés de l'emplacement avec identifiant [code]idx[/code].\n" -"Si [code]enable_left[code]/[code]right[/code], un port apparaîtra et " +"Si [code]enable_left[/code]/[code]right[/code], un port apparaîtra et " "l'emplacement pourra être connectée de ce côté.\n" -"[code]type_left[code]/[code]right[/code] est un type arbitraire du port. " +"[code]type_left[/code]/[code]right[/code] est un type arbitraire du port. " "Seuls les ports avec le même type peuvent être connectés.\n" -"[code]color_left[code]/[code]right[/code] est la teinte de l'icône du port " +"[code]color_left[/code]/[code]right[/code] est la teinte de l'icône du port " "de ce côté.\n" -"[code]custom_left[code]/[code]right[/code] est une texture personnalisée " +"[code]custom_left[/code]/[code]right[/code] est une texture personnalisée " "pour le port de ce côté.\n" "[b]Note :[/b] Cette méthode ne définit que les propriétés de l'emplacement. " -"Pour créer l'emplacement, ajoutez un enfant dérivé de [Control] au " -"GraphNode.\n" +"Pour créer l'emplacement, ajoutez un enfant dérivé de [Control] au GraphNode." +"\n" "Les propriétés individuelles peuvent être définies en utilisant l'une des " "méthodes [code]set_slot_*[/code]. Vous devez activer au moins un côté de " "l'emplacement pour le faire." @@ -36049,13 +35951,10 @@ msgstr "" "dans la grille." #: modules/gridmap/doc_classes/GridMap.xml -#, fuzzy msgid "" "Returns an array of all cells with the given item index specified in " "[code]item[/code]." msgstr "" -"Renvoie la texture de l’atlas de police de caractères à l’index [code]idx[/" -"code]." #: modules/gridmap/doc_classes/GridMap.xml msgid "" @@ -36092,13 +35991,10 @@ msgid "" msgstr "" #: modules/gridmap/doc_classes/GridMap.xml -#, fuzzy msgid "" "If [code]true[/code], this GridMap uses cell navmesh resources to create " "navigation regions." msgstr "" -"Si [code]true[/code], met à jour les animations en réponse aux notifications " -"liées au processus." #: modules/gridmap/doc_classes/GridMap.xml msgid "If [code]true[/code], grid items are centered on the X axis." @@ -36310,9 +36206,8 @@ msgid "The horizontal space between the [HBoxContainer]'s elements." msgstr "L'espace horizontal entre les éléments du [HBoxContainer]." #: doc/classes/HeightMapShape.xml -#, fuzzy msgid "Height map shape for 3D physics." -msgstr "Forme de polygone convexe pour la physique 3D." +msgstr "La forme de carte de hauteurs pour la physique 3D." #: doc/classes/HeightMapShape.xml msgid "" @@ -36585,14 +36480,13 @@ msgid "Displayed when the decrement button is being pressed." msgstr "Affiché quand le bouton de reduction est appuyé." #: doc/classes/HScrollBar.xml -#, fuzzy msgid "" "Icon used as a button to scroll the [ScrollBar] right. Supports custom step " "using the [member ScrollBar.custom_step] property." msgstr "" -"Icône utilisée comme bouton pour faire défiler la [ScrollBar] correctement. " -"Supporte l'étape personnalisée en utilisant la propriété [member ScrollBar." -"custom_step]." +"L'icône utilisée comme bouton pour faire défiler la [ScrollBar] vers la " +"droite. Supporte une étape personnalisée en utilisant la propriété [member " +"ScrollBar.custom_step]." #: doc/classes/HScrollBar.xml doc/classes/VScrollBar.xml msgid "Displayed when the mouse cursor hovers over the increment button." @@ -36611,7 +36505,7 @@ msgstr "" #: doc/classes/HScrollBar.xml doc/classes/VScrollBar.xml #, fuzzy msgid "Used when the mouse hovers over the grabber." -msgstr "Utilisé lorsque la souris survole le grappin." +msgstr "Utilisé lorsque la souris survole le glisseur." #: doc/classes/HScrollBar.xml doc/classes/VScrollBar.xml msgid "Used when the grabber is being dragged." @@ -37702,7 +37596,6 @@ msgid "A node with the ability to send HTTP(S) requests." msgstr "Un nœud qui permet d'envoyer des requêtes HTTP(S)." #: doc/classes/HTTPRequest.xml -#, fuzzy msgid "" "A node with the ability to send HTTP requests. Uses [HTTPClient] " "internally.\n" @@ -37782,28 +37675,28 @@ msgstr "" "des fichiers ou du contenu web via HTTP.\n" "[b]Avertissement :[/b] Voir les notes et avertissements du [HTTPClient] pour " "les limites, notamment concernant la sécurité SSL.\n" -"[b]Exemple pour contacter une API REST et afficher les champs retournés :[/" -"b]\n" +"[b]Exemple pour contacter une API REST et afficher les champs retournés :[/b]" +"\n" "[codeblock]\n" "func _ready():\n" -" # Créer un nœud de requête HTTP et le connecter au signal de " -"complétion.\n" +" # Créer un nœud de requête HTTP et le connecter au signal de complétion." +"\n" " var http_request = HTTPRequest.new()\n" " add_child(http_request)\n" " http_request.connect(\"request_completed\", self, " "\"_http_request_completed\")\n" "\n" -" # Lancer une requête GET. L'URL en-dessous retourne un JSON au moment de " +" # Lancer une requête GET. L'URL en dessous retourne un JSON au moment de " "l'écriture de ce tutoriel.\n" " var error = http_request.request(\"https://httpbin.org/get\")\n" " if error != OK:\n" " push_error(\"Une erreur est survenue dans la requête HTTP.\")\n" "\n" -" # Lancer une requête POST. L'URL en-dessous retourne un JSON au moment " +" # Lancer une requête POST. L'URL en dessous retourne un JSON au moment " "de l'écriture de ce tutoriel.\n" " # Note : Don't make simultaneous requests using a single HTTPRequest " "node.\n" -" # Le code en-dessous est uniquement donné comme exemple.\n" +" # Le code en dessous est uniquement donné comme exemple.\n" " var body = {\"nom\": \"Godette\"}\n" " error = http_request.request(\"https://httpbin.org/post\", [], true, " "HTTPClient.METHOD_POST, body)\n" @@ -37823,14 +37716,14 @@ msgstr "" "HTTPRequest:[/b]\n" "[codeblock]\n" "func _ready():\n" -" # Créer un nœud de requête HTTP et le connecter au signal de " -"complétion.\n" +" # Créer un nœud de requête HTTP et le connecter au signal de complétion." +"\n" " var http_request = HTTPRequest.new()\n" " add_child(http_request)\n" " http_request.connect(\"request_completed\", self, " "\"_http_request_completed\")\n" "\n" -" # Lancer une requête HTTP. L'URL en-dessous retourne une image PNG au " +" # Lancer une requête HTTP. L'URL en dessous retourne une image PNG au " "moment de l'écriture de ce tutoriel.\n" " var error = http_request.request(\"https://via.placeholder.com/512\")\n" " if error != OK:\n" @@ -37937,11 +37830,12 @@ msgid "" msgstr "" #: doc/classes/HTTPRequest.xml -#, fuzzy msgid "" "Maximum number of allowed redirects. This is used to prevent endless " "redirect loops." -msgstr "Nombre maximal de redirections autorisées." +msgstr "" +"Le nombre maximal de redirections autorisées. C'est utilisé pour éviter les " +"redirections infinies." #: doc/classes/HTTPRequest.xml msgid "" @@ -38155,9 +38049,8 @@ msgid "Fills [code]rect[/code] with [code]color[/code]." msgstr "Remplis le [code]rect[/code] avec la [code]color[/code]." #: doc/classes/Image.xml -#, fuzzy msgid "Blends low-alpha pixels with nearby pixels." -msgstr "Mélange les pixels à faible alpha avec les pixels à proximité." +msgstr "Mélange les pixels à faible opacité avec ceux proches." #: doc/classes/Image.xml msgid "Flips the image horizontally." @@ -38939,9 +38832,8 @@ msgid "" msgstr "" #: doc/classes/ImageTexture.xml -#, fuzzy msgid "Returns the format of the texture, one of [enum Image.Format]." -msgstr "Renvoie l'inverse de la racine carrée du paramètre." +msgstr "" #: doc/classes/ImageTexture.xml msgid "" @@ -39186,11 +39078,10 @@ msgid "" msgstr "" #: doc/classes/Input.xml -#, fuzzy msgid "" "Returns the current value of the joypad axis at given index (see [enum " "JoystickList])." -msgstr "Retourne l'état actuel de ce canal, voir [enum ChannelState]." +msgstr "" #: doc/classes/Input.xml msgid "Returns the index of the provided axis name." @@ -39490,10 +39381,9 @@ msgid "" msgstr "" #: doc/classes/Input.xml -#, fuzzy msgid "Controls the mouse mode. See [enum MouseMode] for more information." msgstr "" -"Définit le mode de la souris. Voir les constantes pour plus d'informations." +"Définit le mode de la souris. Voir [enum MouseMode] pour plus d'informations." #: doc/classes/Input.xml msgid "" @@ -39810,9 +39700,8 @@ msgid "" msgstr "" #: doc/classes/InputEventAction.xml -#, fuzzy msgid "InputEvent: Actions" -msgstr "Type d’évènement d’entrée pour les actions." +msgstr "Évènements d’entrée : les actions" #: doc/classes/InputEventAction.xml msgid "The action's name. Actions are accessed via this [String]." @@ -39991,9 +39880,8 @@ msgid "Wikipedia General MIDI Instrument List" msgstr "" #: doc/classes/InputEventMIDI.xml -#, fuzzy msgid "Wikipedia Piano Key Frequencies List" -msgstr "https://en.wikipedia.org/wiki/Piano_key_frequencies#List" +msgstr "La liste des fréquences des touches de piano sur Wikipédia" #: doc/classes/InputEventMIDI.xml msgid "" @@ -40167,12 +40055,12 @@ msgid "Mouse and input coordinates" msgstr "Les coordonnées de la souris" #: doc/classes/InputEventMouseMotion.xml -#, fuzzy msgid "" "Returns [code]true[/code] when using the eraser end of a stylus pen.\n" "[b]Note:[/b] This property is implemented on Linux, macOS and Windows." msgstr "" -"Retourne le nombre de disposition de clavier.\n" +"Retourne [code]true[/code] lors de l'utilisation de la gomme (l'autre " +"extrémité) d'un stylet.\n" "[b]Note :[/b] Cette méthode est implémentée sous Linux, macOS et Windows." #: doc/classes/InputEventMouseMotion.xml @@ -40534,11 +40422,11 @@ msgstr "" "automatiquement." #: doc/classes/InterpolatedCamera.xml -#, fuzzy msgid "" "The camera's process callback. See [enum InterpolatedCameraProcessMode]." msgstr "" -"La méthode de mise à jour de la camera. Voir [enum Camera2DProcessMode]." +"La méthode de mise à jour de la camera. Voir [enum " +"InterpolatedCameraProcessMode]." #: doc/classes/InterpolatedCamera.xml msgid "" @@ -41804,14 +41692,14 @@ msgid "" msgstr "" #: doc/classes/KinematicBody.xml doc/classes/KinematicBody2D.xml -#, fuzzy msgid "" "Returns the number of times the body collided and changed direction during " "the last call to [method move_and_slide] or [method " "move_and_slide_with_snap]." msgstr "" -"Renvoie le nombre de fois où le corps est entré en collision et a changé de " -"direction au cours du dernier appel vers [method move_and_slide]." +"Retourne le nombre de fois où le corps est entré en collision et a changé de " +"direction au cours du dernier appel vers [method move_and_slide] ou [method " +"move_and_slide_with_snap]." #: doc/classes/KinematicBody.xml doc/classes/KinematicBody2D.xml msgid "" @@ -42413,9 +42301,8 @@ msgid "Background [StyleBox] for the [Label]." msgstr "Le [StyleBox] d'arrière-plan pour le [Label]." #: doc/classes/Label3D.xml -#, fuzzy msgid "Displays plain text in a 3D world." -msgstr "Nœud de sprite en 2D dans un monde en 3D." +msgstr "Affiche du texte dans un monde en 3D." #: doc/classes/Label3D.xml msgid "" @@ -42430,78 +42317,67 @@ msgid "" msgstr "" #: doc/classes/Label3D.xml -#, fuzzy msgid "" "If [code]true[/code], the specified flag will be enabled. See [enum Label3D." "DrawFlags] for a list of flags." msgstr "" -"Si [code]true[/code], active l'option donné. Voir [enum Flags] pour ces " -"options." +"Si [code]true[/code], active le drapeau spécifié. Voir [enum Label3D." +"DrawFlags] pour la liste des drapeaux." #: doc/classes/Label3D.xml -#, fuzzy msgid "" "The alpha cutting mode to use for the sprite. See [enum AlphaCutMode] for " "possible values." msgstr "" -"Le mode d'orientation de la TileMap. Voir [enum Mode] pour les valeurs " -"possibles." #: doc/classes/Label3D.xml doc/classes/SpatialMaterial.xml msgid "Threshold at which the alpha scissor will discard values." msgstr "Le seuil à partir duquel le ciseau alpha ignorera les valeurs." #: doc/classes/Label3D.xml -#, fuzzy msgid "If [code]true[/code], wraps the text to the [member width]." -msgstr "Si [code]true[/code], cache la ligne à l'index spécifié." +msgstr "" #: doc/classes/Label3D.xml -#, fuzzy msgid "" "The billboard mode to use for the label. See [enum SpatialMaterial." "BillboardMode] for possible values." msgstr "" -"La direction de remplissage. Voir [enum FillMode] pour les valeurs possibles." #: doc/classes/Label3D.xml -#, fuzzy msgid "" "If [code]true[/code], text can be seen from the back as well, if " "[code]false[/code], it is invisible when looking at it from behind." msgstr "" -"Si [code]true[/code], la ligne sera verticale. Si [code]false[/code], elle " -"sera horizontale." #: doc/classes/Label3D.xml doc/classes/SpriteBase3D.xml -#, fuzzy msgid "" "If [code]true[/code], the label is rendered at the same size regardless of " "distance." msgstr "" -"Si [code]true[/code], l'objet est affiché à la même taille indépendamment de " -"sa distance à la caméra." +"Si [code]true[/code], le label est affiché à la même taille indépendamment " +"de sa distance à la caméra." #: doc/classes/Label3D.xml -#, fuzzy msgid "[Font] used for the [Label3D]'s text." -msgstr "[Font] utilisée pour le texte du [Label]." +msgstr "La [Font] utilisée pour le texte du [Label3D]." #: doc/classes/Label3D.xml msgid "" "Controls the text's horizontal alignment. Supports left, center, right. Set " "it to one of the [enum Align] constants." msgstr "" +"Control l'alignement horizontal du texte. Supporte à gauche, au centre, ou à " +"droite. Réglez-le à l'une des constantes de [enum Align]." #: doc/classes/Label3D.xml -#, fuzzy msgid "Vertical space between lines in multiline [Label3D]." -msgstr "L'espace vertical entre les lignes en multiligne [Label]." +msgstr "" +"L'espacement vertical entre les lignes en mode multi-ligne d'un [Label3D]." #: doc/classes/Label3D.xml -#, fuzzy msgid "Text [Color] of the [Label3D]." -msgstr "La [Color] par défaut du texte du [Label]." +msgstr "La [Color] du texte du [Label3D]." #: doc/classes/Label3D.xml doc/classes/SpatialMaterial.xml #: doc/classes/SpriteBase3D.xml @@ -42509,73 +42385,94 @@ msgid "" "If [code]true[/code], depth testing is disabled and the object will be drawn " "in render order." msgstr "" +"Si [code]true[/code], les tests de profondeur sont désactivés et l'objet " +"sera dessiné suivant son ordre de rendu et non suivant sa distance." #: doc/classes/Label3D.xml -#, fuzzy msgid "The text drawing offset (in pixels)." -msgstr "Le décalage du dessin de la texture." +msgstr "" #: doc/classes/Label3D.xml -#, fuzzy msgid "The tint of [Font]'s outline." -msgstr "La hauteur du cylindre." +msgstr "Le teinte du contour de la [Font]." #: doc/classes/Label3D.xml msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " "This is because opaque objects are not sorted, while transparent objects are " "sorted from back to front (subject to priority)." msgstr "" +"Définit la priorité de rendu pour la bordure du texte. Les objets les plus " +"prioritaires seront affichés par-dessus des objets les moins prioritaires.\n" +"[b]Note :[/b] Cela ne s'applique que si [member alpha_cut] est défini à [" +"constant ALPHA_CUT_DISABLED] (c'est la valeur par défaut).\n" +"[b]Note :[/b] Cela ne s'applique qu'au tri des objets transparents. Cela " +"n'affectera pas la façon dont les objets transparents sont triés par rapport " +"aux objets opaques. C'est parce que les objets opaques ne sont pas triés, " +"alors que les objets transparents sont triés de l'arrière vers l'avant (et " +"suivant leur priorité)." #: doc/classes/Label3D.xml -#, fuzzy msgid "The size of one pixel's width on the label to scale it in 3D." -msgstr "La taille d'un des pixels de la sprite pour définir sa taille en 3D." +msgstr "La taille d'un des pixels du label pour définir sa taille en 3D." #: doc/classes/Label3D.xml msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " "This is because opaque objects are not sorted, while transparent objects are " "sorted from back to front (subject to priority)." msgstr "" +"Définit la priorité de rendu pour le texte. Les objets les plus prioritaires " +"seront affichés par-dessus des objets les moins prioritaires.\n" +"[b]Note :[/b] Cela ne s'applique que si [member alpha_cut] est défini à [" +"constant ALPHA_CUT_DISABLED] (c'est la valeur par défaut).\n" +"[b]Note :[/b] Cela ne s'applique qu'au tri des objets transparents. Cela " +"n'affectera pas la façon dont les objets transparents sont triés par rapport " +"aux objets opaques. C'est parce que les objets opaques ne sont pas triés, " +"alors que les objets transparents sont triés de l'arrière vers l'avant (et " +"suivant leur priorité)." #: doc/classes/Label3D.xml -#, fuzzy msgid "" "If [code]true[/code], the [Light] in the [Environment] has effects on the " "label." -msgstr "Si [code]true[/code], ce [HTTPClient] a une réponse disponible." +msgstr "" #: doc/classes/Label3D.xml msgid "" "Controls the text's vertical alignment. Supports top, center, bottom. Set it " "to one of the [enum VAlign] constants." msgstr "" +"Control l'alignement vertical du texte. Supports en haut, au centre, et en " +"bas. Réglez-le à l'une des constantes de [enum VAlign]." #: doc/classes/Label3D.xml msgid "Text width (in pixels), used for autowrap and fill alignment." msgstr "" +"La largeur de texte (en pixels), utilisée pour les retours à la ligne et " +"l'alignement de remplissage." #: doc/classes/Label3D.xml -#, fuzzy msgid "If set, lights in the environment affect the label." -msgstr "Si [code]true[/code], ce [HTTPClient] a une réponse disponible." +msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" +"Si défini, le texte sera aussi visible de derrière. Sinon, la texture ne " +"sera visible que de face." #: doc/classes/Label3D.xml doc/classes/SpatialMaterial.xml #: doc/classes/SpriteBase3D.xml @@ -42583,11 +42480,16 @@ msgid "" "Disables the depth test, so this object is drawn on top of all others. " "However, objects drawn after it in the draw order may cover it." msgstr "" +"Désactive le test de profondeur, de sorte que cet objet sera dessiné devant " +"tous les autres. Cependant, les objets dessinés après lui dans l'ordre " +"d'affichage peuvent être devant." #: doc/classes/Label3D.xml msgid "" "Label is scaled by depth so that it always appears the same size on screen." msgstr "" +"L'étiquette est mise à l'échelle suivant la distance pour qu'elle apparaisse " +"toujours à la même taille à l'écran." #: doc/classes/Label3D.xml doc/classes/SpriteBase3D.xml msgid "Represents the size of the [enum DrawFlags] enum." @@ -42599,6 +42501,9 @@ msgid "" "areas, but transparency sorting issues may be visible when multiple " "transparent materials are overlapping." msgstr "" +"Ce mode réalise un mélange l'opacité standard. Il peut afficher des zones " +"translucides, mais des problèmes de tri selon la transparence peuvent être " +"visibles lorsque plusieurs matériaux transparents se chevauchent." #: doc/classes/Label3D.xml msgid "" @@ -42610,6 +42515,15 @@ msgid "" "scripts), this mode might have transparency sorting issues between the main " "text and the outline." msgstr "" +"Ce mode ne permet que les pixels transparents ou alors entièrement opaques. " +"Ce mode est également connu sous le nom de [i]alpha testing[/i] ou " +"[i]transparence 1 bit[/i].\n" +"[b]Note :[/b] Ce mode peut avoir des problèmes avec des polices avec " +"anticrénelage et des contours, essayez d'ajuster [member " +"alpha_scisor_threshold] ou en utilisant la police avec SDF.\n" +"[b]Note :[/b] Lors de l'utilisation de texte avec des caractères superposés " +"(par exemple des cursives), ce mode pourrait avoir des problèmes de tri de " +"la transparence entre le texte principal et le contour." #: doc/classes/Label3D.xml msgid "" @@ -42621,6 +42535,13 @@ msgid "" "scripts), this mode might have transparency sorting issues between the main " "text and the outline." msgstr "" +"Ce mode dessine des pixels entièrement opaques lors de la pré-passe de " +"profondeur. Ceci est plus lent que [constant ALPHA_CUT_DISABLED] ou " +"[constant ALPHA_CUT_DISCARD], mais ça permet d'afficher des zones " +"translucides et des bords lisses tout en utilisant le tri approprié.\n" +"[b]Note :[/b] Lors de l'utilisation de texte avec des caractères superposés " +"(par exemple des cursives), ce mode pourrait avoir des problèmes de tri de " +"la transparence entre le texte principal et le contour." #: doc/classes/LargeTexture.xml msgid "" @@ -42637,6 +42558,10 @@ msgid "" "You can dynamically add pieces ([Texture]s) to this [LargeTexture] using " "different offsets." msgstr "" +"[i]Obsolète (elle sera retiré dans Godot 4.0).[/i] Une [Texture] capable de " +"stocker de nombreuses textures plus petites avec des décalages.\n" +"Vous pouvez ajouter dynamiquement des [Texture] à ce [LargeTexture] en " +"utilisant différents décalages." #: doc/classes/LargeTexture.xml msgid "" @@ -42659,9 +42584,8 @@ msgid "Returns the offset of the piece with the index [code]idx[/code]." msgstr "Retourne le décalage de la pièce à l'index [code]idx[/code]." #: doc/classes/LargeTexture.xml -#, fuzzy msgid "Returns the [Texture] of the piece with the index [code]idx[/code]." -msgstr "Retourne la position du point à l'index [code]point[/code]." +msgstr "" #: doc/classes/LargeTexture.xml msgid "" @@ -42672,12 +42596,10 @@ msgstr "" "code]." #: doc/classes/LargeTexture.xml -#, fuzzy msgid "" "Sets the [Texture] of the piece with index [code]idx[/code] to " "[code]texture[/code]." msgstr "" -"Déplace l’élément de l’index [code]from_idx[/code] à [code]to_idx[/code]." #: doc/classes/LargeTexture.xml msgid "Sets the size of this [LargeTexture]." @@ -42694,6 +42616,11 @@ msgid "" "from it. Light contains the common variables and parameters used for " "lighting." msgstr "" +"Light est la classe de base [i]abstraite[/i] pour les lumières. Puisque ça " +"ne peut être instancié, ça ne devrait pas être utilisé directement. D'autres " +"types de nœuds de lumière héritent de cette classe, qui contient les " +"variables communes aux sous-classes, et les paramètres utilisés pour " +"l'éclairage." #: doc/classes/Light.xml doc/classes/SpotLight.xml msgid "3D lights and shadows" @@ -42712,6 +42639,8 @@ msgid "" "If [code]true[/code], the light only appears in the editor and will not be " "visible at runtime." msgstr "" +"Si [code]true[/code], la lumière n'apparaît que dans l'éditeur et ne sera " +"pas visible au lancement du jeu." #: doc/classes/Light.xml msgid "The light's bake mode. See [enum BakeMode]." @@ -42722,6 +42651,9 @@ msgid "" "The light's color. An [i]overbright[/i] color can be used to achieve a " "result equivalent to increasing the light's [member light_energy]." msgstr "" +"La couleur de la lumière. Une couleur [i]sur-brillante[/i] peut être " +"utilisée pour un résultant équivalent à augmenter l'énergie [member " +"light_energy] de la lumière." #: doc/classes/Light.xml msgid "The light will affect objects in the selected layers." @@ -42733,18 +42665,26 @@ msgid "" "[OmniLight] and [SpotLight], changing this value will only change the light " "color's intensity, not the light's radius." msgstr "" +"Le multiplicateur de force de la lumière (ça n'a aucune unité physique). " +"Pour [OmniLight] et [SpotLight], changer cette valeur ne changera que " +"l'intensité de la constante de couleur de la lumière, et non le rayon de la " +"lumière." #: doc/classes/Light.xml msgid "" "Secondary multiplier used with indirect light (light bounces). This works on " "both [BakedLightmap] and [GIProbe]." msgstr "" +"Le multiplicateur secondaire utilisé pour la lumière indirecte (les rebonds " +"de lumière). Cela fonctionne avec [BakedLightmap] et aussi [GIProbe]." #: doc/classes/Light.xml msgid "" "If [code]true[/code], the light's effect is reversed, darkening areas and " "casting bright shadows." msgstr "" +"Si [code]true[/code], l'effet de la lumière est inversé, assombrissant les " +"zones et lançant des ombres lumineuses." #: doc/classes/Light.xml msgid "" @@ -42761,6 +42701,11 @@ msgid "" "emission, this can be used to avoid unrealistic reflections when placing " "lights above an emissive surface." msgstr "" +"L'intensité du reflet spéculaire dans les objets touchés par la lumière. " +"Avec [code]0[/code], la lumière devient une lumière purement diffuse. Si ça " +"n'est pas une émission pré-calculée, cela peut être utilisé pour éviter des " +"reflets irréalistes lorsqu'on place des lumières au-dessus d'une surface " +"émise." #: doc/classes/Light.xml msgid "" @@ -42768,6 +42713,10 @@ msgid "" "shadowing (\"shadow acne\"), while too large a value causes shadows to " "separate from casters (\"peter-panning\"). Adjust as needed." msgstr "" +"Utilisé pour ajuster l'apparence de l'ombre. Une valeur trop petite résulte " +"au auto-ombrage (« shadow acne »), et quqand trop grande, ça provoque des " +"ombres séparées de l'objet qui crée l'ombre (« peter-panning »). Réglez " +"selon les besoins." #: doc/classes/Light.xml msgid "The color of shadows cast by this light." @@ -42781,6 +42730,11 @@ msgid "" "[b]Note:[/b] Contact shadows can look broken, so leaving this property to " "[code]0.0[/code] is recommended." msgstr "" +"Tente de réduire l'écart [member shadow_bias] en rendant les ombres de " +"contact en fonction de l'espace-écran. Cela a un impact sur les " +"performances, surtout avec des valeurs élevées.\n" +"[b]Note :[/b] Les ombres de contact peuvent sembler brisées, donc laisser " +"cette propriété à [code]0.0[/code] est plutôt recommandé." #: doc/classes/Light.xml msgid "If [code]true[/code], the light will cast shadows." @@ -42793,6 +42747,11 @@ msgid "" "cast a shadow on both sides of the mesh, set the mesh to use double-sided " "shadows with [constant GeometryInstance.SHADOW_CASTING_SETTING_DOUBLE_SIDED]." msgstr "" +"Si [code]true[/code], inverse la face arrière du maillage. Cela peut être " +"utile lorsque vous avez un maillage plat qui a une lumière derrière elle. Si " +"vous avez besoin de lancer une ombre sur les deux côtés du maillage, " +"définissez le maillage pour utiliser les deux faces avec [constant " +"GeometryInstance.SHADOW_CASTING_SETTING_DOUBLE_SIDED]." #: doc/classes/Light.xml msgid "Constant for accessing [member light_energy]." @@ -42892,10 +42851,13 @@ msgid "" "Light is ignored when baking.\n" "[b]Note:[/b] Hiding a light does [i]not[/i] affect baking." msgstr "" +"La lumière est ignorée lors du pré-calcul.\n" +"[b]Note :[/b] L'enregistrement d'une lumière ne [i]n'affecte pas[/i] le pré-" +"calcul." #: doc/classes/Light.xml msgid "Only indirect lighting will be baked (default)." -msgstr "" +msgstr "Seul l'éclairage indirect sera pré-calculé (choix par défaut)." #: doc/classes/Light.xml msgid "" @@ -42903,6 +42865,9 @@ msgid "" "[b]Note:[/b] You should hide the light if you don't want it to appear twice " "(dynamic and baked)." msgstr "" +"La lumière directe et indirecte sera pré-calculée.\n" +"[b]Note :[/b] Vous devriez cacher la lumière si vous ne voulez pas qu'elle " +"apparaisse deux fois (une fois dynamique et une autre pour le pré-calcul)." #: doc/classes/Light2D.xml msgid "Casts light in a 2D environment." @@ -42915,6 +42880,11 @@ msgid "" "parameters (range and shadows-related).\n" "[b]Note:[/b] Light2D can also be used as a mask." msgstr "" +"Montre la lumière dans un environnement 2D. La lumière est définie par une " +"texture (généralement grise), une couleur, une valeur énergétique, un mode " +"(voir les constantes), et divers autres paramètres (relatifs à la portée et " +"aux ombres).\n" +"[b]Note :[/b] Light2D peut aussi être utilisée comme masque." #: doc/classes/Light2D.xml msgid "The Light2D's [Color]." @@ -42939,20 +42909,23 @@ msgstr "" #: doc/classes/Light2D.xml msgid "The Light2D's mode. See [enum Mode] constants for values." msgstr "" +"Le mode de la Light2D. Voir les constantes [enum Mode] pour les valeurs." #: doc/classes/Light2D.xml msgid "The offset of the Light2D's [code]texture[/code]." -msgstr "" +msgstr "Le décalage de la [code]texture[/code] de la Light2D." #: doc/classes/Light2D.xml msgid "The height of the Light2D. Used with 2D normal mapping." -msgstr "" +msgstr "La hauteur du Light2D. Utilisé avec une mapping de normale 2D." #: doc/classes/Light2D.xml msgid "" "The layer mask. Only objects with a matching mask will be affected by the " "Light2D." msgstr "" +"Le masque de calque. Seuls les objets avec un masque correspondant seront " +"sous l'influence de ce Light2D." #: doc/classes/Light2D.xml msgid "Maximum layer value of objects that are affected by the Light2D." @@ -42979,7 +42952,6 @@ msgstr "" "les Light2D." #: doc/classes/Light2D.xml -#, fuzzy msgid "Shadow buffer size." msgstr "Taille du tampon d'ombre." @@ -43003,13 +42975,16 @@ msgstr "Valeur de lissage pour les ombres." #: doc/classes/Light2D.xml msgid "Smooth shadow gradient length." -msgstr "" +msgstr "Longeur de lissage du dégradé d'ombre." #: doc/classes/Light2D.xml msgid "" "The shadow mask. Used with [LightOccluder2D] to cast shadows. Only occluders " "with a matching light mask will cast shadows." msgstr "" +"Le masque d'ombre. Utilisé avec [LightOccluder2D] pour lancer des ombres. " +"Seuls les occulteurs avec un masque de lumière correspondant lanceront des " +"ombres." #: doc/classes/Light2D.xml msgid "[Texture] used for the Light2D's appearance." @@ -43024,18 +42999,24 @@ msgid "" "Adds the value of pixels corresponding to the Light2D to the values of " "pixels under it. This is the common behavior of a light." msgstr "" +"Ajoute la valeur des pixels correspondant à la Light2D aux valeurs des " +"pixels sous elle. C'est le comportement classique des lumières." #: doc/classes/Light2D.xml msgid "" "Subtracts the value of pixels corresponding to the Light2D to the values of " "pixels under it, resulting in inversed light effect." msgstr "" +"Soustrait la valeur des pixels correspondant à la Light2D aux valeurs des " +"pixels sous elle, ce qui entraîne un effet de lumière inversé." #: doc/classes/Light2D.xml msgid "" "Mix the value of pixels corresponding to the Light2D to the values of pixels " "under it by linear interpolation." msgstr "" +"Mélange la valeur des pixels correspondant à la Light2D aux valeurs des " +"pixels sous elle, via une interpolation linéaire." #: doc/classes/Light2D.xml msgid "" @@ -43043,40 +43024,54 @@ msgid "" "parts of the screen underneath depending on the value of each pixel of the " "light (mask) texture." msgstr "" +"La texture de lumière de la Light2D est utilisée comme masque, cache ou " +"révèle des parties de l'écran sous la valeur de chaque pixel de la texture " +"de la lumière (masque)." #: doc/classes/Light2D.xml msgid "No filter applies to the shadow map. See [member shadow_filter]." msgstr "" +"Aucun filtre ne s'applique à la carte d'ombre. Voir [member Shadow_filter]." #: doc/classes/Light2D.xml msgid "" "Percentage closer filtering (3 samples) applies to the shadow map. See " "[member shadow_filter]." msgstr "" +"Le pourcentage de filtrage proche (3 échantillons) s'applique à la carte de " +"l'ombre. Voir [member Shadow_filter]." #: doc/classes/Light2D.xml msgid "" "Percentage closer filtering (5 samples) applies to the shadow map. See " "[member shadow_filter]." msgstr "" +"Le pourcentage de filtrage proche (5 échantillons) s'applique à la carte de " +"l'ombre. Voir [member Shadow_filter]." #: doc/classes/Light2D.xml msgid "" "Percentage closer filtering (7 samples) applies to the shadow map. See " "[member shadow_filter]." msgstr "" +"Le pourcentage de filtrage proche (7 échantillons) s'applique à la carte de " +"l'ombre. Voir [member Shadow_filter]." #: doc/classes/Light2D.xml msgid "" "Percentage closer filtering (9 samples) applies to the shadow map. See " "[member shadow_filter]." msgstr "" +"Le pourcentage de filtrage proche (9 échantillons) s'applique à la carte de " +"l'ombre. Voir [member Shadow_filter]." #: doc/classes/Light2D.xml msgid "" "Percentage closer filtering (13 samples) applies to the shadow map. See " "[member shadow_filter]." msgstr "" +"Le pourcentage de filtrage proche (13 échantillons) s'applique à la carte de " +"l'ombre. Voir [member Shadow_filter]." #: doc/classes/LightOccluder2D.xml msgid "Occludes light cast by a Light2D, casting shadows." @@ -43094,10 +43089,12 @@ msgid "" "The LightOccluder2D's light mask. The LightOccluder2D will cast shadows only " "from Light2D(s) that have the same light mask(s)." msgstr "" +"Le masque de lumière du LightOccluder2D. Le LightOccluder2D ne lancera que " +"des ombres que sur les Light2D qui ont le même masque de lumière." #: doc/classes/LightOccluder2D.xml msgid "The [OccluderPolygon2D] used to compute the shadow." -msgstr "" +msgstr "Le [OccluderPolygon2D] utilisé pour calculer l'ombre." #: doc/classes/Line2D.xml msgid "A 2D line." @@ -43113,6 +43110,14 @@ msgid "" "[member ProjectSettings.rendering/limits/buffers/" "canvas_polygon_index_buffer_size_kb]." msgstr "" +"Une ligne à travers plusieurs points dans l'espace 2D. Supporte une largeur " +"et une couleur différentes sur la longueur, la texture et plusieurs types " +"d'embout et de jointure.\n" +"[b]Note :[/b] Par défaut, Godot ne peut dessiner que 4 096 points de " +"polygone à la fois. Pour augmenter cette limite, ouvrez les paramètres du " +"projet et augmentez [member ProjectSettings.rendering/limits/buffers/" +"canvas_polygon_buffer_size_kb] et [member ProjectSettings.rendering/limits/" +"buffers/canvas_polygon_index_buffer_size_kb]." #: doc/classes/Line2D.xml msgid "" @@ -43125,10 +43130,18 @@ msgid "" "get_point_count][/code]), the point will be appended at the end of the point " "list." msgstr "" +"Ajoute un point au [code]position[/code]. Ajoute le point à la fin de la " +"ligne.\n" +"Si [code]at_position[/code] est donné, le point est inséré avant l'indice " +"[code]at_position[/code], en déplaçant ce point (et chaque point après) " +"après le point inséré. Si [code]at_position[/code] n'est pas donné, ou est " +"une valeur invalide ([code]at_position < 0[/code] ou [code]at_position >= " +"[method get_point_count][/code]), le point sera ajouté à la fin de la liste " +"des points." #: doc/classes/Line2D.xml msgid "Removes all points from the line." -msgstr "" +msgstr "Retire tous les points de la ligne." #: doc/classes/Line2D.xml msgid "Returns the Line2D's amount of points." @@ -43164,6 +43177,19 @@ msgid "" "perform antialiasing. 2D batching is also still supported with those " "antialiased lines." msgstr "" +"Si [code]true[/code], la bordure de la ligne essayera d'activer " +"anticrénelage en dessinant de fines lignes en OpenGL sur les bords de la " +"ligne.\n" +"[b]Note :[/b] Line2D n'est pas accéléré par lots si [code]antialiased[/code] " +"est [code]true[/code].\n" +"[b]Note :[/b] En raison de son fonctionnement, l'anticrénelage calculé en " +"interne n'est pas correct pour les lignes semi-transparents voire peut ne " +"pas fonctionner sur certaines plateformes. Vous pouvez corriger ce problème " +"en installant le greffon [url=https://github.com/godot-extended-libraries/" +"godot-antialiased-line2d]Antialiased Line2D[/url] puis créez un nœud " +"\"AntialiasedPolygon2D\". Ce nœud utilise des texture avec des mipmaps " +"personnalisés pour afficher l'anticrénelage. L'accélération par lot est " +"toujours supporté même avec les lignes avec anticrénelage." #: doc/classes/Line2D.xml msgid "" @@ -43190,6 +43216,8 @@ msgid "" "The gradient is drawn through the whole line from start to finish. The " "default color will not be used if a gradient is set." msgstr "" +"Le dégradé est dessiné par toute la ligne du début à la fin. La couleur par " +"défaut ne sera pas utilisée si un dégradé est défini." #: doc/classes/Line2D.xml msgid "The style for the points between the start and the end." @@ -43200,6 +43228,9 @@ msgid "" "The points that form the lines. The line is drawn between every point set in " "this array. Points are interpreted as local vectors." msgstr "" +"Les points qui forment les lignes. La ligne est tracée entre chaque point " +"défini dans ce tableau. Les points sont interprétés comme des vecteurs " +"locaux." #: doc/classes/Line2D.xml msgid "" @@ -43210,24 +43241,37 @@ msgid "" "width]. For thin lines, this value should be reduced to a number between " "[code]2[/code] and [code]4[/code] to improve performance." msgstr "" +"Le lissage des coins et des bouts. Les valeurs plus élevées affichent des " +"coins plus lisses, mais demandent plus de ressources pour le rendu. Ceci " +"n'est utilisé que si un coin ou un bout est défini comme arrondi.\n" +"[b]Note :[/b] La valeur par défaut est réglée pour les lignes avec la " +"largeur [member width] par défaut. Pour les lignes fines, cette valeur " +"devrait être réduite à entre [code]2[/code] et [code]4[/code] pour améliorer " +"les performances." #: doc/classes/Line2D.xml msgid "" "The direction difference in radians between vector points. This value is " "only used if [member joint_mode] is set to [constant LINE_JOINT_SHARP]." msgstr "" +"La différence de direction entre les points vectoriels. Cette valeur n'est " +"utilisée que si [member joint_mode] est [constant LINE_JOINT_SHARP]." #: doc/classes/Line2D.xml msgid "" "The texture used for the line's texture. Uses [code]texture_mode[/code] for " "drawing style." msgstr "" +"La texture utilisée pour la texture de la ligne. Utilise " +"[code]texture_mode[/code] pour le style de dessin." #: doc/classes/Line2D.xml msgid "" "The style to render the [code]texture[/code] on the line. Use [enum " "LineTextureMode] constants." msgstr "" +"Le style de rendu de la [code]texture[/code] sur la ligne. Utilisez une des " +"constantes [enum LineTextureMode]." #: doc/classes/Line2D.xml msgid "The line's width." @@ -43238,12 +43282,16 @@ msgid "" "The line's width varies with the curve. The original width is simply " "multiply by the value of the Curve." msgstr "" +"La largeur de la ligne dépend selon la courbe. La largeur originale est " +"simplement multipliée par la valeur de la Curve." #: doc/classes/Line2D.xml msgid "" "The line's joints will be pointy. If [code]sharp_limit[/code] is greater " "than the rotation of a joint, it becomes a bevel joint instead." msgstr "" +"Les coins de la ligne sont pointus. Si [code]sharp_limit[/code] est plus " +"grand que l'angle d'un coin, ça devient un biseau." #: doc/classes/Line2D.xml msgid "The line's joints will be bevelled/chamfered." @@ -43251,7 +43299,7 @@ msgstr "" #: doc/classes/Line2D.xml msgid "The line's joints will be rounded." -msgstr "" +msgstr "Les coins de la ligne seront arrondis." #: doc/classes/Line2D.xml msgid "Don't draw a line cap." @@ -43269,6 +43317,7 @@ msgstr "Dessine le bout de la ligne avec un arrondi." msgid "" "Takes the left pixels of the texture and renders it over the whole line." msgstr "" +"Utilise les pixels de gauche de la texture pour le rendu de toute la ligne." #: doc/classes/Line2D.xml msgid "" @@ -43281,10 +43330,12 @@ msgid "" "Stretches the texture across the line. Import the texture with [b]Repeat[/b] " "disabled for best results." msgstr "" +"Étire la texture à travers la ligne. Importez la texture avec la " +"[b]répétition[/b] désactivée pour de meilleurs résultats." #: doc/classes/LineEdit.xml msgid "Control that provides single-line string editing." -msgstr "" +msgstr "Le Control qui fournit l'édition d'un texte d'une seule ligne." #: doc/classes/LineEdit.xml msgid "" @@ -43372,6 +43423,9 @@ msgid "" "[code]from_column[/code] to [code]to_column[/code]. Both parameters should " "be within the text's length." msgstr "" +"Supprime une section du [member text] allant de la position " +"[code]from_column[/code] à [code]to_column[/code]. Les deux paramètres " +"doivent être de la longueur du texte." #: doc/classes/LineEdit.xml doc/classes/RichTextLabel.xml msgid "Clears the current selection." @@ -43385,12 +43439,19 @@ msgid "" "may cause a crash. If you wish to hide it or any of its children, use their " "[member CanvasItem.visible] property." msgstr "" +"Retourne le [PopupMenu] de ce [LineEdit]. Par défaut, ce menu s'affiche " +"lorsque le clic-droit sur le [LineEdit].\n" +"[b]Avertissement :[/b] Il s'agit d'un nœud interne requis, le retirer et le " +"supprimer peut causer un plantage. Si vous voulez le cacher, lui ou un de " +"ses enfants, utilisez la propriété [member CanvasItem.visible]." #: doc/classes/LineEdit.xml msgid "" "Returns the scroll offset due to [member caret_position], as a number of " "characters." msgstr "" +"Retourne le décalage du défilement suivant [member caret_position], en tant " +"que nombre de caractères." #: doc/classes/LineEdit.xml doc/classes/TextEdit.xml msgid "Returns the selection begin column." @@ -43401,9 +43462,8 @@ msgid "Returns the selection end column." msgstr "Retourne la colonne de fin de sélection." #: doc/classes/LineEdit.xml -#, fuzzy msgid "Returns [code]true[/code] if the user has selected text." -msgstr "Retourne [code]true[/code] si le minuteur est arrêté." +msgstr "Retourne [code]true[/code] si l'utilisateur a sélectionné du texte." #: doc/classes/LineEdit.xml msgid "Executes a given action as defined in the [enum MenuItems] enum." @@ -43422,6 +43482,15 @@ msgid "" "select(2, 5) # Will select \"lco\".\n" "[/codeblock]" msgstr "" +"Sélectionne les caractères à l'intérieur du [LineEdit] entre [code]from[/" +"code] et [code]to[/code]. Par défaut, [code]from[/code] est au début et " +"[code]to[/code] à la fin.\n" +"[codeblock]\n" +"text = \"Bienvenue\"\n" +"select() # Will select \"Bienvenue\".\n" +"select(5) # Will select \"venue\".\n" +"select(2, 7) # Will select \"enven\".\n" +"[/codeblock]" #: doc/classes/LineEdit.xml msgid "Selects the whole [String]." @@ -43444,6 +43513,8 @@ msgid "" "The cursor's position inside the [LineEdit]. When set, the text may scroll " "to accommodate it." msgstr "" +"La position du curseur dans le [LineEdit]. Lorsqu'il est défini, le texte " +"peut défiler pour l'afficher." #: doc/classes/LineEdit.xml msgid "" @@ -43460,13 +43531,12 @@ msgstr "Si [code]true[/code], le menu contextuel apparaitra au clic-droit." #: doc/classes/LineEdit.xml doc/classes/RichTextLabel.xml #: doc/classes/TextEdit.xml -#, fuzzy msgid "" "If [code]true[/code], the selected text will be deselected when focus is " "lost." msgstr "" -"Si [code]true[/code], la cellule actuellement sélectionnée peut être " -"sélectionnée à nouveau." +"Si [code]true[/code], le texte actuellement sélectionné sera désélectionné " +"quand le focus sera perdu." #: doc/classes/LineEdit.xml msgid "" @@ -44184,35 +44254,58 @@ msgid "" "add_constant_override(\"margin_right\", margin_value)\n" "[/codeblock]" msgstr "" +"Ajoute une marge supérieure, gauche, inférieure et droite à tous les nœuds " +"[Control] qui sont des enfants directs du conteneur. Pour contrôler la marge " +"du [MarginContainer], utilisez les propriétés [code]margin_*[/code] du " +"thèmes listées ci-dessous.\n" +"[b]Note :[/b] Soyez prudent, les valeurs des marges de [Control] sont " +"différentes des valeurs de marge constante. Si vous souhaitez modifier les " +"valeurs de marge personnalisées du [MarginContainer] par code, vous devez " +"utiliser les exemples suivants :\n" +"[codeblock]\n" +"# Cet exemple suppose que ce script hérite de MarginContainer.\n" +"var margin_value = 100\n" +"add_constant_override(\"margin_top\", margin_value)\n" +"add_constant_override(\"margin_left\", margin_value)\n" +"add_constant_override(\"margin_bottom\", margin_value)\n" +"add_constant_override(\"margin_right\", margin_value)\n" +"[/codeblock]" #: doc/classes/MarginContainer.xml msgid "" "All direct children of [MarginContainer] will have a bottom margin of " "[code]margin_bottom[/code] pixels." msgstr "" +"Tous les enfants directs de [MarginContainer] auront la marge du bas de " +"[code]margin_bottom[/code] pixels." #: doc/classes/MarginContainer.xml msgid "" "All direct children of [MarginContainer] will have a left margin of " "[code]margin_left[/code] pixels." msgstr "" +"Tous les enfants directs de [MarginContainer] auront la marge gauche de " +"[code]margin_left[/code] pixels." #: doc/classes/MarginContainer.xml msgid "" "All direct children of [MarginContainer] will have a right margin of " "[code]margin_right[/code] pixels." msgstr "" +"Tous les enfants directs de [MarginContainer] auront la marge droite de " +"[code]margin_right[/code] pixels." #: doc/classes/MarginContainer.xml msgid "" "All direct children of [MarginContainer] will have a top margin of " "[code]margin_top[/code] pixels." msgstr "" +"Tous les enfants directs de [MarginContainer] auront la marge du haut de " +"[code]margin_top[/code] pixels." #: doc/classes/Marshalls.xml -#, fuzzy msgid "Data transformation (marshalling) and encoding helpers." -msgstr "Transformation de données (marshalling) et assistants d'encodage." +msgstr "Transformation de données (\"marshalling\") et assistants d'encodage." #: doc/classes/Marshalls.xml msgid "Provides data transformation and encoding utility functions." @@ -44221,13 +44314,12 @@ msgstr "" "données." #: doc/classes/Marshalls.xml -#, fuzzy msgid "" "Returns a decoded [PoolByteArray] corresponding to the Base64-encoded string " "[code]base64_str[/code]." msgstr "" -"Renvoie un [PoolByteArray] décodé correspondant à la chaîne de caractères " -"encodée en Base64 [code]base64_str[/code]." +"Retourne un [PoolByteArray] décodé correspondant à la chaîne de caractères " +"[code]base64_str[/code] encodée en Base64." #: doc/classes/Marshalls.xml msgid "" @@ -44361,6 +44453,9 @@ msgid "" "text color of the button. Disabled, hovered, and pressed states take " "precedence over this color." msgstr "" +"Le texte [Color] utilisé quand le [MenuButton] a le focus. Il suffit de " +"remplacer la couleur de texte normale du bouton. Les états désactivés, " +"survolés et pressés sont prioritaires sur cette couleur." #: doc/classes/MenuButton.xml msgid "Text [Color] used when the [MenuButton] is being hovered." @@ -44388,6 +44483,9 @@ msgid "" "current [StyleBox], so using [StyleBoxEmpty] will just disable the focus " "visual effect." msgstr "" +"La [StyleBox] utilisée quand le [MenuButton] a le focus. Elle est affichée " +"par dessus l'actuelle [StyleBox], donc utiliser [StyleBoxEmpty] va tout " +"simplement désactiver l'effet visuel du focus." #: doc/classes/MenuButton.xml msgid "[StyleBox] used when the [MenuButton] is being hovered." @@ -44414,6 +44512,12 @@ msgid "" "surfaces is preferred to a single surface, because objects created in 3D " "editing software commonly contain multiple materials." msgstr "" +"Mesh est un type de [Resource] qui contient la géométrie à base de tableaux " +"de sommets, divisé en [i]surfaces[/i]. Chaque surface contient un tableau " +"complètement séparé et un matériau utilisé pour le dessiner. Au niveau du " +"design, un maillage avec plusieurs surfaces est préféré à une seule surface, " +"car les objets créés dans le logiciel d'édition 3D contiennent généralement " +"plusieurs matériaux." #: doc/classes/Mesh.xml msgid "" @@ -44424,6 +44528,13 @@ msgid "" "If [code]simplify[/code] is [code]true[/code], the geometry can be further " "simplified to reduce the amount of vertices. Disabled by default." msgstr "" +"Calcule la [ConvexPolygonShape] du maillage.\n" +"Si [code]clean[/code] est [code]true[/code] (par défaut), les sommets " +"intérieurs et en double sont automatiquement supprimés. Vous pouvez le " +"définir à [code]false[/code] pour rendre le processus plus rapide si " +"nécessaire.\n" +"Si [code]simplify[/code] est [code]true[/code], la géométrie peut être plus " +"simplifiée pour réduire la quantité de sommets. Désactivé par défaut." #: doc/classes/Mesh.xml msgid "" @@ -44432,6 +44543,10 @@ msgid "" "[b]Note:[/b] This method typically returns the vertices in reverse order (e." "g. clockwise to counterclockwise)." msgstr "" +"Calcule un maillage de contour avec un décalage défini (marge) du maillage " +"d'origine.\n" +"[b]Note :[/b] Cette méthode renvoie généralement les sommets en ordre " +"inverse (par ex., du sens horaire au sens anti-horaire)." #: doc/classes/Mesh.xml msgid "Calculate a [ConcavePolygonShape] from the mesh." @@ -44448,6 +44563,10 @@ msgid "" "get_transformed_aabb].\n" "[b]Note:[/b] This is only implemented for [ArrayMesh] and [PrimitiveMesh]." msgstr "" +"Retourne le plus petit [AABB] englobant ce maillage dans l'espace local. Non " +"affecté par [code]custom_aabb[/code]. Voir aussi [method VisualInstance." +"get_transformed_aabb]\n" +"[b]Note :[/b] Ceci n'est implémenté que pour [ArrayMesh] et [PrimitiveMesh]." #: doc/classes/Mesh.xml msgid "" @@ -44772,6 +44891,9 @@ msgid "" "Uses specified surface of given [Mesh] to populate data for MeshDataTool.\n" "Requires [Mesh] with primitive type [constant Mesh.PRIMITIVE_TRIANGLES]." msgstr "" +"Utiliser la surface spécifiée de [Mesh] pour construire les données pour le " +"MeshDataTool.\n" +"Nécessite un [Mesh] de type primitif [constant Mesh.PRIMITIVE_TRIANGES]." #: doc/classes/MeshDataTool.xml msgid "Returns the number of edges in this [Mesh]." @@ -44791,6 +44913,9 @@ msgid "" "Vertex argument can only be 0 or 1 because edges are comprised of two " "vertices." msgstr "" +"Retourne l'index des sommet spécifiés reliés au bord donné.\n" +"L'argument du sommet ne peut être que 0 ou 1 car les bords ne sont composés " +"que de deux sommets." #: doc/classes/MeshDataTool.xml msgid "Returns the number of faces in this [Mesh]." @@ -44801,6 +44926,9 @@ msgid "" "Returns specified edge associated with given face.\n" "Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" +"Retourne le bord spécifié associé au face donné.\n" +"L'argument du bord doit être soit 0, 1 ou 2 parce qu'une face n'a que trois " +"bords." #: doc/classes/MeshDataTool.xml msgid "Returns the metadata associated with the given face." @@ -44816,6 +44944,9 @@ msgid "" "Vertex argument must be either 0, 1, or 2 because faces contain three " "vertices." msgstr "" +"Retourne le vertx spécifié du face donné.\n" +"L'argument du sommet doit être soit 0, 1 ou 2 parce que les faces ne " +"contiennent que trois sommets." #: doc/classes/MeshDataTool.xml msgid "" @@ -44826,6 +44957,12 @@ msgid "" "ARRAY_FORMAT_NORMAL] is [code]2[/code].\n" "See [enum ArrayMesh.ArrayFormat] for a list of format flags." msgstr "" +"Retourne le format du [Mesh]. Le format est un entier composé des drapeaux " +"de format du [Mesh]. Par exemple, un maillage contenant à la fois des " +"sommets et des normales retournerait un format de [code]3[/code] parce que [" +"constant ArrayMesh.ARRAY_FORMAT_VERTEX] est [code]1[/code] et [constant " +"ArrayMesh.ARRAY_FORMAT_NORMAL] est [code]2[/code].\n" +"Voir [enum ArrayMesh.ArrayFormat] pour une liste de drapeaux de format." #: doc/classes/MeshDataTool.xml msgid "Returns the material assigned to the [Mesh]." @@ -44940,6 +45077,13 @@ msgid "" "[Mesh] has to be instanced more than thousands of times at close proximity, " "consider using a [MultiMesh] in a [MultiMeshInstance] instead." msgstr "" +"MeshInstance est un nœud qui prend une ressource [Mesh] et l'ajoute au " +"scénario actuel en créant une instance. C'est la classe la plus souvent " +"utilisée pour obtenir la géométrie 3D pour le rendu et peut être utilisé " +"pour l'instance d'un seul [Mesh] dans de nombreux endroits. Cela permet de " +"réutiliser la géométrie et d'économiser des ressources. Lorsqu'un [Mesh] " +"doit être instancié plusieurs milliers de fois les uns proches des autres, " +"préférez plutôt un [MultiMesh] dans un [MultiMeshInstance]." #: doc/classes/MeshInstance.xml msgid "" @@ -44952,6 +45096,16 @@ msgid "" "If [code]simplify[/code] is [code]true[/code], the geometry can be further " "simplified to reduce the amount of vertices. Disabled by default." msgstr "" +"Cette aide crée un nœud [StaticBody] enfant avec une forme de collision " +"[ConvexPolygonShape] calculée à partir de la géométrie du maillage. Elle est " +"principalement utilisée pour les essais.\n" +"Si [code]clean[/code] est [code]true[/code] (par défaut), les doublons et " +"les sommets intérieurs sont automatiquement supprimés. Vous pouvez le " +"définir à [code]false[/code] pour rendre le processus de création plus " +"rapide.\n" +"Si [code]simplify[/code] est [code]true[/code], la géométrie pourra être " +"simplifiée pour réduire la quantité de sommets, ce qui est désactivé par " +"défaut." #: doc/classes/MeshInstance.xml msgid "" @@ -44990,11 +45144,15 @@ msgid "" "[method Mesh.surface_get_material] to get materials associated with the " "[Mesh] resource." msgstr "" +"Retourne la surcharge [Material] pour une surface de la ressource [Mesh].\n" +"[b]Note :[/b] Cette fonction ne retourne que les matériaux associés à la " +"[i]surchage[/i] de la [MeshInstance]. Préférez [method get_active_material] " +"ou [method Mesh.surface_get_material] pour obtenir des matériaux associés à " +"la ressource [Mesh]." #: doc/classes/MeshInstance.xml -#, fuzzy msgid "Returns the number of surface override materials." -msgstr "Retourne le nombre de surfaces du matériau." +msgstr "Retourne le nombre de surcharges des surfaces du matériau." #: doc/classes/MeshInstance.xml msgid "" @@ -45004,6 +45162,12 @@ msgid "" "In order to be mergeable, properties of the [MeshInstance] must match, and " "each surface must match, in terms of material, attributes and vertex format." msgstr "" +"Retourne [code]true[/code] si cette [MeshInstance] peut être fusionnée avec " +"l'autre instance [code]other_mesh_instance[/code], en utilisant la fonction [" +"method MeshInstance.merge_meshes].\n" +"Pour pouvoir être fusionnées, les propriétés des [MeshInstance] doivent " +"correspondre, et chaque surface doit correspondre, en termes de matériau, " +"d'attributs et de format des sommets." #: doc/classes/MeshInstance.xml msgid "" @@ -45028,6 +45192,26 @@ msgid "" "Also note that any initial data in the destination [MeshInstance] data will " "be discarded." msgstr "" +"Cette fonction peut fusionner les données de plusieurs [MeshInstance] " +"sources en une seule [MeshInstance] finale (le MeshInstance sur laquel la " +"fonction est appelée). Ceci est principalement utile pour améliorer les " +"performances en réduisant le nombre de appels de dessin et de [Node].\n" +"Le fusions ne doivent être faites que sur des maillages simples et ne " +"contenant pas d'animation.\n" +"Les sommets finaux peuvent soit être retournés dans l'espace global, soit " +"dans l'espace local par rapport à la transformation globale de la " +"[MeshInstance] finale (ce nœud doit être à l'intérieur du [SceneTree] pour " +"l'espace local pour fonctionner).\n" +"La fonction effectuera un contrôle final de compatibilité entre les " +"[MeshInstance] par défaut, cela devrait toujours être utilisé à moins que " +"vous n'ayez préalablement vérifié la compatibilité avec [method MeshInstance." +"is_mergeable_with]. Si la vérification est ignorée et que les maillages sont " +"fusionnés, vous pouvez voir des erreurs de rendu.\n" +"[b]Note :[/b] Les exigences de similitude entre les maillages sont assez " +"strictes. Elles peuvent être vérifiés avec [method MeshInstance." +"is_mergeable_with], avant d'appeler [method MeshInstance.merge_meshes]\n" +"Notez également que toutes les données initiales dans la [MeshInstance] " +"finale seront supprimées." #: doc/classes/MeshInstance.xml msgid "" @@ -45035,6 +45219,9 @@ msgid "" "resource. This material is associated with this [MeshInstance] rather than " "with the [Mesh] resource." msgstr "" +"Définit la surcharge [Material] pour la surface spécifiée de la ressource " +"[Mesh]. Ce matériel est associé à cette ressource [MeshInstance] plutôt qu'à " +"la ressource [Mesh]." #: doc/classes/MeshInstance.xml msgid "The [Mesh] resource for the instance." @@ -45127,9 +45314,8 @@ msgid "Returns the item's mesh." msgstr "Retourne le maillage de l'élément." #: doc/classes/MeshLibrary.xml -#, fuzzy msgid "Returns the transform applied to the item's mesh." -msgstr "Retourne la matrice de transformation de la toile de cet objet." +msgstr "" #: doc/classes/MeshLibrary.xml msgid "Returns the item's name." @@ -45172,9 +45358,8 @@ msgid "Sets the item's mesh." msgstr "Définit le maillage de l'élément." #: doc/classes/MeshLibrary.xml -#, fuzzy msgid "Sets the transform to apply to the item's mesh." -msgstr "Retourne la matrice de transformation de la toile de cet objet." +msgstr "" #: doc/classes/MeshLibrary.xml msgid "" @@ -45303,12 +45488,16 @@ msgid "" "The height at which the camera is placed in relation to the ground (i.e. " "[ARVROrigin] node)." msgstr "" +"La hauteur à laquelle la caméra est placée par rapport au sol (c'est-à-dire " +"au nœud [ARVROrigin])." #: modules/mobile_vr/doc_classes/MobileVRInterface.xml msgid "" "The interocular distance, also known as the interpupillary distance. The " "distance between the pupils of the left and right eye." msgstr "" +"La distance interoculaire, aussi appelée la distance interpupillaire. La " +"distance entre la pupille de l'œil gauche et celle du l'œil droit." #: modules/mobile_vr/doc_classes/MobileVRInterface.xml msgid "" @@ -45321,7 +45510,7 @@ msgstr "" #: modules/mobile_vr/doc_classes/MobileVRInterface.xml msgid "The k2 lens factor, see k1." -msgstr "" +msgstr "Le facteur k2 de lentille, voir k1." #: modules/mobile_vr/doc_classes/MobileVRInterface.xml msgid "" @@ -45394,6 +45583,18 @@ msgid "" "(4 bytes as is) and [code]COLOR_FLOAT[/code] / [code]CUSTOM_DATA_FLOAT[/" "code] is stored as 4 floats." msgstr "" +"Définit toutes les données relatives aux instances en une seule fois. Ceci " +"est particulièrement utile lors du chargement des données du disque ou de la " +"préparation des données de GDNative.\n" +"Toutes les données sont empaquetées dans un grand tableau flottant. Un " +"tableau peut ressembler à ceci : la Transform pour l'instance 1, les données " +"de couleur pour l'instance 1, des données personnalisées pour l'instance 1, " +"la Transform pour l'instance 2, les données de couleur pour l'instance 2, " +"etc.\n" +"[Transform] est enregistré avec 12 flottants, [Transform2D] avec 8 " +"flottants, [code]COLOR_8BIT[/code] / [code]CUSTOM_DATA_8BIT[/code] avec 1 " +"flottant (4 octets en général) et [code]COLOR_FLOAT[/code] / " +"[code]CUSTOM_DATA_FLOAT[/code] avec 4 flottants." #: doc/classes/MultiMesh.xml msgid "" @@ -45406,6 +45607,16 @@ msgid "" "When the order of instances is coherent, the simpler [method MultiMesh." "set_as_bulk_array] can still be used with interpolation." msgstr "" +"Une version alternative de [method MultiMesh.set_as_bulk_array] qui peut " +"être utilisée avec [i]l'interpolation physique[/i]. Cette méthode prend deux " +"tableaux, et peut définir les données pour la trame actuelle et précédente " +"en une seule fois. Le rendu interpolera automatiquement les données entre " +"ces deux trames.\n" +"Ceci est utile pour les situations où l'ordre des instances peut changer " +"d'une trame physique à l'autre, comme les systèmes de particules.\n" +"Lorsque l'ordre des instances est cohérent, la méthode [method MultiMesh." +"set_as_bulk_array] plus simple peut encore être utilisée avec " +"l'interpolation." #: doc/classes/MultiMesh.xml msgid "" @@ -45415,6 +45626,11 @@ msgid "" "[code]null[/code] on the [MultiMesh] and [member SpatialMaterial." "vertex_color_use_as_albedo] is [code]true[/code] on the material." msgstr "" +"Définit la couleur d'une instance spécifique en [i]multipliant[/i] les " +"couleurs des sommets existants du maillage.\n" +"Pour que la couleur soit modifiée, assurez-vous que [member color_format] " +"n'est pas [code]null[/code] pour le [MultiMesh] et [member SpatialMaterial." +"vertex_color_use_as_albedo] est [code]true[/code] dans le matériau." #: doc/classes/MultiMesh.xml msgid "" @@ -45422,6 +45638,10 @@ msgid "" "just a container for 4 floating point numbers. The format of the number can " "change depending on the [enum CustomDataFormat] used." msgstr "" +"Définit des données personnalisées pour une instance spécifique. Bien que " +"[Color] soit utilisée, ce n'est qu'un conteneur pour 4 flottants qui peut " +"servir à autre chose. Le format du nombre peut changer en fonction du [enum " +"CustomDataFormat] utilisé." #: doc/classes/MultiMesh.xml msgid "Sets the [Transform] for a specific instance." @@ -45433,11 +45653,11 @@ msgstr "Définit la [Transform2D] pour l'instance spécifiée." #: doc/classes/MultiMesh.xml msgid "Format of colors in color array that gets passed to shader." -msgstr "" +msgstr "Le format des couleurs dans le tableau de couleurs passé au shader." #: doc/classes/MultiMesh.xml msgid "Format of custom data in custom data array that gets passed to shader." -msgstr "" +msgstr "Le format des données personnalisées dans ce tableau passé au shader." #: doc/classes/MultiMesh.xml msgid "" @@ -45445,6 +45665,9 @@ msgid "" "buffers. By default, all instances are drawn but you can limit this with " "[member visible_instance_count]." msgstr "" +"Le nombre de cas qui seront affichés. Cela effacera et re-dimensionnera les " +"mémoires tampons. Par défaut, toutes les instantes sont dessinées mais vous " +"pouvez les limiter avec [member visible_instance_count]." #: doc/classes/MultiMesh.xml msgid "Mesh to be drawn." @@ -45459,6 +45682,14 @@ msgid "" "special cases mentioned above, the quality should be comparable to high " "quality." msgstr "" +"Choisis si vous utilisez une méthode d'interpolation qui favorise la vitesse " +"ou la qualité.\n" +"Lors de l'utilisation de faibles taux de trames physiques (généralement " +"inférieur à 20) ou de taux élevés de rotation d'objets, vous pouvez obtenir " +"de meilleurs résultats à partir du réglage de haute qualité.\n" +"[b]Note :[/b] La qualité rapide ne correspond pas à la qualité basse. Sauf " +"dans les cas particuliers mentionnés ci-dessus, la qualité devrait être " +"comparable à la qualité." #: doc/classes/MultiMesh.xml msgid "Format of transform used to transform mesh, either 2D or 3D." @@ -45471,6 +45702,8 @@ msgid "" "Limits the number of instances drawn, -1 draws all instances. Changing this " "does not change the sizes of the buffers." msgstr "" +"Limite le nombre d'instances affichées, et -1 les dessine toutes. Changer " +"cela ne change pas la taille des mémoires tampons." #: doc/classes/MultiMesh.xml msgid "Use this when using 2D transforms." @@ -45489,12 +45722,17 @@ msgid "" "Compress [Color] data into 8 bits when passing to shader. This uses less " "memory and can be faster, but the [Color] loses precision." msgstr "" +"Compresse les données [Color] en 8 bits quand elles seront passées au " +"shader. Cela utilise moins de mémoire et peut être plus rapide, mais les " +"[Color] perdent en précision." #: doc/classes/MultiMesh.xml msgid "" "The [Color] passed into [method set_instance_color] will use 4 floats. Use " "this for highest precision [Color]." msgstr "" +"La [Color] passée dans [method set_instance_color] utilisera 4 flottants. " +"Utilisez ceci pour la plus haute précision [Color]." #: doc/classes/MultiMesh.xml msgid "Use when you are not using per-instance custom data." @@ -45686,12 +45924,16 @@ msgid "" "Emitted when this MultiplayerAPI's [member network_peer] successfully " "connected to a server. Only emitted on clients." msgstr "" +"Émis lorsque le [member network_peer] de ce MultijoueurAPI est connecté avec " +"succès à un serveur. Seulement émis aux clients." #: doc/classes/MultiplayerAPI.xml msgid "" "Emitted when this MultiplayerAPI's [member network_peer] fails to establish " "a connection to a server. Only emitted on clients." msgstr "" +"Émis lorsque le [member network_peer] de ce MultijoueurAPI ne parvient pas à " +"établir une connexion à un serveur. Seulement émis aux clients." #: doc/classes/MultiplayerAPI.xml msgid "" @@ -45700,6 +45942,11 @@ msgid "" "clients connect to the same server. Upon connecting to a server, a client " "also receives this signal for the server (with ID being 1)." msgstr "" +"Émis lorsque le [member network_peer] de ce MultiplayerAPI se connecte à un " +"nouveau pair. L'identifiant est celui du nouveau pair. Les clients sont " +"informés lorsque d'autres clients se connectent au même serveur. En se " +"connectant à un serveur, un client reçoit également ce signal pour le " +"serveur (avec identifiant étant à 1)." #: doc/classes/MultiplayerAPI.xml msgid "" @@ -45707,6 +45954,9 @@ msgid "" "peer. Clients get notified when other clients disconnect from the same " "server." msgstr "" +"Émis lorsque le [member network_peer] de ce MultiplayerAPI se déconnecte " +"d'un pair. Les clients sont informés lorsque d'autres clients se " +"déconnectent du même serveur." #: doc/classes/MultiplayerAPI.xml msgid "" @@ -45714,12 +45964,18 @@ msgid "" "[code]packet[/code] with custom data (see [method send_bytes]). ID is the " "peer ID of the peer that sent the packet." msgstr "" +"Émis lorsque le [member network_peer] de ce MultijoueurAPI reçoit un " +"[code]packet[/code] avec des données personnalisées (voir [method " +"send_bytes)]. L'identifiant est l'identifiant par les pairs de l'équipe qui " +"a envoyé le paquet." #: doc/classes/MultiplayerAPI.xml msgid "" "Emitted when this MultiplayerAPI's [member network_peer] disconnects from " "server. Only emitted on clients." msgstr "" +"Émis lorsque le [member network_peer] de ce MultijoueurAPI se déconnecte du " +"serveur. Seulement émis sur les clients." #: doc/classes/MultiplayerAPI.xml msgid "" @@ -45760,34 +46016,47 @@ msgid "" "[i]Deprecated.[/i] Use [constant RPC_MODE_PUPPET] instead. Analogous to the " "[code]slave[/code] keyword." msgstr "" +"[i]Obsolète.[/i] Utilisez plutôt [constant RPC_MODE_PUPPET]. Similaire au " +"mot-clé [code]slave[/code]." #: doc/classes/MultiplayerAPI.xml msgid "" "Behave like [constant RPC_MODE_REMOTE] but also make the call or property " "change locally. Analogous to the [code]remotesync[/code] keyword." msgstr "" +"Se comporte comme [constant RPC_MODE_REMOTE] mais fait aussi l'appel ou le " +"changement d'un propriété en local. Similaire au mot-clé " +"[code]remotesync[/code]." #: doc/classes/MultiplayerAPI.xml msgid "" "[i]Deprecated.[/i] Use [constant RPC_MODE_REMOTESYNC] instead. Analogous to " "the [code]sync[/code] keyword." msgstr "" +"[i]Obsolète.[/i] Utilisez plutôt [constant RPC_MODE_REMOTESYNC]. Similaire " +"au mot-clé [code]sync[/code]." #: doc/classes/MultiplayerAPI.xml msgid "" "Behave like [constant RPC_MODE_MASTER] but also make the call or property " "change locally. Analogous to the [code]mastersync[/code] keyword." msgstr "" +"Se comporte comme [constant RPC_MODE_MASTER] mais fait aussi l'appel ou le " +"changement d'une propriété en local. Similaire au mot-clé " +"[code]mastersync[/code]." #: doc/classes/MultiplayerAPI.xml msgid "" "Behave like [constant RPC_MODE_PUPPET] but also make the call or property " "change locally. Analogous to the [code]puppetsync[/code] keyword." msgstr "" +"Se comporte comme [constant RPC_MODE_PUPPET] mais fait aussi l'appel ou le " +"changement d'une propriété en local. Similaire au mot-clé " +"[code]puppetsync[/code]." #: doc/classes/Mutex.xml msgid "A synchronization mutex (mutual exclusion)." -msgstr "" +msgstr "Un mutex de synchronisation (exclusion mutuelle)." #: doc/classes/Mutex.xml msgid "" @@ -45904,6 +46173,9 @@ msgid "" "Returns the owner of the [NavigationMesh] which contains the navigation " "point closest to the point given. This is usually a [NavigationMeshInstance]." msgstr "" +"Retourne le propriétaire du [NavigationMesh] qui contient le point de " +"navigation le plus proche du point donné. C'est généralement une " +"[NavigationMeshInstance]." #: doc/classes/Navigation.xml msgid "" @@ -45914,9 +46186,8 @@ msgid "" msgstr "" #: doc/classes/Navigation.xml -#, fuzzy msgid "Returns the [RID] of the navigation map on the [NavigationServer]." -msgstr "Retourne le [RID] de la énième forme d'une zone." +msgstr "" #: doc/classes/Navigation.xml msgid "" @@ -45928,6 +46199,13 @@ msgid "" "agent properties associated with each [NavigationMesh] (radius, height, " "etc.) are considered in the path calculation, otherwise they are ignored." msgstr "" +"[i]Obsolète.[/i] Le nœud [Navigation] la méthode [method get_simple_path] " +"sont obsolètes se seront retiré dans une prochaine version. Utilisez plutôt [" +"method NavigationServer.map_get_path].\n" +"Retourne le chemin entre deux points donnés. Les points sont des coordonées " +"locales. Si [code]optimize[/code] est [code]true[/code] (par défaut), les " +"propriétés de l'agent associées à chaque [NavigationMesh] (rayon, hauteur, " +"etc.) sont considérés dans le calcul du chemin, sinon ils sont ignorés." #: doc/classes/Navigation.xml msgid "The cell height to use for fields." @@ -45953,12 +46231,16 @@ msgid "" "Defines which direction is up. By default, this is [code](0, 1, 0)[/code], " "which is the world's \"up\" direction." msgstr "" +"Définit la direction. Par défaut, il s'agit de [code](0, 1, 0)[/code], qui " +"est la direction du haut (\"up\")." #: doc/classes/Navigation.xml doc/classes/Navigation2DServer.xml #: doc/classes/NavigationServer.xml msgid "" "Emitted when a navigation map is updated, when a region moves or is modified." msgstr "" +"Émis quand une carte de navigation est mise à jour, ou quand une région se " +"déplace ou est modifiée." #: doc/classes/Navigation2D.xml msgid "2D navigation and pathfinding node." @@ -46007,9 +46289,8 @@ msgid "" msgstr "" #: doc/classes/Navigation2DServer.xml -#, fuzzy msgid "Server interface for low-level 2D navigation access." -msgstr "Interface de serveur pour l'accès audio de bas niveau." +msgstr "" #: doc/classes/Navigation2DServer.xml #, fuzzy @@ -46047,16 +46328,16 @@ msgstr "" "de navigation. Ensemble, ces cartes définissent les aires navigables dans le " "monde 2D. Pour que deux régions soient connectées entre elles, elles doivent " "avoir une bordure en commun. Une bordure (\"edge\") est considérée connectée " -"à une autre si elles ont deux sommets rapprochés de moins de la distance " -"[member Navigation.edge_connection_margin].\n" +"à une autre si elles ont deux sommets rapprochés de moins de la distance [" +"member Navigation.edge_connection_margin].\n" "Pour utiliser le système d'évitement, vous devez utiliser des agents. Vous " "pouvez définir la vitesse cible d'un agent, puis le serveur émettra une " "méthode de rappel avec la vitesse modifiée.\n" "[b]Note :[/b] Le système d'évitement des collisions ignorent les régions. " "Utiliser la vitesse modifiée telle quelle peut déplacer un agent hors de la " -"surface de navigable. C'est une limite du système d'évitement des collision, " -"et certaines situations plus complexes peuvent nécessiter l'utilisation du " -"moteur physique.\n" +"surface de navigable. C'est une limite du système d'évitement des " +"collisions, et certaines situations plus complexes peuvent nécessiter " +"l'utilisation du moteur physique.\n" "Le serveur garde en mémoire tous les appels et les exécutent durant la phase " "de synchronisation. Cela veut dire que vous pouvez demander n'importe quel " "changement sur l'ensemble des cartes, via n'importe quel fil d'exécution, " @@ -46071,11 +46352,12 @@ msgid "" "Returns the navigation map [RID] the requested [code]agent[/code] is " "currently assigned to." msgstr "" +"Retourne le [RID] de la carte de navigation auquel le [code]agent[/code] " +"spécifié est actuellement assigné." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns [code]true[/code] if the map got changed the previous frame." -msgstr "Renvoie [code]true[/code] si le chemin donné est filtré." +msgstr "" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" @@ -46101,11 +46383,13 @@ msgid "" "navigation. The larger this number, the longer the running time of the " "simulation. If the number is too low, the simulation will not be safe." msgstr "" +"Définit le nombre maximal d'autres agents que cet agent prend en compte dans " +"la navigation. Plus ce nombre est grand, plus la durée de la simulation est " +"longue. Si le nombre est trop bas, la simulation ne sera pas fiable." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the maximum speed of the agent. Must be positive." -msgstr "Obtient le nom d'un entrée par son index." +msgstr "" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" @@ -46113,11 +46397,14 @@ msgid "" "the navigation. The larger this number, the longer the running time of the " "simulation. If the number is too low, the simulation will not be safe." msgstr "" +"Définit la distance maximale avec d'autres agents que cet agent prend en " +"compte dans la navigation. Plus ce nombre est grand, plus la durée de la " +"simulation est longue. Si le nombre est trop bas, la simulation ne sera pas " +"fiable." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the position of the agent in world space." -msgstr "Définit la position du nœud spécifié." +msgstr "" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "Sets the radius of the agent." @@ -46135,11 +46422,14 @@ msgid "" "agents, but the less freedom this agent has in choosing its velocities. Must " "be positive." msgstr "" +"La quantité minimale de temps pour laquelle les vitesses de l'agent " +"calculées par la simulation sont fiables pour les autres agents. Plus ce " +"nombre est grand, plus tôt cet agent répondra à la présence d'autres agents, " +"mais moins il aura de liberté pour choisir sa vitesse. Ça doit être positif." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the current velocity of the agent." -msgstr "Définit le trame présentement visible de l'animation." +msgstr "" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "Destroys the given RID." @@ -46151,6 +46441,9 @@ msgid "" "returns both 2D and 3D created navigation maps as there is technically no " "distinction between them." msgstr "" +"Retourne tous les [RID] des cartes de navigation créées sur le " +"NavigationServer. Cela renvoie les cartes de navigation 2D et aussi 3D car " +"il n'y a techniquement aucune distinction entre eux." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "Create a new map." @@ -46184,19 +46477,47 @@ msgid "" "but it can also introduce bugs if used inappropriately without much " "foresight." msgstr "" +"Cette fonction force immédiatement la synchronisation de la navigation " +"spécifiée par le [RID] spécifié par [code]map[/code]. Par défaut, les cartes " +"de navigation ne sont synchronisées qu'à la fin de chaque trame physique. " +"Cette fonction peut être utilisée pour calculer immédiatement tous les " +"maillages de navigation et les connexions entre les régions de la carte de " +"navigation. Cela permet d'interroger un chemin de navigation pour une carte " +"modifiée immédiatement et dans la même trame (plusieurs fois si nécessaire)." +"\n" +"En raison de restrictions techniques, la file de commandes actuelle de " +"NavigationServer sera exécutée aussitôt. Cela signifie que toutes les " +"commandes de mise à jour en attente pour cette trame de physique seront " +"exécutées, même celles destinées à d'autres cartes, régions et agents qui ne " +"font pas partie de la carte spécifiée. Le calcul coûteux des maillages de " +"navigation et des connexions de régions d'une carte ne sera fait que pour la " +"carte spécifiée. D'autres cartes recevront la synchronisation normale à la " +"fin de la trame physique. Si la carte spécifiée reçoit des changements après " +"la mise à jour forcée, elle sera à nouveau mise à jour aussi bien lorsque " +"les autres cartes recevront leur mise à jour.\n" +"Le traitement d'évitement et l'envoi des signaux [code]safe_velocity[/code] " +"ne sont pas affectés par cette fonction et continuent de se produire pour " +"tous les cartes et agents à la fin de la trame physique.\n" +"[b]Note :[/b] Une grande pouvoir implique une grande responsabilité. Cette " +"fonction ne devrait être utilisée que par les utilisateurs qui savent " +"vraiment ce qu'ils font et ont une bonne raison de l'utiliser. Pour " +"effectuer une mise à jour immédiate d'une carte de navigation, il faut " +"verrouiller le NavigationServer et exécuter toute la file de commandes du " +"NavigationServer. Non seulement cela peut affecter sévèrement les " +"performances du jeu, mais il peut également introduire des bugs si ça n'est " +"pas fait avec le plus grand soin." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" "Returns all navigation agents [RID]s that are currently assigned to the " "requested navigation [code]map[/code]." msgstr "" +"Retourne tous [RID] des agents de navigation qui sont actuellement affectés " +"à la navigation [code]map[/code] spécifiée." #: doc/classes/Navigation2DServer.xml -#, fuzzy msgid "Returns the map cell height. [b]Note:[/b] Currently not implemented." msgstr "" -"Retourne l'actuelle ligne du fichier interprété (actuellement non " -"implémenté)." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "Returns the map cell size." @@ -46215,12 +46536,16 @@ msgid "" "Returns the owner region RID for the point returned by [method " "map_get_closest_point]." msgstr "" +"Retourne la région propriétaire du RID pour le point retourné par [method " +"map_get_closest_point]." #: doc/classes/Navigation2DServer.xml msgid "" "Returns the edge connection margin of the map. The edge connection margin is " "a distance used to connect two regions." msgstr "" +"Retourne la marge de raccordement du bord de la carte. La marge de " +"raccordement est une distance utilisée pour relier deux régions." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" @@ -46228,38 +46553,42 @@ msgid "" "[code]navigation_layers[/code] is a bitmask of all region layers that are " "allowed to be in the path." msgstr "" +"Retourne le chemin de navigation pour atteindre la destination de l'origine. " +"[code]navigation_layers[/code] est un bitmask de toutes les calques de la " +"région qui sont autorisées à être dans le chemin." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" "Returns all navigation regions [RID]s that are currently assigned to the " "requested navigation [code]map[/code]." msgstr "" +"Retourne toutes les régions de navigation [RID] qui sont actuellement " +"affectées à la navigation demandée [code]map[/code]." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns [code]true[/code] if the map is active." -msgstr "Retourne [code]true[/code] si l'[AABB] est vide." +msgstr "" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "Sets the map active." msgstr "Définit la carte comme active." #: doc/classes/Navigation2DServer.xml -#, fuzzy msgid "" "Set the map cell height used to weld the navigation mesh polygons. [b]Note:[/" "b] Currently not implemented." -msgstr "Définit le polygone de navigation de la tuile." +msgstr "" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Set the map cell size used to weld the navigation mesh polygons." -msgstr "Définit le polygone de navigation de la tuile." +msgstr "" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" "Set the map edge connection margin used to weld the compatible region edges." msgstr "" +"Définit la marge de connexion de bord de la carte utilisée pour fusionner " +"les bords compatibles de la région." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "Creates a new region." @@ -46271,6 +46600,8 @@ msgid "" "index between 0 and the return value of [method " "region_get_connections_count]." msgstr "" +"Retourne le point de fin d'une porte de connexion. [code]connection[/code] " +"est un indice entre 0 et la valeur de [method region_get_connections_count]." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" @@ -46278,33 +46609,36 @@ msgid "" "an index between 0 and the return value of [method " "region_get_connections_count]." msgstr "" +"Retourne le point de départ d'une porte de connexion. [code]connection[/code]" +" est un indice entre 0 et la valeur de [method region_get_connections_count]." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" "Returns how many connections this [code]region[/code] has with other regions " "in the map." msgstr "" +"Retourne le nombre de connexions ce [code]region[/code] a avec les autres " +"régions de la carte." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns the [code]enter_cost[/code] of this [code]region[/code]." -msgstr "Retourne [code]true[/code] si le [code]signal[/code] donné existe." +msgstr "" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" "Returns the navigation map [RID] the requested [code]region[/code] is " "currently assigned to." msgstr "" +"Retourne le [RID] de la carte de navigation à laquelle la [code]region[/code]" +" spécifiée est actuellement assignée." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns the region's navigation layers." -msgstr "Retourne le maillage de navigation de l'élément." +msgstr "Retourne les calques de navigation de la région." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]." -msgstr "Retourne [code]true[/code] si le [code]signal[/code] donné existe." +msgstr "" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" @@ -46322,41 +46656,49 @@ msgid "" "(which should be avoided in general) the result might not be what is " "expected." msgstr "" +"Retourne [code]true[/code] si la coordonnée [code]point[/code] global " +"appartient actuellement à la [code]region[/code] de la navigation. Dans ce " +"contexte, l'une des faces du polygone de maillages de navigation de la " +"région a une position possible à la distance la plus proche de ce point par " +"rapport à tous les autres maillages de navigation provenant d'autres régions " +"de navigation également enregistrées sur la carte de navigation de la région " +"donnée.\n" +"Si plusieurs maillages de navigation ont des positions à égale distance, la " +"région de navigation dont les polygones sont traités en premier sont " +"retournés. Les polygones sont traités dans l'ordre d'ajout des régions dans " +"le serveur de navigation.\n" +"[b]Note :[/b] Si les maillages de navigation provenant de différentes " +"régions de navigation se chevauchent (qui doivent être évités en général), " +"le résultat peut être inattendu." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]." msgstr "" -"Définit la [code]position[/code] du point avec l'identifiant [code]id[/code] " -"spécifié." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the map for the region." -msgstr "Retourne la hauteur du contenu." +msgstr "Définit la carte de la région." #: doc/classes/Navigation2DServer.xml msgid "" "Set the region's navigation layers. This allows selecting regions from a " "path request (when using [method Navigation2DServer.map_get_path])." msgstr "" +"Définit les calques de navigation de la région. Cela permet de sélectionner " +"les régions à partir d'une requête de chemin (en utilisant [method " +"Navigation2DServer.map_get_path])." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the navigation mesh for the region." -msgstr "Définit le polygone de navigation de la tuile." +msgstr "Définit le polygone de navigation de la région." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the global transformation for the region." -msgstr "Retourne la matrice de transformation globale de cet élément." +msgstr "Retourne la transformation globale de cette région." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the [code]travel_cost[/code] for this [code]region[/code]." msgstr "" -"Définit la [code]position[/code] du point avec l'identifiant [code]id[/code] " -"spécifié." #: doc/classes/NavigationAgent.xml msgid "3D agent used in navigation for collision avoidance." @@ -46378,6 +46720,21 @@ msgid "" "position from this function should be used as the next movement position for " "the agent's parent Node." msgstr "" +"Agent 3D utilisé dans la navigation pour atteindre un emplacement tout en " +"évitant les obstacles statiques et dynamiques. Les obstacles dynamiques sont " +"évités en utilisant la méthode RVO (Reciprocal Velocity Obstacles). L'agent " +"a besoin de données de navigation pour fonctionner correctement. Par défaut " +"ce nœud s'enregistrera à la carte de navigation par défaut du [World]. Si ce " +"nœud est un enfant d'un nœud [Navigation] il s'inscrira à la carte de " +"navigation du nœud de navigation ou la fonction [method set_navigation] peut " +"être utilisée pour définir le nœud de navigation directement. " +"[NavigationAgent] est sûr lors du traitement physique.\n" +"[b]Note :[/b] Après que [method set_target_location] est utilisé, il est " +"nécessaire d'utiliser la fonction [method get_next_location] une fois par " +"trame physique pour mettre à jour la logique de chemin interne du " +"NavigationAgent. La position vectorielle retournée de cette fonction devrait " +"être utilisée comme position de mouvement suivante pour le Node parent de " +"l'agent principal." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46385,6 +46742,9 @@ msgid "" "position. The user must set the target location with [method " "set_target_location] in order for this to be accurate." msgstr "" +"Retourne la distance jusqu'à l'emplacement cible, en utilisant la position " +"globale de l'agent observé. L'utilisateur doit définir l'emplacement de la " +"cible avec [method set_target_location] afin d'être précis." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46392,6 +46752,9 @@ msgid "" "if the navigation path is altered in any way. Because of this, it would be " "best to check this each frame." msgstr "" +"Retourne l'emplacement final accessible dans les coordonnées globales. Cela " +"peut changer si le chemin de navigation est modifié de quelque manière que " +"ce soit. Pour cette raison, il serait préférable de vérifier chaque trame." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46404,6 +46767,15 @@ msgid "" "for the agents movement as this function also updates the internal path " "logic." msgstr "" +"Retourne le chemin actuel de l'agent du début jusqu'à la fin, dans les " +"coordonnées globales. Le chemin ne met à jour que lorsque l'emplacement de " +"la cible est modifié ou que l'agent demande un re-calcul du chemin. Le " +"réseau de chemin n'est pas destiné à être utilisé dans le mouvement de " +"chemin direct car l'agent a sa propre logique de chemin interne qui serait " +"corrompu en changeant le réseau de chemin manuellement. Utilisez la [method " +"get_next_location] voulue une fois chaque trame de physique pour recevoir le " +"point de chemin suivant pour le mouvement des agents car cette fonction met " +"également à jour la logique du chemin interne." #: doc/classes/NavigationAgent.xml msgid "" @@ -46416,6 +46788,8 @@ msgid "" "Returns the [Navigation] node that the agent is using for its navigation " "system." msgstr "" +"Retourne le nœud [Navigation] que l'agent utilise pour son système de " +"navigation." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46427,6 +46801,14 @@ msgid "" "the navigation map for the NavigationAgent and also update the agent on the " "NavigationServer." msgstr "" +"Retourne le [RID] de la carte de navigation pour ce nœud NavigationAgent. " +"Cette fonction retourne toujours la carte définie sur le nœud " +"NavigationAgent et non la carte de l'agent abstrait sur le serveur " +"Navigation. Si la carte de l'agent est changée directement avec l'API de " +"NavigationServer, le nœud NavigationAgent ne sera pas au courant du " +"changement de carte. Utilisez [method set_navigation_map] pour changer la " +"carte de navigation pour le NavigationAgent et mettre à jour l'agent sur le " +"NavigationServer." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46436,25 +46818,28 @@ msgid "" "use of this function once every physics frame is required to update the " "internal path logic of the NavigationAgent." msgstr "" +"Retourne l'emplacement suivant dans les coordonnées globales qui peuvent " +"être déplacées, en s'assurant qu'il n'y a pas d'objets statiques dans le " +"chemin. Si l'agent n'a pas de chemin de navigation, il retourne la position " +"du parent de l'agent. L'utilisation de cette fonction une fois chaque trame " +"physique est nécessaire pour mettre à jour la logique de chemin interne de " +"la NavigationAgent." #: doc/classes/NavigationAgent.xml -#, fuzzy msgid "Returns the [RID] of this agent on the [NavigationServer]." -msgstr "Retourne le [RID] de la énième forme d'une zone." +msgstr "Retourne le [RID] de cet agent dans le [NavigationServer]." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "" "Returns the user-defined target location (set with [method " "set_target_location])." -msgstr "Renvoie le mode de remplacement de l’espace pour la zone." +msgstr "" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the navigation path's final location has been " "reached." -msgstr "Renvoie [code]true[/code] si le chemin donné est filtré." +msgstr "" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46477,18 +46862,25 @@ msgid "" "Sets the [Navigation] node used by the agent. Useful when you don't want to " "make the agent a child of a [Navigation] node." msgstr "" +"Définit le nœud [Navigation] utilisé par l'agent. Utile lorsque vous ne " +"voulez pas faire de l'agent un enfant d'un nœud [Navigation]." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Sets the [RID] of the navigation map this NavigationAgent node should use " "and also updates the [code]agent[/code] on the NavigationServer." msgstr "" +"Définit le [RID] de la carte de navigation que ce nœud NavigationAgent " +"devrait utiliser et met à jour le [code]agent[/code] sur le serveur de " +"navigation." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Sets the user desired final location. This will clear the current navigation " "path." msgstr "" +"Définit l'emplacement final souhaité de l'utilisateur. Cela permettra " +"d'effacer le chemin de navigation actuel." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46496,6 +46888,9 @@ msgid "" "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" +"Envoie la vitesse spécifiée à l'algorithme d'évitement de collision. Celui-" +"ci ajustera la vitesse pour éviter les collisions. Une fois le réglage de la " +"vitesse terminée, il émettra le signal [signal velocity_computed]." #: doc/classes/NavigationAgent.xml msgid "" @@ -46506,6 +46901,14 @@ msgid "" "that the developer baked with appropriate agent radius or height values are " "required to support different-sized agents." msgstr "" +"La hauteur du NavigationAgent est soustraite de la valeur de l'axe Y de " +"toute position de chemin vectoriel pour ce NavigationAgent. Le décalage de " +"hauteur du NavigationAgent ne change pas ou n'influence pas le résultat de " +"la requête du maillage de navigation ou du cheminement. Des cartes de " +"navigation supplémentaires qui utilisent des régions avec des maillages de " +"navigation que le développeur a pré-calculé avec un rayon d'agent approprié " +"ou des valeurs de hauteur sont nécessaires pour supporter des agents de " +"taille différente." #: doc/classes/NavigationAgent.xml msgid "" @@ -46516,22 +46919,29 @@ msgid "" "with many registered agents has a significant performance cost and should " "only be enabled on agents that currently require it." msgstr "" +"Si [code]true[/code] l'agent est enregistré pour un rappel d'évitement RVO " +"sur le [NavigationServer]. Lorsque [method set_velocity] est utilisé et que " +"le traitement est terminé, un Vector3 [code]safe_velocity[/code] est reçu " +"avec une connexion du signal [signal velocity_computed]. Le traitement de " +"l'évitement avec de nombreux agents enregistrés a un coût de performance " +"important et ne devrait être activé que pour les agents qui en ont " +"actuellement besoin." #: doc/classes/NavigationAgent.xml msgid "" "Ignores collisions on the Y axis. Must be [code]true[/code] to move on a " "horizontal plane." msgstr "" +"Ignore les collisions sur l'axe Y. Doit être [code]true[/code] pour se " +"déplacer sur un plan horizontal." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "The maximum number of neighbors for the agent to consider." -msgstr "La valeur de luminance maximale pour l'exposition automatique." +msgstr "" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "The maximum speed that an agent can move." -msgstr "Rotation maximale à travers la charnière." +msgstr "La vitesse maximale à laquelle un agent peut se déplacer." #: doc/classes/NavigationAgent.xml msgid "" @@ -46539,11 +46949,14 @@ msgid "" "belongs to. On path requests the agent will ignore navmeshes without at " "least one matching layer." msgstr "" +"Un masque de bit déterminant toutes les calque de carte de navigation " +"auxquels ce [NavigationAgent] appartient. Lors de requête de chemin, l'agent " +"va ignorer les maillages de navigation qui n'ont pas au moins un calque " +"correspondant." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "The distance to search for other agents." -msgstr "L’instance n’a pas de type." +msgstr "" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46555,6 +46968,14 @@ msgid "" "it will constantly overshoot or undershoot the distance to the next point on " "each physics frame update." msgstr "" +"Le seuil de distance avant qu'un point de chemin soit considéré comme " +"atteint. Cela permettra à un agent de ne pas avoir à atteindre un point de " +"chemin exactement sur le chemin, mais uniquement un zone autour. Si cette " +"valeur est élevée, la NavigationAgent sautera des points sur le chemin qui " +"peut conduire à quitter le maillage de navigation. Si cette valeur est trop " +"faible, le NavigationAgent sera coincé dans une boucle de chemin parce qu'il " +"va constamment mal estimer la distance jusqu'au point suivant à chaque mise " +"à jour de la trame physique." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46562,6 +46983,9 @@ msgid "" "final location. This can happen due to trying to avoid collisions. When the " "maximum distance is exceeded, it recalculates the ideal path." msgstr "" +"La distance maximale de l'agent est permise loin du chemin idéal jusqu'à " +"l'emplacement final. Cela peut arriver en essayant d'éviter les collisions. " +"Lorsque la distance maximale est dépassée, cela recalcule le chemin idéal." #: doc/classes/NavigationAgent.xml msgid "" @@ -46572,6 +46996,13 @@ msgid "" "bake [NavigationMesh] resources with a different [member NavigationMesh." "agent_radius] property and use different navigation maps for each actor size." msgstr "" +"Le rayon d'évitement de l'agent. Il s'agit du « corps » de l'agent " +"d'évitement et non le rayon de la manœuvre d'évitement (qui est contrôlé par " +"[member neighbor_dist)].\n" +"N'affecte pas le cheminement normal. Pour changer les ressources " +"[NavigationMesh] de rayon de pré-calcul de cheminement d'un acteur avec la " +"propriété [member NavigationMesh.agent_radius] différente et utiliser " +"différentes cartes de navigation pour chaque acteur." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46582,6 +47013,12 @@ msgid "" "overshoot or undershoot the distance to the final target point on each " "physics frame update." msgstr "" +"Le seuil de distance avant qu'un point de chemin soit considéré comme " +"atteint. Cela permettra à un agent de ne pas avoir à atteindre un point de " +"chemin exactement sur le chemin, mais uniquement un zone autour. Si cette " +"valeur est trop faible, le NavigationAgent sera coincé dans une boucle de " +"chemin parce qu'il va constamment mal estimer la distance jusqu'au point " +"suivant à chaque mise à jour de la trame physique." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46591,29 +47028,39 @@ msgid "" "other agents, but the less freedom in choosing its velocities. Must be " "positive." msgstr "" +"La quantité minimale de temps pour laquelle les vitesses de cet agent, " +"calculées avec l'algorithme d'évitement de collision, sont sûres pour les " +"autres agents. Plus le nombre est élevé, plus tôt l'agent répondra à " +"d'autres agents, mais moins il aura la liberté de choisir sa vitesse. Ça " +"doit être positif." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "Notifies when the final location is reached." -msgstr "Avertit quand une animation commence à jouer." +msgstr "" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Notifies when the navigation path changes. This can be triggered by the " "navigation system or by the user changing the path." msgstr "" +"Notifie quand le chemin de navigation change. Cela peut être déclenché par " +"le système de navigation ou par l'utilisateur qui change le chemin." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Notifies when the player-defined target, set with [method " "set_target_location], is reached." msgstr "" +"Notifie quand la cible définie par le joueur, définie avec [method " +"set_target_location], est atteinte." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Notifies when the collision avoidance velocity is calculated after a call to " "[method set_velocity]." msgstr "" +"Notifie quand la vitesse d'évitement de collision est calculée après un " +"appel à [method set_velocity]." #: doc/classes/NavigationAgent2D.xml msgid "2D agent used in navigation for collision avoidance." @@ -46635,6 +47082,21 @@ msgid "" "position from this function should be used as the next movement position for " "the agent's parent Node." msgstr "" +"L'agent 2D utilisé dans la navigation pour atteindre un emplacement tout en " +"évitant les obstacles statiques et dynamiques. Les obstacles dynamiques sont " +"évités en utilisant l'évitement de collision RVO (Reciprocal Velocity " +"Obstacles). L'agent a besoin de données de navigation pour fonctionner " +"correctement. Par défaut ce nœud s'enregistrera à la carte de navigation par " +"défaut du [World2D]. Si ce nœud est un enfant d'un nœud [Navigation2D] il " +"s'inscrira à la carte de navigation du nœud de navigation ou la fonction " +"[method set_navigation] peut être utilisé pour définir le nœud de navigation " +"directement. [NavigationAgent2D] est sûr lors des trames physiques.\n" +"[b]Note :[/b] Après que [method set_target_location] est utilisé, il est " +"nécessaire d'utiliser la fonction [method get_next_location] une fois chaque " +"trame physique pour mettre à jour la logique interne de chemin du " +"NavigationAgent. La position vectorielle retournée de cette fonction devrait " +"être utilisée comme position de mouvement suivante pour le Node parent de " +"l'agent principal." #: doc/classes/NavigationAgent2D.xml msgid "" @@ -46647,17 +47109,20 @@ msgid "" "Returns the [Navigation2D] node that the agent is using for its navigation " "system." msgstr "" +"Retourne le nœud [Navigation2D] que l'agent utilise pour son système de " +"navigation." #: doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "Returns the [RID] of this agent on the [Navigation2DServer]." -msgstr "Retourne le [RID] de la énième forme d'une zone." +msgstr "Retourne le [RID] de cet agent dans le [Navigation2DServer]." #: doc/classes/NavigationAgent2D.xml msgid "" "Sets the [Navigation2D] node used by the agent. Useful when you don't want " "to make the agent a child of a [Navigation2D] node." msgstr "" +"Définit le nœud [Navigation2D] utilisé par l'agent. Utile lorsque vous ne " +"voulez pas faire de l'agent un enfant d'un nœud [Navigation2D]." #: doc/classes/NavigationAgent2D.xml msgid "" @@ -46668,6 +47133,13 @@ msgid "" "with many registered agents has a significant performance cost and should " "only be enabled on agents that currently require it." msgstr "" +"Si [code]true[/code] l'agent est enregistré pour un rappel d'évitement RVO " +"sur le [Navigation2DServer]. Lorsque [method set_velocity] est utilisé et " +"que le traitement est terminé, un Vector2 [code]safe_velocity[/code] est " +"reçu avec une connexion au signal [signal velocity_computed]. Le traitement " +"de l'évitement avec de nombreux agents enregistrés a un coût de performance " +"important et ne devrait être activé que pour les agents qui en ont " +"actuellement besoin." #: doc/classes/NavigationAgent2D.xml msgid "" @@ -46675,6 +47147,10 @@ msgid "" "belongs to. On path requests the agent will ignore navmeshes without at " "least one matching layer." msgstr "" +"Un masque de bit déterminant toutes les calque de carte de navigation " +"auxquels ce [NavigationAgent2D] appartient. Lors de requête de chemin, " +"l'agent va ignorer les maillages de navigation qui n'ont pas au moins un " +"calque correspondant." #: doc/classes/NavigationAgent2D.xml msgid "" @@ -46683,6 +47159,10 @@ msgid "" "[member neighbor_dist]).\n" "Does not affect normal pathfinding." msgstr "" +"Le rayon d'évitement de l'agent. Il s'agit du « corps » de l'agent " +"d'évitement et non le rayon de la manœuvre d'évitement (qui est contrôlé par " +"[member neighbor_dist)].\n" +"N'affecte pas le cheminement normal." #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." @@ -46714,11 +47194,10 @@ msgid "" msgstr "" #: doc/classes/NavigationMesh.xml -#, fuzzy msgid "" "Returns whether the specified [code]bit[/code] of the [member " "geometry_collision_mask] is set." -msgstr "Retourne si la [code]class[/code] spécifiée est disponible ou non." +msgstr "" #: doc/classes/NavigationMesh.xml doc/classes/NavigationPolygon.xml msgid "" @@ -46729,9 +47208,8 @@ msgstr "" "créé." #: doc/classes/NavigationMesh.xml -#, fuzzy msgid "Returns the number of polygons in the navigation mesh." -msgstr "Renvoie le nombre de points sur l'axe de mélange." +msgstr "" #: doc/classes/NavigationMesh.xml msgid "" @@ -46742,17 +47220,16 @@ msgstr "" "créé." #: doc/classes/NavigationMesh.xml -#, fuzzy msgid "" "If [code]value[/code] is [code]true[/code], sets the specified [code]bit[/" "code] in the [member geometry_collision_mask].\n" "If [code]value[/code] is [code]false[/code], clears the specified [code]bit[/" "code] in the [member geometry_collision_mask]." msgstr "" -"Si [code]value[/code] est [code]true[/code]], définit le [code]bit[/code] " -"spécifié dans le masque [nom collision_mask].\n" -"Si [code]value[/code] est [code]false[/code], rétablit le [code]bit[/code] " -"spécifié dans le masque [nom collision_mask]." +"Si [code]value[/code] est [code]true[/code], définit le [code]bit[/code] " +"spécifié dans le masque [member geometry_collision_mask].\n" +"Si [code]value[/code] est [code]false[/code], efface le [code]bit[/code] " +"spécifié dans le masque [member geometry_collision_mask]." #: doc/classes/NavigationMesh.xml doc/classes/NavigationPolygon.xml msgid "" @@ -46776,9 +47253,8 @@ msgid "" msgstr "" #: doc/classes/NavigationMesh.xml -#, fuzzy msgid "The maximum slope that is considered walkable, in degrees." -msgstr "Rotation maximale à travers la charnière." +msgstr "" #: doc/classes/NavigationMesh.xml msgid "" @@ -46827,9 +47303,8 @@ msgid "The position offset applied to the [member filter_baking_aabb] [AABB]." msgstr "" #: doc/classes/NavigationMesh.xml -#, fuzzy msgid "If [code]true[/code], marks spans that are ledges as non-walkable." -msgstr "Si [code]true[/code], les titres des colonnes sont visibles." +msgstr "" #: doc/classes/NavigationMesh.xml msgid "" @@ -46838,13 +47313,10 @@ msgid "" msgstr "" #: doc/classes/NavigationMesh.xml -#, fuzzy msgid "" "If [code]true[/code], marks walkable spans as not walkable if the clearance " "above the span is less than [member agent_height]." msgstr "" -"Si [code]true[/code], les particules sera émise une seule fois puis " -"arrêtées. Équivalent à [member Particles.one_shot]." #: doc/classes/NavigationMesh.xml msgid "" @@ -46852,12 +47324,17 @@ msgid "" "Only used when [member geometry_parsed_geometry_type] is [constant " "PARSED_GEOMETRY_STATIC_COLLIDERS] or [constant PARSED_GEOMETRY_BOTH]." msgstr "" +"Les calques de physique pour scanner les collisions statiques.\n" +"Seulement utilisé quand [member geometry_parsed_geometry_type] est [constant " +"PARSED_GEOMETRY_STATIC_COLLIDERS] ou [constant] PARSED_GEOMETRY_BOTH]." #: doc/classes/NavigationMesh.xml msgid "" "Determines which type of nodes will be parsed as geometry. See [enum " "ParsedGeometryType] for possible values." msgstr "" +"Détermine quel type de nœuds seront interprétés comme géométrie. Voir [enum " +"ParsedGeometryType] pour les valeurs possibles." #: doc/classes/NavigationMesh.xml msgid "" @@ -46872,12 +47349,18 @@ msgid "" "SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN] or [constant " "SOURCE_GEOMETRY_GROUPS_EXPLICIT]." msgstr "" +"Le nom du groupe pour scanner la géométrie.\n" +"Seulement utilisé lorsque [member geometry_source_geometry_mode] est " +"[constant SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN] ou [constant] " +"SOURCE_GEOMETRY_GROUPS_EXPLICIT]." #: doc/classes/NavigationMesh.xml msgid "" "The maximum number of vertices allowed for polygons generated during the " "contour to polygon conversion process." msgstr "" +"Le nombre maximal de sommets permis pour les polygones générés pendant le " +"contour du processus de conversion en polygones." #: doc/classes/NavigationMesh.xml msgid "" @@ -46886,6 +47369,10 @@ msgid "" "[b]Note:[/b] This value will be squared to calculate the number of cells. " "For example, a value of 20 will set the number of cells to 400." msgstr "" +"Toutes les régions ayant une taille inférieure à celle-ci seront fusionnées " +"avec des régions plus grandes si possible.\n" +"[b]Note :[/b] Cette valeur sera carrée pour calculer le nombre de cellules. " +"Par exemple, une valeur de 20 définira le nombre de cellules à 400." #: doc/classes/NavigationMesh.xml msgid "" @@ -46894,12 +47381,18 @@ msgid "" "cells allowed to form isolated island areas. For example, a value of 8 will " "set the number of cells to 64." msgstr "" +"La taille minimale d'une région pour qu'elle soit créée.\n" +"[b]Note :[/b] Cette valeur sera fixée pour calculer le nombre minimum de " +"cellules autorisées à former des zones insulaires isolées. Par exemple, une " +"valeur de 8 définira le nombre de cellules à 64." #: doc/classes/NavigationMesh.xml msgid "" "Partitioning algorithm for creating the navigation mesh polys. See [enum " "SamplePartitionType] for possible values." msgstr "" +"Algorithme de partitionnement pour la création des polygones de maillage de " +"navigation. Voir [enum SamplePartitionType] pour les valeurs possibles." #: doc/classes/NavigationMesh.xml msgid "" @@ -46911,12 +47404,16 @@ msgstr "" msgid "" "Monotone partitioning. Use this if you want fast navigation mesh generation." msgstr "" +"Partage monotone. Utilisez ceci si vous voulez une génération de maillages " +"de navigation rapide." #: doc/classes/NavigationMesh.xml msgid "" "Layer partitioning. Good choice to use for tiled navigation mesh with medium " "and small sized tiles." msgstr "" +"Le partitionnement du calque. Un bon choix à utiliser pour la maillage de " +"navigation en carreaux de taille moyenne et petite." #: doc/classes/NavigationMesh.xml msgid "Represents the size of the [enum SamplePartitionType] enum." @@ -46935,6 +47432,9 @@ msgid "" "Parses [StaticBody] colliders as geometry. The collider should be in any of " "the layers specified by [member geometry_collision_mask]." msgstr "" +"Interprète l'élément de collision [StaticBody] comme géométrie. Cet élément " +"doit être dans l'un des calques spécifiés par [member " +"geometry_collision_mask]." #: doc/classes/NavigationMesh.xml msgid "" @@ -46952,18 +47452,24 @@ msgstr "Représente la taille de l’enum [enum ParsedGeometryType]." msgid "" "Scans the child nodes of [NavigationMeshInstance] recursively for geometry." msgstr "" +"Scanne les nœuds d'enfants de [NavigationMeshInstance] récursivement pour la " +"géométrie." #: doc/classes/NavigationMesh.xml msgid "" "Scans nodes in a group and their child nodes recursively for geometry. The " "group is specified by [member geometry_source_group_name]." msgstr "" +"Scanne les nœuds dans un groupe et leurs nœuds enfants récursivement pour la " +"géométrie. Le groupe est spécifié par [member geometry_source_group_name]." #: doc/classes/NavigationMesh.xml msgid "" "Uses nodes in a group for geometry. The group is specified by [member " "geometry_source_group_name]." msgstr "" +"Utilise des nœuds dans un groupe de géométrie. Le groupe est spécifié par " +"[member geometry_source_group_name]." #: doc/classes/NavigationMesh.xml msgid "Represents the size of the [enum SourceGeometryMode] enum." @@ -46972,6 +47478,7 @@ msgstr "Représente la taille de l'énumération [enum SourceGeometryMode]." #: doc/classes/NavigationMeshGenerator.xml msgid "Helper class for creating and clearing navigation meshes." msgstr "" +"Classe d'aide pour la création et la suppression des maillages de navigation." #: doc/classes/NavigationMeshGenerator.xml msgid "" @@ -47014,6 +47521,52 @@ msgid "" "inside, the baking will generate navigation mesh areas that are inside the " "obstructing source geometry mesh." msgstr "" +"Cette classe est responsable de la création et du la suppression des " +"maillages de navigation 3D utilisés comme [NavigationMesh] ressources à " +"l'intérieur des [NavigationMeshInstance]. Le [NavigationMeshGenerator] est " +"très limité voire n'a aucune utilisation pour 2D car le processus de " +"navigation de pré-calcule de maillages s'attend à des types de nœuds 3D et " +"la géométrie source en 3D.\n" +"L'ensemble du pré-calcule de maillages de navigation est préférable dans un " +"autre fil d'exécution puisque les étapes de voxelisation, de collision et " +"d'optimisation de maillages impliquées sont des opérations, sont très " +"couteuses en temps processeur.\n" +"Le pré-calcule de maillage de navigation se produit en plusieurs étapes et " +"le résultat dépend de la géométrie source 3D et des propriétés de la " +"ressource [NavigationMesh]. Dans la première étape, à partir d'un nœud " +"racine et selon les propriétés [NavigationMesh], tous les nœuds de géométrie " +"de source 3D valides sont collectés à partir du [SceneTree]. Deuxièmement, " +"tous les nœuds collectés sont interprétés pour obtenir les données de " +"géométrie 3D pertinentes et un maillage 3D combiné est construit. En raison " +"des différents types d'objets à interpréter, des [MeshInstance] normaux aux " +"[CSGShape] ou divers [CollisionObject], certaines opérations de collecte de " +"données de géométrie peuvent déclencher des synchronisations du " +"[VisualServer] et du [PhysicsServer]. La synchronisation du serveur peut " +"avoir un effet négatif sur le temps de pré-calcule car elle implique souvent " +"le verrouillage de [Mutex] dans le fil d'exécution. De nombreux objets à " +"interpréter et de nombreuses synchronisations des serveurs peuvent augmenter " +"considérablement le temps de pré-calcule. D'un autre côté, seulement " +"quelques objets, mais très grands et complexes, prendront du temps de " +"préparation des serveurs ce qui peuvent bloquer le rendu suivant. De règle " +"générale, la quantité totale d'objets à interpréter, leur taille et leur " +"complexité individuelles devraient être équilibrées pour éviter les " +"problèmes de fluidité ou des temps de pré-calcule très longs. Le maillage " +"combiné est ensuite transmis à l'Object Recast Navigation pour tester la " +"géométrie source pour le terrain à parcourir adapté aux propriétés des " +"agents [NavigationMesh] en créant un monde de voxel autour de la zone de " +"maillage.\n" +"Le maillage de navigation finalisé est ensuite retourné et enregistré à " +"l'intérieur du [NavigationMesh] pour être utilisé comme ressource à " +"l'intérieur des nœuds [NavigationMeshInstance].\n" +"[b]Note :[/b] L'utilisation de maillages ne définissen pas seulement les " +"surfaces à parcourir mais peut aussi empêcher le pré-calcul de fonctionner. " +"La navigation n'a pas de concept de ce qu'est une géométrie \"à " +"l'intérieur\" quand on traite de la géométrie de source de maillage et c'est " +"intentionnel. Selon les paramètres de pré-calcule actuels, dès que le " +"maillage obstructif est assez grande pour s'adapter à une zone de maillage " +"de navigation à l'intérieur, le pré-calcule générera des zones de maillage " +"de navigation qui sont à l'intérieur du maillage de géométrie de source " +"obstructif." #: doc/classes/NavigationMeshGenerator.xml msgid "" @@ -47024,13 +47577,18 @@ msgid "" "NavigationMesh.geometry_source_geometry_mode] properties on the " "[NavigationMesh] resource." msgstr "" +"Pré-calcule les données de navigation du [code]nav_mesh[/code] donné en " +"interprétant les nœuds enfants dans le [code]root_node[/code] spécifié ou un " +"groupe spécifique de nœuds pour la géométrie de source potentielle. Le " +"comportement d'interprétation peut être contrôlé avec les propriétés [member " +"NavigationMesh.geometry_parsed_geometry_type] et [member NavigationMesh." +"geometry_source_geometry_mode] de la ressource [NavigationMesh]." #: doc/classes/NavigationMeshGenerator.xml -#, fuzzy msgid "" "Removes all polygons and vertices from the provided [code]nav_mesh[/code] " "resource." -msgstr "Supprime l’animation avec la touche [code]name[/code]." +msgstr "" #: doc/classes/NavigationMeshInstance.xml msgid "An instance of a [NavigationMesh]." @@ -47050,11 +47608,29 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." msgstr "" +"Une instance de [NavigationMesh]. Il signale au nœud [Navigation] ce qui " +"peut être navigué et ce qui ne peut pas, basé sur la ressource " +"[NavigationMesh].\n" +"Par défaut ce nœud s'enregistrera à la carte de navigation du [World] par " +"défaut. Si ce nœud est un enfant d'un nœud [Navigation], il s'inscrira à la " +"carte de navigation du nœud de navigation.\n" +"Deux régions peuvent être reliées l'une à l'autre si elles partagent un même " +"bord. Vous pouvez définir la distance minimale entre deux sommets " +"nécessaires pour connecter deux bords en utilisant [method NavigationServer." +"map_set_edge_connection_margin]\n" +"[b]Note :[/b] Le chevauchement de deux régions n'est pas suffisant pour " +"relier deux régions. Ils doivent partager un même bord.\n" +"Le coût d'entrée dans cette région d'une autre région peut être contrôlé " +"avec la valeur [member enter_cost].\n" +"[b]Note :[/b] Cette valeur n'est pas ajoutée au coût du chemin lorsque la " +"position de départ est déjà dans cette région.\n" +"Le coût des distances de voyage dans cette région peut être contrôlé avec le " +"multiplicateur [member travel_cost]." #: doc/classes/NavigationMeshInstance.xml msgid "" @@ -47068,6 +47644,18 @@ msgid "" "operating systems that cannot use threads (such as HTML5 with threads " "disabled)." msgstr "" +"Pré-calcule le [NavigationMesh]. Si [code]on_thread[/code] est défini à " +"[code]true[/code] (par défaut), le pré-calcul est fait sur un fil " +"d'exécution séparé. Le pré-calcul sur un fil d'exécution séparé est utile " +"parce que la navigation est une opération relativement coûteuse. Lorsqu'il " +"est terminé, il définit automatiquement ce nouveau [NavigationMesh]. " +"Veuillez noter que le pré-calcul sur le fil d'exécution séparé peut être " +"très lent si la géométrie est composée de plein de maillages puisque l'accès " +"asynchrone à chaque maillage nécessite une lourde synchronisation. De plus, " +"veuillez noter que le pré-calculs sur un fil d'exécution séparé est " +"automatiquement désactivée sur les systèmes d'exploitation qui ne peuvent " +"pas utiliser des fils d'exécution (comme HTML5 si cette fonction est " +"désactivée)." #: doc/classes/NavigationMeshInstance.xml msgid "" @@ -47076,6 +47664,10 @@ msgid "" "identify the [NavigationMeshInstance] closest to a point on the merged " "navigation map." msgstr "" +"Retourne le [RID] de cette région sur [NavigationServer]. Combiné avec [" +"method NavigationServer.map_get_closest_point_owner], peut être utilisé pour " +"identifier le [NavigationMeshInstance] le plus proche d'un point d'une carte " +"de navigation fusionnée." #: doc/classes/NavigationMeshInstance.xml msgid "Determines if the [NavigationMeshInstance] is enabled or disabled." @@ -47108,11 +47700,13 @@ msgid "" "are multiplied with [code]travel_cost[/code] for determining the shortest " "path." msgstr "" +"Lorsque le cheminement se déplace à l'intérieur de cette région, les " +"distances parcourues sont multipliées par [code]travel_cost[/code] pour " +"déterminer le chemin le plus court." #: doc/classes/NavigationMeshInstance.xml -#, fuzzy msgid "Notifies when the navigation mesh bake operation is completed." -msgstr "Avertit quand une animation commence à jouer." +msgstr "" #: doc/classes/NavigationMeshInstance.xml msgid "Notifies when the [NavigationMesh] has changed." @@ -47131,12 +47725,22 @@ msgid "" "[b]Note:[/b] Obstacles are intended as a last resort option for constantly " "moving objects that cannot be (re)baked to a navigation mesh efficiently." msgstr "" +"Obstacle 3D utilisé dans la navigation pour éviter les collisions. " +"L'obstacle a besoin de données de navigation pour fonctionner correctement. " +"Cela peut être fait avec l'obstacle comme enfant d'un nœud [Navigation], ou " +"en utilisant [method set_navigation]. [NavigationObstacle] est sûr lors des " +"trames physiques.\n" +"[b]Note :[/b] Les obstacles sont conçus comme dernière option pour les " +"objets constamment mobiles qui ne peuvent pas être pré-calculés efficacement " +"dans un maillage de navigation." #: doc/classes/NavigationObstacle.xml msgid "" "Returns the [Navigation] node that the obstacle is using for its navigation " "system." msgstr "" +"Retourne le nœud [Navigation] que l'obstacle utilise pour son système de " +"navigation." #: doc/classes/NavigationObstacle.xml msgid "Returns the [RID] of this obstacle on the [NavigationServer]." @@ -47147,18 +47751,24 @@ msgid "" "Sets the [Navigation] node used by the obstacle. Useful when you don't want " "to make the obstacle a child of a [Navigation] node." msgstr "" +"Définit le nœud [Navigation] utilisé par l'obstacle. Utile lorsque vous ne " +"voulez pas faire l'obstacle un enfant d'un nœud [Navigation]." #: doc/classes/NavigationObstacle.xml doc/classes/NavigationObstacle2D.xml msgid "" "Enables radius estimation algorithm which uses parent's collision shapes to " "determine the obstacle radius." msgstr "" +"Active l'algorithme d'estimation de rayon qui utilise les formes de " +"collision des parents pour déterminer le rayon des obstacles." #: doc/classes/NavigationObstacle.xml doc/classes/NavigationObstacle2D.xml msgid "" "The radius of the agent. Used only if [member estimate_radius] is set to " "[code]false[/code]." msgstr "" +"Le rayon de l'agent. Utilisé uniquement si [member estimate_radius] est " +"[code]false[/code]." #: doc/classes/NavigationObstacle2D.xml msgid "2D obstacle used in navigation for collision avoidance." @@ -47173,12 +47783,22 @@ msgid "" "[b]Note:[/b] Obstacles are intended as a last resort option for constantly " "moving objects that cannot be (re)baked to a navigation mesh efficiently." msgstr "" +"L'obstacle 2D utilisé dans la navigation pour éviter les collisions. " +"L'obstacle a besoin de données de navigation pour fonctionner correctement. " +"Cela peut être fait avec l'obstacle comme enfant d'un nœud [Navigation2D], " +"ou en utilisant [method set_navigation]. [NavigationObstacle2D] est sûr lors " +"des trames physiques.\n" +"[b]Note :[/b] Les obstacles sont conçus comme dernière option pour les " +"objets constamment mobiles qui ne peuvent pas être pré-calculés efficacement " +"dans un maillage de navigation." #: doc/classes/NavigationObstacle2D.xml msgid "" "Returns the [Navigation2D] node that the obstacle is using for its " "navigation system." msgstr "" +"Retourne le nœud [Navigation2D] que l'obstacle utilise pour son système de " +"navigation." #: doc/classes/NavigationObstacle2D.xml msgid "Returns the [RID] of this obstacle on the [Navigation2DServer]." @@ -47189,12 +47809,16 @@ msgid "" "Sets the [Navigation2D] node used by the obstacle. Useful when you don't " "want to make the obstacle a child of a [Navigation2D] node." msgstr "" +"Définit le nœud [Navigation2D] utilisé par l'obstacle. Utile lorsque vous ne " +"voulez pas faire l'obstacle un enfant d'un nœud [Navigation2D]." #: doc/classes/NavigationPolygon.xml msgid "" "A node that has methods to draw outlines or use indices of vertices to " "create navigation polygons." msgstr "" +"Un nœud qui a des méthodes pour dessiner des contours ou utiliser des " +"indices de sommets pour créer des polygones de navigation." #: doc/classes/NavigationPolygon.xml msgid "" @@ -47220,6 +47844,27 @@ msgid "" "$NavigationPolygonInstance.navpoly = polygon\n" "[/codeblock]" msgstr "" +"Il y a deux façons de créer des polygones. Soit en utilisant la méthode [" +"method add_outline], soit en utilisant la méthode [method add_polygon].\n" +"Avec [method add_outline] :\n" +"[codeblock]\n" +"var polygon = NavigationPolygon.new()\n" +"var outline = PoolVector2Array([Vector2(0, 0), Vector2(0, 50), Vector2(50, " +"50), Vector2(50, 0)])\n" +"polygon.add_outline(outline)\n" +"polygon.make_polygons_from_outlines()\n" +"$NavigationPolygonInstance.navpoly = polygon\n" +"[/codeblock]\n" +"Avec [method add_polygon] et les indices du tableau des sommets :\n" +"[codeblock]\n" +"var polygon = NavigationPolygon.new()\n" +"var vertices = PoolVector2Array([Vector2(0, 0), Vector2(0, 50), Vector2(50, " +"50), Vector2(50, 0)])\n" +"polygon.set_vertices(vertices)\n" +"var indices = PoolIntArray([0, 1, 2, 3])\n" +"polygon.add_polygon(indices)\n" +"$NavigationPolygonInstance.navpoly = polygon\n" +"[/codeblock]" #: doc/classes/NavigationPolygon.xml msgid "" @@ -47228,6 +47873,10 @@ msgid "" "make_polygons_from_outlines] in order for this array to be converted to " "polygons that the engine will use." msgstr "" +"Ajoute un [PoolVector2Array] qui contient les sommets d'un contour au " +"tableau interne qui contient tous les contours. Vous devez appeler [method " +"make_polygons_from_outlines] afin que ce tableau soit converti en polygones " +"que le moteur pourra utiliser." #: doc/classes/NavigationPolygon.xml msgid "" @@ -47236,18 +47885,26 @@ msgid "" "to call [method make_polygons_from_outlines] in order for this array to be " "converted to polygons that the engine will use." msgstr "" +"Ajoute un [PoolVector2Array] qui contient les sommets d'un contour au " +"tableau interne qui contient tous les contours à une position fixe. Vous " +"devez appeler [method make_polygons_from_outlines] afin que ce tableau soit " +"converti en polygones que le pourra utiliser." #: doc/classes/NavigationPolygon.xml msgid "" "Clears the array of the outlines, but it doesn't clear the vertices and the " "polygons that were created by them." msgstr "" +"Efface le tableau des contours, mais ça n'efface pas les sommets et les " +"polygones qui ont été créés par eux." #: doc/classes/NavigationPolygon.xml msgid "" "Clears the array of polygons, but it doesn't clear the array of outlines and " "vertices." msgstr "" +"Efface le tableau des polygones, mais ça n'effacera pas le tableau des " +"contours et des sommets." #: doc/classes/NavigationPolygon.xml msgid "" @@ -47256,17 +47913,25 @@ msgid "" "NavigationServer.region_set_navmesh] API directly (as 2D uses the 3D server " "behind the scene)." msgstr "" +"Retourne le [NavigationMesh] résultant de ce polygone de navigation. Ce " +"navmesh peut être utilisé pour mettre à jour le navmesh d'une région avec " +"l'API [method NavigationServer.region_set_navmesh] directement (comme la 2D " +"utilise le serveur 3D en interne)." #: doc/classes/NavigationPolygon.xml msgid "" "Returns a [PoolVector2Array] containing the vertices of an outline that was " "created in the editor or by script." msgstr "" +"Retourne un [PoolVector2Array] contenant les sommets d'un contour qui a été " +"créé dans l'éditeur ou par un script." #: doc/classes/NavigationPolygon.xml msgid "" "Returns the number of outlines that were created in the editor or by script." msgstr "" +"Retourne le nombre de contours qui ont été créés dans l'éditeur ou par un " +"script." #: doc/classes/NavigationPolygon.xml msgid "Returns the count of all polygons." @@ -47277,27 +47942,33 @@ msgid "" "Returns a [PoolVector2Array] containing all the vertices being used to " "create the polygons." msgstr "" +"Retourne un [PoolVector2Array] contenant tous les sommets utilisés pour " +"créer les polygones." #: doc/classes/NavigationPolygon.xml msgid "Creates polygons from the outlines added in the editor or by script." msgstr "" +"Crée des polygones des contours ajoutés dans l'éditeur ou par un script." #: doc/classes/NavigationPolygon.xml msgid "" "Removes an outline created in the editor or by script. You have to call " "[method make_polygons_from_outlines] for the polygons to update." msgstr "" +"Enlève un aperçu créé dans l'éditeur ou par un script. Vous devez appeler [" +"method make_polygons_from_outlines] pour mettre à jour les polygones." #: doc/classes/NavigationPolygon.xml msgid "" "Changes an outline created in the editor or by script. You have to call " "[method make_polygons_from_outlines] for the polygons to update." msgstr "" +"Change un aperçu créé dans l'éditeur ou par un script. Vous devez appeler [" +"method make_polygons_from_outlines] pour mettre à jour les polygones." #: doc/classes/NavigationPolygonInstance.xml -#, fuzzy msgid "A region of the 2D navigation map." -msgstr "Prépare le maillage de navigation." +msgstr "" #: doc/classes/NavigationPolygonInstance.xml msgid "" @@ -47313,11 +47984,29 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." msgstr "" +"Une région de la carte de navigation. Il indique au [Navigation2DServer] ce " +"qui peut être navigué et ce qui ne peut pas l'être, en fonction de sa " +"ressource [NavigationPolygon].\n" +"Par défaut ce nœud s'enregistrera à la carte de navigation du [World2D] par " +"défaut. Si ce nœud est un enfant d'un nœud [Navigation2D], il s'inscrirea à " +"la carte de navigation du nœud de navigation.\n" +"Deux régions peuvent être reliées l'une à l'autre si elles partagent un bord " +"similaire. Vous pouvez définir la distance minimale entre deux sommets " +"nécessaires pour connecter deux bords en utilisant [method Navigation2DServer" +".map_set_edge_connection_margin]\n" +"[b]Note :[/b] Embiquer deux régions ne suffit pas pour relier ces deux " +"régions. Elles doivent partager un bord similaire.\n" +"Le coût de cheminement de cette région vers une autre peut être contrôlé " +"avec la valeur [member enter_cost].\n" +"[b]Note :[/b] Cette valeur n'est pas ajoutée au coût du chemin lorsque la " +"position de départ est déjà dans cette région.\n" +"Le coût de parcours des distances de cheminement à l'intérieur de cette " +"région peut être contrôlé avec le multiplicateur [member travel_cost]." #: doc/classes/NavigationPolygonInstance.xml msgid "" @@ -47326,11 +48015,14 @@ msgid "" "identify the [NavigationPolygonInstance] closest to a point on the merged " "navigation map." msgstr "" +"Retourne le [RID] de cette région sur le [Navigation2DServer]. Combiné avec [" +"method Navigation2DServer.map_get_closest_point_propriétaire] peut permettre " +"d'identifier le [NavigationPolygonInstance] le plus proche d'un point sur la " +"carte de navigation fusionnée." #: doc/classes/NavigationPolygonInstance.xml -#, fuzzy msgid "Determines if the [NavigationPolygonInstance] is enabled or disabled." -msgstr "Détermine si le [NavigationMeshInstance] est actif ou non." +msgstr "Détermine si la [NavigationPolygonInstance] est active ou non." #: doc/classes/NavigationPolygonInstance.xml msgid "" @@ -47341,14 +48033,12 @@ msgid "" msgstr "" #: doc/classes/NavigationPolygonInstance.xml -#, fuzzy msgid "The [NavigationPolygon] resource to use." -msgstr "La ressource [NavigationMesh] à utiliser." +msgstr "La ressource [NavigationPolygon] à utiliser." #: doc/classes/NavigationServer.xml -#, fuzzy msgid "Server interface for low-level 3D navigation access." -msgstr "Interface de serveur pour l'accès audio de bas niveau." +msgstr "" #: doc/classes/NavigationServer.xml #, fuzzy @@ -47398,15 +48088,13 @@ msgstr "" "sans soucis." #: doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns the map cell height." -msgstr "Retourne la taille du tableau." +msgstr "" #: doc/classes/NavigationServer.xml -#, fuzzy msgid "" "Returns the normal for the point returned by [method map_get_closest_point]." -msgstr "Renvoie l'inverse de la racine carrée du paramètre." +msgstr "" #: doc/classes/NavigationServer.xml msgid "" @@ -47420,15 +48108,16 @@ msgid "" "Returns the edge connection margin of the map. This distance is the minimum " "vertex distance needed to connect two edges from different regions." msgstr "" +"Retourne la marge de raccordement du bord de la carte. Cette distance est la " +"distance minimale nécessaire pour relier deux bords de différentes régions." #: doc/classes/NavigationServer.xml msgid "Returns the map's up direction." msgstr "Retourne la direction haut de la carte." #: doc/classes/NavigationServer.xml -#, fuzzy msgid "Set the map cell height used to weld the navigation mesh polygons." -msgstr "Définit le polygone de navigation de la tuile." +msgstr "" #: doc/classes/NavigationServer.xml msgid "Sets the map up direction." @@ -47441,6 +48130,10 @@ msgid "" "called in the main thread.\n" "[b]Note:[/b] This function is not thread safe." msgstr "" +"Traite les agents d'évitement de collision.\n" +"Le résultat de ce processus est nécessaire par le serveur de physique, de " +"sorte que cela doit être appelé dans le fil d'exécution principal.\n" +"[b]Note :[/b] Cette fonction n'est pas sûre entre plusieurs fils d'exécution." #: doc/classes/NavigationServer.xml msgid "Bakes the navigation mesh." @@ -47451,11 +48144,62 @@ msgid "" "Set the region's navigation layers. This allows selecting regions from a " "path request (when using [method NavigationServer.map_get_path])." msgstr "" +"Définir les calques de navigation de la région. Cela permet de sélectionner " +"les régions à partir d'une requête de chemin (en utilisant [method " +"NavigationServer.map_get_path])." #: doc/classes/NavigationServer.xml msgid "Control activation of this server." msgstr "Contrôle l'activation de ce serveur." +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" +"Retourne l'état actuel de la connexion. Voir [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -47476,6 +48220,18 @@ msgid "" "the server port in UDP. You can use the [UPNP] class to try to forward the " "server port automatically when starting the server." msgstr "" +"Une implémentation de PacketPeer qui devrait être passée au [member " +"SceneTree.network_peer] après avoir été initialisé en tant que client ou " +"serveur. Les événements peuvent ensuite être gérés en se connectant aux " +"signaux de [SceneTree].\n" +"L'intêret de ENet est de fournir un calque de communication à travers le " +"réseau relativement léger, simple et robuste par dessus UDP (User Datagram " +"Protocol).\n" +"[b]Note :[/b] ENet utilise seulement UDP, et non TCP. Lors du branchement du " +"port serveur pour rendre votre serveur accessible sur internet, vous n'avez " +"besoin que d'envoyer le port serveur en UDP. Vous pouvez utiliser la classe " +"[UPNP] pour essayer d'envoyer automatiquement le port serveur dès le " +"démarrage du serveur." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47484,6 +48240,10 @@ msgid "" "disconnecting them. If this is a client it simply closes the connection to " "the server." msgstr "" +"Ferme la connexion. Ignoré si aucune connexion n'est actuellement établie. " +"Si c'est un serveur, il essaie de notifier tous les clients avant de les " +"déconnecter de force. Si c'est un client, il ferme simplement la connexion " +"au serveur." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47506,6 +48266,25 @@ msgid "" "code] is specified, the client will also listen to the given port; this is " "useful for some NAT traversal techniques." msgstr "" +"Créer un client qui se connecte au serveur à [code]address[/code] donnée via " +"le [code]port[/code]. L'adresse donnée doit être soit un nom de domaine " +"entièrement qualifié (ex.: [code]\"www.example.com\"[/code]) ou une adresse " +"IP en format IPv4 ou IPv6 (par exemple [code]\"192.168.1.1\"[/code]). Le " +"[code]port[/code] est le port que le serveur écoute. Les paramètres " +"[code]in_bandwidth[/code] et [code]out_bandwidth[/code] peuvent être " +"utilisés pour limiter la bande passante entrante et sortante, en octets par " +"seconde. Le défaut de 0 signifie que la bande passante ne sera pas limitée. " +"Notez que ENet ignorera stratégiquement des paquets d'une connexion entre " +"pairs pour s'assurer que la bande passante par les pairs n'est pas dépassée. " +"Les paramètres de bande passante déterminent également la taille de la " +"fenêtre d'une connexion qui limite la quantité de paquets fiables qui " +"peuvent être envoyés à tout moment donné. Retourne [constant OK] si un " +"client a été créé, [constant ERR_ALREADY_IN_USE] si ce " +"NetworkedMultiplayerENet a déjà une connexion ouverte (dans quel cas vous " +"devez appeler [method close_connection] d'abord) ou [constant " +"ERR_CANT_CREATE] si le client ne peut pas être créé. Si " +"[code]client_port[/code] est spécifié, le client écoutera également le port " +"donné ; ceci est utile pour certaines techniques NAT transversale." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47524,12 +48303,29 @@ msgid "" "case you need to call [method close_connection] first) or [constant " "ERR_CANT_CREATE] if the server could not be created." msgstr "" +"Créer un serveur qui écoute les connexions via [code]port[/code]. Le port " +"doit être un port disponible et inutilisé entre 0 et 65535. Notez que les " +"ports inférieurs à 1024 sont réservés et peuvent nécessiter des " +"autorisations élevées en fonction de la plateforme. Pour modifier " +"l'interface que le serveur écoute, utilisez [method set_bind_ip]. L'IP par " +"défaut est le joker [code]\"*\"[/code], qui écoute toutes les interfaces " +"disponibles. [code]max_clients[/code] est le nombre maximum de clients " +"autorisés en même temps, tout nombre jusqu'à 4095 peut être utilisé, même si " +"le nombre possible de clients simultanés peut être beaucoup plus faible et " +"dépend de l'application. Pour plus de détails sur les paramètres de bande " +"passante, voir [method create_client]. Retourne [constant OK] si un serveur " +"a été créé, [constant ERR_ALREADY_IN_USE] si ce NetworkedMultiplayerENet a " +"déjà une connexion ouverte (dans quel cas vous devez appeler [method " +"close_connection] d'abord) ou [constant ERR_CANT_CREATE] si le serveur ne " +"peut pas être créé." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "Disconnect the given peer. If \"now\" is set to [code]true[/code], the " "connection will be closed immediately without flushing queued messages." msgstr "" +"Déconnecte le pair donné. Si \"maintenant\" est [code]true[/code], la " +"connexion sera fermée immédiatement sans envoyer les messages en attente." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47544,6 +48340,8 @@ msgid "" "Returns the channel of the next packet that will be retrieved via [method " "PacketPeer.get_packet]." msgstr "" +"Retourne le canal du prochain paquet qui sera récupéré via [method PacketPeer" +".get_packet]." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml #: modules/websocket/doc_classes/WebSocketServer.xml @@ -47562,6 +48360,10 @@ msgid "" "needs to be in IPv4 or IPv6 address format, for example: " "[code]\"192.168.1.1\"[/code]." msgstr "" +"L'adresse IP utilisée lors de la création d'un serveur. Ceci est défini le " +"joker [code]\"*\"[/code] par défaut, qui se connecte à toutes les interfaces " +"disponibles. L'adresse donnée doit être au format IPv4 ou IPv6, par " +"exemple : [code]\"192.168.1.1\"[/code]." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47569,6 +48371,9 @@ msgid "" "code]. For servers, you must also setup the [CryptoKey] via [method " "set_dtls_key]." msgstr "" +"Configure le [X509Certificate] à utiliser lorsque [member use_dtls] est " +"[code]true[/code]. Pour les serveurs, vous devez également configurer le " +"[CryptoKey] via [method set_dtls_key]." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47576,6 +48381,9 @@ msgid "" "code]. Remember to also call [method set_dtls_certificate] to setup your " "[X509Certificate]." msgstr "" +"Configure la [CryptoKey] à utiliser lorsque [member use_dtls] est " +"[code]true[/code]. N'oubliez pas d'appeler [method set_dtls_certificate] " +"pour configurer votre [X509Certificate]." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47590,6 +48398,17 @@ msgid "" "other hand, defines a fixed timeout for which any packet must be " "acknowledged or the peer will be dropped." msgstr "" +"Définit les paramètres de limite de temps pour un pair. Les paramètres de " +"limite de temps contrôlent comment et quand un pair estimera que le traffic " +"n'est pas assez fiable. Les valeurs de limite de temps sont exprimées en " +"millisecondes.\n" +"La [code]timeout_limit[/code] est un facteur qui, multiplié par une valeur " +"basée sur le temps d'envoi moyen, déterminera la limite de temps pour un " +"paquet fiable. Lorsque cette limite est atteinte, la limite de temps sera " +"doublée, et le pair sera déconnecté si cette limite atteint " +"[code]timeout_min[/code]. Le paramètre [code]timeout_max[/code], d'autre " +"part, définit une limite de temps fixe pour lequel tout paquet doit estimé " +"comme fiable, ou alors le pair sera supprimé." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47598,6 +48417,11 @@ msgid "" "NetworkedMultiplayerPeer.TRANSFER_MODE_UNRELIABLE_ORDERED]). This is the " "only way to use ordering with the RPC system." msgstr "" +"Force le tri des paquets lors de l'utilisation de [constant " +"NetworkedMultiplayerPeer.TRANSFER_MODE_UNRELIABLE] (ce qui se comporte de la " +"même manière [constant NetworkedMultiplayerPeer." +"TRANSFER_MODE_UNRELIABLE_ORDERED]). C'est le seul moyen d'utiliser le tri " +"avec un système RPC." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47608,6 +48432,12 @@ msgid "" "status of a packet in one channel won't stall the delivery of other packets " "in another channel." msgstr "" +"Le nombre de canaux à utiliser par ENet. Les canaux sont utilisés pour " +"séparer différents types de données. En mode fiable ou ordonné, par exemple, " +"l'ordre d'envoi des paquets est assuré sur une base par canal. Ceci est fait " +"pour lutter contre la latence et réduit les restrictions d'ordre sur les " +"paquets. L'état d'envoi d'un paquet d'un canal a été décalé dans l'envoi " +"d'autres paquets dans un autre canal." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47624,6 +48454,21 @@ msgid "" "COMPRESS_NONE]. Nonetheless, mixing engine versions between clients and " "server is not recommended and not officially supported." msgstr "" +"La méthode de compression utilisée pour les paquets réseau. Ceux-ci ont " +"différents compromis de vitesse de compression par rapport à la bande " +"passante, vous pouvez avoir besoin quelle méthode fonctionne le mieux pour " +"votre cas d'utilisation si vous utilisez la compression pour tout.\n" +"[b]Note :[/b] La conception réseau de la plupart des jeux nécessite l'envoi " +"de nombreux petits paquets fréquemment (moins de 4 KB chacun). Dans le " +"doute, il est recommandé de garder l'algorithme de compression par défaut " +"car il fonctionne le mieux avec ces petits paquets.\n" +"[b]Note :[/b] [member compression_mode] doit être défini à la même valeur " +"sur le serveur et sur tous ses clients. Les clients ne se connecteront pas " +"si le [member compression_mode] d'un client diffère de celui du serveur. " +"Avant Godot 3.4, la valeur par défaut de [member compression_mode] était " +"[constant COMPRESS_NONE]. Néanmoins, il n'est pas recommandé, ni " +"officiellement supporté, d'utiliser différentes versions du moteur entre les " +"clients et le serveur." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47632,9 +48477,12 @@ msgid "" "When set to an empty string, the [code]address[/code] parameter passed to " "[method create_client] is used instead." msgstr "" +"Le nom d'hôte utilisé pour la vérification DTLS, à comparer à la valeur « CN " +"» du certificat fourni par le serveur.\n" +"Si la chaîne est vide, le paramètre [code]address[/code] passé à [method " +"create_client] est utilisé à la place." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml -#, fuzzy msgid "" "Enable or disable certificate verification when [member use_dtls] is " "[code]true[/code]." @@ -47649,6 +48497,11 @@ msgid "" "is [code]false[/code], clients won't be automatically notified of other " "peers and won't be able to send them packets through the server." msgstr "" +"Activer ou désactiver la fonction serveur qui notifie les clients de la " +"connexion/déconnection des autres pairs enregistrés, et relaye les messages " +"entre eux. Lorsque cette option est [code]false[/code], les clients ont " +"obtenu la notification automatique d'autres pairs et ont obtenu la " +"possibilité de les envoyer par le serveur." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47660,6 +48513,14 @@ msgid "" "that channel for sending data. See [member channel_count] for more " "information about ENet channels." msgstr "" +"Définit le canal par défaut à utiliser pour transférer les données. Par " +"défaut, cette valeur est [code]-1[/code] ce qui signifie que ENet " +"n'utilisera que 2 canaux : un pour les paquets fiables, et un pour les " +"paquets non fiables. Le canal [code]0[/code] est réservé et ne peut pas être " +"utilisé. Définit cette propriété à n'importe quelle valeur entre [code]0[/" +"code] et [member channel_count] (exclus) forcera ENet à utiliser ce canal " +"pour envoyer les données. Voir [member channel_count] pour plus " +"d'informations sur les canaux ENet." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47673,6 +48534,16 @@ msgid "" "dtls_verify] option, and configure the certificate accordingly via [method " "set_dtls_certificate]." msgstr "" +"Quand activé, le client ou le serveur créé par ce pair utilisera " +"[PacketPeerDTLS] au lieu des sockets UDP bruts pour communiquer avec le pair " +"distant. Cela permettra de chiffrer la communication avec DTLS avec une " +"utilisation plus importante des ressources mais aussi peut-être de la taille " +"des paquets.\n" +"[b]Note :[/b] Lors de la création d'un serveur DTLS, assurez-vous de " +"configurer à la fois la clé et le certificat avec [method set_dtls_key] et " +"[method set_dtls_certificate]. Pour les clients DTLS, regardez l'option " +"[member dtls_verify] et configurez le certificat en conséquence avec [method " +"set_dtls_certificate]." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47680,12 +48551,17 @@ msgid "" "requiring the fewest CPU resources. This option may also be used to make " "network debugging using tools like Wireshark easier." msgstr "" +"Aucune compression. Cela utilise le plus de bande passante, mais moins de " +"ressource du CPU. Cette option peut également être utilisée pour faciliter " +"le débogage du réseau en utilisant des outils comme Wireshark." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "ENet's built-in range encoding. Works well on small packets, but is not the " "most efficient algorithm on packets larger than 4 KB." msgstr "" +"L'encodage intégré d'ENet. Fonctionne bien sur les petits paquets, mais " +"n'est pas l'algorithme le plus efficace pour les paquets de plus de 4 KB." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47693,6 +48569,9 @@ msgid "" "resources compared to [constant COMPRESS_ZLIB], at the expense of using more " "bandwidth." msgstr "" +"L'algorithme de compression [url=http://fastlz.org/]FastLZ[/url]. Cette " +"option utilise moins de ressources CPU par rapport à [constant " +"COMPRESS_ZLIB] mais utilise plus de bande passante." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47702,6 +48581,11 @@ msgid "" "packets smaller than 4 KB. Therefore, it's recommended to use other " "compression algorithms in most cases." msgstr "" +"L'algorithme de compression [url=https://www.zlib.net/]Zlib[/url]. Cette " +"option utilise moins de bande passante par rapport à [constant " +"COMPRESS_FASTLZ] mais utilise plus le CPU. Notez que cet algorithme n'est " +"pas très efficace pour les paquets de moins de 4 KB. Il est donc souvent " +"recommandé d'utiliser d'autres algorithmes de compression." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "[url=https://facebook.github.io/zstd/]Zstandard[/url] compression." @@ -47721,6 +48605,11 @@ msgid "" "detail and isn't meant to be used by non-Godot servers. It may change " "without notice." msgstr "" +"Gère la connexion aux pairs du réseau. Attribue des identifiants uniques à " +"chaque client connecté au serveur. Voir aussi [MultiplayerAPI].\n" +"[b]Note :[/b] Le protocole de l'API multijoueur de haut niveau dépend de son " +"implémentation et n'est pas destiné à être utilisé par des serveurs en " +"dehors de Godot. Ce protocole peut changer dans une future version." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "High-level multiplayer" @@ -47728,7 +48617,7 @@ msgstr "API multijoueur de haut niveau" #: doc/classes/NetworkedMultiplayerPeer.xml msgid "WebRTC Signaling Demo" -msgstr "" +msgstr "Démo des signaux WebRTC" #: doc/classes/NetworkedMultiplayerPeer.xml msgid "" @@ -47760,6 +48649,13 @@ msgid "" "peer ID to send to all peers except that one. By default, the target peer is " "[constant TARGET_PEER_BROADCAST]." msgstr "" +"Définit le pair auquel les paquets seront envoyés.\n" +"L'identifiant [code]id[/code] peut être : [constant TARGET_PEER_BROADCAST] " +"pour envoyer à tous les pairs connectés, [constant TARGET_PEER_SERVER] pour " +"envoyer au pair agissant en tant que serveur, un identifiant de pairs valide " +"pour envoyer à ce pair spécifique, ou un identifiant négatif pour envoyer à " +"tous les pairs sauf celui-ci. Par défaut, le pair cible est [constant " +"TARGET_PEER_BROADCAST]." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "" @@ -47774,6 +48670,8 @@ msgid "" "The manner in which to send packets to the [code]target_peer[/code]. See " "[enum TransferMode]." msgstr "" +"La manière d'envoyer des paquets au [code]target_peer[/code]. Voir [enum " +"TransferMode]." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "Emitted when a connection attempt fails." @@ -47802,6 +48700,11 @@ msgid "" "TRANSFER_MODE_UNRELIABLE_ORDERED]. Use for non-critical data, and always " "consider whether the order matters." msgstr "" +"Les paquets ne sont pas reconnus, aucune tentative de ré-envoi n'est faite " +"pour les paquets perdus. Les paquets peuvent arriver dans n'importe quelle " +"commande. Peut être plus rapide que [constant " +"TRANSFER_MODE_UNRELIABLE_ORDERED]. À utiliser pour des données non " +"critiques, et toujours à considérer si l'ordre compte." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "" @@ -47811,6 +48714,12 @@ msgid "" "would be outdated if received late due to resend attempt(s) anyway, for " "example movement and positional data." msgstr "" +"Les paquets ne sont pas reconnus, aucune tentative de ré-envoi n'est faite " +"pour les paquets perdus. Les paquets sont reçus dans l'ordre où ils ont été " +"envoyés. Peut être plus rapide que [constant TRANSFER_MODE_RELIABLE]. À " +"utiliser pour les données non critiques ou qui seraient périmées si elles " +"étaient reçues tardivement à cause du ré-envoi, par exemple pour les données " +"de mouvement et de positionnement." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "" @@ -47821,6 +48730,14 @@ msgid "" "order, for example an ability being triggered or a chat message. Consider " "carefully if the information really is critical, and use sparingly." msgstr "" +"Les paquets doivent être reçus et les tentatives de ré-envoi doivent être " +"faites jusqu'à ce que les paquets soient reconnus. Les paquets doivent être " +"reçus dans l'ordre où ils ont été envoyés. C'est le mode de transfert le " +"plus fiable, mais potentiellement le plus lent en cause de la surcharge. À " +"utiliser pour les données critiques qui doivent être transmises et arriver " +"en ordre, par exemple un élément activé ou un message de discussion. À " +"considérez soigneusement si l'information est vraiment critique, et à " +"utiliser avec parcimonie." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "The ongoing connection disconnected." @@ -47862,30 +48779,40 @@ msgid "" "Returns the size of the margin identified by the given [enum Margin] " "constant." msgstr "" +"Retourne la taille de la marge identifiée par la constante [enum Margin] " +"donnée." #: doc/classes/NinePatchRect.xml msgid "" "Sets the size of the margin identified by the given [enum Margin] constant " "to [code]value[/code] in pixels." msgstr "" +"Définit la taille de la marge identifiée par la constante [enum Margin] " +"donnée à [code]value[/code] en pixels." #: doc/classes/NinePatchRect.xml msgid "" "The stretch mode to use for horizontal stretching/tiling. See [enum " "NinePatchRect.AxisStretchMode] for possible values." msgstr "" +"Le mode d'étirement à utiliser pour l'étirement horizontal. Voir [enum " +"NinePatchRect.AxisStretchMode] pour les valeurs possibles." #: doc/classes/NinePatchRect.xml msgid "" "The stretch mode to use for vertical stretching/tiling. See [enum " "NinePatchRect.AxisStretchMode] for possible values." msgstr "" +"Le mode d'étirement à utiliser pour l'étirement vertical. Voir [enum " +"NinePatchRect.AxisStretchMode] pour les valeurs possibles." #: doc/classes/NinePatchRect.xml msgid "" "If [code]true[/code], draw the panel's center. Else, only draw the 9-slice's " "borders." msgstr "" +"Si [code]true[/code], dessine le centre du panneau. Sinon, ne dessine que " +"les bordures des 9 parties." #: doc/classes/NinePatchRect.xml msgid "" @@ -47893,6 +48820,10 @@ msgid "" "bottom corners and side will have a height of 16 pixels. You can set all 4 " "margin values individually to create panels with non-uniform borders." msgstr "" +"La hauteur de la ligne du bas des 9 parties. Une marge de 16 signifie que " +"les angles du bas des 9 parties et les côtés auront une hauteur de 16 " +"pixels. Vous pouvez définir les 4 valeurs de marge individuellement pour " +"créer des panneaux avec des bordures non uniformes." #: doc/classes/NinePatchRect.xml msgid "" @@ -47900,6 +48831,10 @@ msgid "" "left corners and side will have a width of 16 pixels. You can set all 4 " "margin values individually to create panels with non-uniform borders." msgstr "" +"La largeur de la colonne gauche des 9 parties. Une marge de 16 signifie que " +"les angles de gauche des 9 parties et les côtés auront une largeur de 16 " +"pixels. Vous pouvez définir les 4 valeurs de marge individuellement pour " +"créer des panneaux avec des bordures non uniformes." #: doc/classes/NinePatchRect.xml msgid "" @@ -47907,6 +48842,10 @@ msgid "" "right corners and side will have a width of 16 pixels. You can set all 4 " "margin values individually to create panels with non-uniform borders." msgstr "" +"La largeur de la colonne droite de 9 parties. Une marge de 16 signifie que " +"les angles de droite des 9 parties et le côté auront une largeur de 16 " +"pixels. Vous pouvez définir les 4 valeurs de marge individuellement pour " +"créer des panneaux avec des bordures non uniformes." #: doc/classes/NinePatchRect.xml msgid "" @@ -47914,6 +48853,10 @@ msgid "" "corners and side will have a height of 16 pixels. You can set all 4 margin " "values individually to create panels with non-uniform borders." msgstr "" +"La hauteur de la ligne du haut de 9 parties. Une marge de 16 signifie que " +"les angles du haut des 9 parties et le côté auront une hauteur de 16 pixels. " +"Vous pouvez définir les 4 valeurs de marge individuellement pour créer des " +"panneaux avec des bordures non uniformes." #: doc/classes/NinePatchRect.xml msgid "" @@ -47922,6 +48865,10 @@ msgid "" "other properties are relative to this one. If the rect is empty, " "NinePatchRect will use the whole texture." msgstr "" +"La région rectangulaire de la texture à utiliser. Si vous travaillez avec un " +"atlas, utilisez cette propriété pour définir la zone à utiliser. Toutes les " +"autres propriétés sont par rapport à celle-ci. Si le rectangle est vide, le " +"NinePatchRect utilisera la texture dans son entièreté." #: doc/classes/NinePatchRect.xml msgid "The node's texture resource." @@ -47936,6 +48883,8 @@ msgid "" "Stretches the center texture across the NinePatchRect. This may cause the " "texture to be distorted." msgstr "" +"Étire la texture du centre sur tout le NinePatchRect. Cela peut entraîner " +"une distorsion de cette texture." #: doc/classes/NinePatchRect.xml msgid "" @@ -47945,6 +48894,11 @@ msgid "" "[b]Note:[/b] Only supported when using the GLES3 renderer. When using the " "GLES2 renderer, this will behave like [constant AXIS_STRETCH_MODE_STRETCH]." msgstr "" +"Répète la texture centrale sur tout le NinePatchRect. Cela ne provoque " +"aucune distorsion visible. La texture doit être transparente pour que cela " +"fonctionne sans afficher d'artefacts entre les bords.\n" +"[b]Note :[/b] Seulement pris en charge avec GLES3. Avec GLES2, cela se " +"comportera comme [constant AXIS_STRETCH_MODE_STRETCH]." #: doc/classes/NinePatchRect.xml msgid "" @@ -47956,6 +48910,13 @@ msgid "" "[b]Note:[/b] Only supported when using the GLES3 renderer. When using the " "GLES2 renderer, this will behave like [constant AXIS_STRETCH_MODE_STRETCH]." msgstr "" +"Répète la texture centrale sur tout le NinePatchRect, mais étirera également " +"la texture pour s'assurer que chaque tuile est visible entièrement. Cela " +"peut causer une distorsion de la texture, mais moins que [constant " +"AXIS_STRETCH_MODE_STRETCH]. La texture doit être transparente pour que cela " +"fonctionne sans afficher d'artefacts entre les bords.\n" +"[b]Note :[/b] Seulement pris en charge avec GLES3. Avec GLES2, cela se " +"comportera comme [constant AXIS_STRETCH_MODE_STRETCH]." #: doc/classes/Node.xml msgid "Base class for all [i]scene[/i] objects." @@ -48021,6 +48982,69 @@ msgid "" "(make sure node names are the same on all peers). Also, take a look at the " "high-level networking tutorial and corresponding demos." msgstr "" +"Les nœuds sont les blocs de construction de Godot. Ils peuvent être assignés " +"comme enfant d'un autre nœud, ce qui entraîne définit l'arborescence. Un " +"nœud donné peut contenir n'importe quel nombre de nœuds enfants mais tous " +"ces enfants doivent avoir des noms différents.\n" +"Une arborescence de nœuds est appelé une [i]scène[/i]. Les scènes peuvent " +"être sauvegardées sur le disque et ensuite instanciées dans d'autres scènes. " +"Cela permet une très grande flexibilité dans l'architecture et le modèle de " +"données des projets Godot.\n" +"[b]Arbre de scène :[/b] Le [SceneTree] contient l'arborescence des nœuds. " +"Lorsqu'un nœud est ajouté à l'arborescence de scène, il reçoit la " +"notification [constant NOTIFICATION_ENTER_TREE] et sa méthode [method " +"enter_tree] est appelée. Les nœuds d'enfants sont toujours ajoutés [i]après[/" +"i] leur nœud parent, c'est-à-dire la méthode [method enter_tree] d'un nœud " +"parent sera appelée avant celle de son enfant.\n" +"Une fois que tous les nœuds ont été ajoutés dans l'arborescence de la scène, " +"ils reçoivent la notification [constante NOTIFICATION_READY] et leurs " +"méthodes respectives [method _ready] sont appelées. Pour les groupes de " +"nœuds, la méthode [method _ready] est appelée avec un ordre inversé, en " +"commençant par les enfants et en allant jusqu'aux nœuds parent.\n" +"Cela signifie qu'en ajoutant un nœud à l'arborescence de la scène, l'ordre " +"suivant sera utilisé pour les appels des méthodes: [method enter_tree] du " +"parent, [method enter_tree] des enfants, [method _ready] des enfants et " +"enfin [method _ready] du parent (recursivement pour l'arborescence complète " +"de la scène).\n" +"[b]Processus :[/b] Les nœuds peuvent surcharger l'état du processus, de " +"sorte qu'ils reçoivent un appel à chaque trame demandant un traitement (de " +"faire quelque chose). Le traitement normal (la méthode [method _process], " +"activée avec [method set_process]) se produit aussi vite que possible et " +"dépend du nombre de trames par seconde, de sorte que le temps de traitement " +"[i]delta[/i] (en secondes) est passé en argument. Le traitement physique (la " +"méthode [method physical_process], activée avec [method " +"set_physics_process]) est appelée un nombre fixe de fois par seconde (60 " +"fois par défaut) et est utile pour le code lié au moteur physique.\n" +"Les nœuds peuvent également traiter les événements d'entrée. À l'heure " +"actuelle, la fonction [method _input] sera appelée pour chaque entrée que le " +"programme reçoit. Dans de nombreux cas, cela peut faire trop d'informations " +"(sauf pour des projets simples), et la fonction [method unhandled_input] " +"peut être préférée ; elle est appelée lorsque l'événement d'entrée n'a été " +"traité par aucun élément (généralement, des nœuds d'interface [Control]), " +"pour s'assurer que le nœud ne reçoit que les événements qui lui sont " +"destinés.\n" +"Pour garder la trace de l'arborescence de la scène (surtout lorsque vous " +"instanciez des scènes dans d'autres scènes), un \"propriétaire\" peut être " +"défini pour le nœud avec la propriété [member owner]. Cela garde une trace " +"de quel élément a instancié quel autre élément. Cela est surtout utile " +"lorsque vous écrivez des éditeurs et des outils.\n" +"Enfin, quand un nœud est libéré avec [method Object.free] ou [method " +"queue_free], il va également libérer tous ses enfants.\n" +"[b]Les groupes : [/b] Les nœuds peuvent être ajoutés à autant de groupes que " +"vous voulez, vous pouvez créer des groupes comme « ennemis » ou « " +"récupérables » par exemple, selon votre jeu. Voir [method add_to_group], " +"[method is_in_group] et [method remove_from_group]. Vous pouvez ensuite " +"récupérer tous les nœuds d'un groupe, lister les groupes et même appeler des " +"méthodes sur les groupes via des méthodes de [SceneTree].\n" +"[b]Faire communiquer les nœud via le réseau :[/b] Après s'être connecté à un " +"serveur (ou en faire un, voir [NetworkedMultiplayerENet]), il est possible " +"d'utiliser le système RPC intégré (\"Remote Procedure Call\") pour " +"communiquer sur le réseau. En appelant [method rpc] avec un nom de méthode, " +"il sera appelé localement et pour tous les pairs connectés (un pair = un " +"client et le serveur qui accepte les connexions). Pour identifier quel nœud " +"reçoit l'appel RPC, Godot utilisera son [NodePath] (s'assurant que les noms " +"de nœuds sont les mêmes sur tous les pairs). Consultez également le tutoriel " +"pour les réseaux à haut niveau et les démos correspondantes." #: doc/classes/Node.xml msgid "Nodes and Scenes" @@ -48039,6 +49063,12 @@ msgid "" "Corresponds to the [constant NOTIFICATION_ENTER_TREE] notification in " "[method Object._notification]." msgstr "" +"Appelé lorsque le nœud entre dans la [SceneTree] (par exemple en étant " +"instancié, au changement de scène, ou après avoir appelé [method add_child] " +"dans un script). Si le nœud a des enfants, sa méthode [méthod enter_tree] " +"sera appelée d'abord, puis ensuite celle de ses enfants.\n" +"Correspond à la notification [constant NOTIFICATION_ENTER_TREE] dans [method " +"Object._notification]." #: doc/classes/Node.xml msgid "" @@ -48051,6 +49081,15 @@ msgid "" "the node has already left the active tree, connect to the [signal " "tree_exited]." msgstr "" +"Appelé lorsque le nœud va quitter la [SceneTree] (par exemple sur la " +"suppression, au changement de scène, ou après avoir appelé [method " +"remove_child] dans un script). Si le nœud a des enfants, sa méthode [method " +"exit_tree] sera appelée en dernier, quand tous ses enfants auront quitté " +"l'arborescence.\n" +"Correspond à la notification [constant NOTIFICATION_EXIT_TREE] dans [method " +"Object._notification] et signal [signal tree_exiting]. Pour être notifié " +"lorsque le nœud a déjà quitté l'arborescence active, connectez-vous à " +"[signal tree_exited]." #: doc/classes/Node.xml msgid "" @@ -48060,6 +49099,12 @@ msgid "" "Call [method update_configuration_warning] when the warning needs to be " "updated for this node." msgstr "" +"La chaîne retournée de cette méthode est affichée comme un avertissement " +"dans la barre d'outil Scène si le script qui la modifie est un script " +"[code]tool[/code].\n" +"Retourner une chaîne vide ne produit aucun avertissement.\n" +"Appelez [method update_configuration_warning] lorsque l'avertissement doit " +"être mis à jour pour ce nœud." #: doc/classes/Node.xml msgid "" @@ -48158,6 +49203,21 @@ msgid "" "call with [method request_ready], which may be called anywhere before adding " "the node again." msgstr "" +"Appelé lorsque le nœud est « prêt », c'est-à-dire lorsque le nœud et ses " +"enfants sont entrés dans l'arborescence de la scène. Si le nœud a des " +"enfants, leur méthode [method _ready] sera appelée en premier, et le nœud " +"parent recevra la notification après.\n" +"Correspond à la notification [constant NOTIFICATION_READY] dans [method " +"Object._notification]. Voir aussi le mot-clé [code]onready[/code] pour les " +"variables.\n" +"Habituellement utilisé pour l'initialisation. Pour encore avant cela, " +"[method Object._init] peut être utilisé. Voir aussi [méthod enter_tree].\n" +"[b]Note :[/b] [method _ready] ne peut être appelée qu'une seule fois pour " +"chaque nœud. Après avoir retiré un nœud de l'arborescence de scène et " +"l'ajouter à nouveau, [code]_ready[/code] ne sera pas appelé une deuxième " +"fois. Cela peut être changé en demandant un autre appel avec [method " +"request_ready], qui peut être appelé n'importe où avant d'ajouter le nœud à " +"nouveau." #: doc/classes/Node.xml msgid "" @@ -48247,6 +49307,30 @@ msgid "" "will not be visible in the scene tree, though it will be visible in the " "2D/3D view." msgstr "" +"Ajoute un nœud enfant. Les nœuds peuvent avoir autant d'enfants que voulu, " +"mais chaque enfant doit avoir un nom unique. Les nœuds d'enfants sont " +"automatiquement supprimés lorsque le nœud parent est supprimé, de sorte " +"qu'une scène entière peut être supprimée en supprimant juste son nœud le " +"plus haut.\n" +"Si [code]legible_unique_name[/code] est [code]true[/code], le nœud d'enfant " +"aura un nom clairement lisible basé sur le nom du nœud étant analysé au lieu " +"de son type.\n" +"[b]Note :[/b] Si le nœud enfant a déjà un parent, la fonction échouera. " +"Utilisez [method remove_child] d'abord pour retirer le nœud de son parent " +"actuel. Par exemple :\n" +"[codeblock]\n" +"if child_node.get_parent():\n" +" child_node.get_parent().remove_child(child_node)\n" +"add_child(child_node)\n" +"[/codeblock]\n" +"[b]Note :[/b] Si vous voulez qu'un enfant soit persiste dans un " +"[PackedScene], vous devez définir [member owner] après avoir appelé [method " +"add_child]. Ceci est généralement pertinent pour [url=$DOCS_URL/tutorials/" +"plugins/running_code_in_the_editor.html]scripts d'outil[/url] et " +"[url=$DOCS_URL/tutorials/plugins/editor/index.html]greffons d'éditeur[/url]. " +"Si [method add_child] est appelé sans définir [member owner], le nouveau " +"[Node] ajouté ne sera pas visible dans l'arborescence de la scène, bien " +"qu'il sera visible dans la vue 2D/3D." #: doc/classes/Node.xml msgid "" @@ -48256,6 +49340,10 @@ msgid "" "will have a human-readable name based on the name of the node being " "instanced instead of its type." msgstr "" +"Ajoute [code]child_nœud[/code] en tant qu'enfant. L'enfant est placé sous le " +"[code]nœud[/code] donné dans la liste des enfants.\n" +"Si [code]legible_unique_name[/code] est [code]true[/code], le nœud d'enfant " +"aura un nom lisible humainement basé sur le nom du nœud plutôt que son type." #: doc/classes/Node.xml msgid "" @@ -48278,6 +49366,10 @@ msgid "" "scene tree is not paused, and [code]false[/code] if the node is not in the " "tree." msgstr "" +"Retourne [code]true[/code] si le nœud peut traiter pendant que " +"l'arborescence de scène est interrompue (voir [member pause_mode)]. Retourne " +"toujours [code]true[/code] si l'arborescence de scène n'est pas interrompue, " +"et [code]false[/code] si le nœud n'est pas dans l'arborescence." #: doc/classes/Node.xml msgid "" @@ -48287,6 +49379,10 @@ msgid "" "get_tree().create_tween().bind_node(self)\n" "[/codeblock]" msgstr "" +"Crée un nouveau [SceneTreeTween] et le lie à ce nœud. Cela équivaut à :\n" +"[codeblock]\n" +"get_tree().create_tween().bind_node(self)\n" +"[/codeblock]" #: doc/classes/Node.xml msgid "" @@ -48297,6 +49393,13 @@ msgid "" "constructor arguments (i.e. needs to supply arguments to [method Object." "_init] method). In that case, the node will be duplicated without a script." msgstr "" +"Duplique le nœud, retournant un nouveau nœud.\n" +"Vous pouvez affiner le comportement en utilisant des drapeaux dans " +"[code]flags[/code] (voir [enum DuplicateFlags)].\n" +"[b]Note :[/b] Ça ne fonctionnera pas correctement si le nœud contient un " +"script avec des arguments de constructeur (c'est-à-dire qu'on doit fournir " +"des arguments à la méthode [method Object._init]). Dans ce cas, le nœud sera " +"dupliqué sans script." #: doc/classes/Node.xml msgid "" @@ -48315,6 +49418,23 @@ msgid "" "consider using [method get_node] instead. To avoid using [method find_node] " "too often, consider caching the node reference into a variable." msgstr "" +"Trouve un descendant de ce nœud dont le nom correspond à [code]mask[/code] " +"suivant le même fonctionnement que pour [method String.match] (c'est-à-dire " +"sensible à la casse, que [code]\"*\"[/code] correspond à un zéro au un seul " +"caractère, et que [code]\"?\"[/code] correspond à n'importe quel unique " +"caractère sauf [code]\".\"[/code]). Retourne [code]null[/code] si aucun " +"[Node] correspondant n'est trouvée.\n" +"[b]Note :[/b] La correspondance ne se fait pas sur le chemin complet mais " +"juste les noms des nœuds.\n" +"Si [code]owned[/code] est [code]true[/code], cette méthode ne trouve que des " +"nœuds dont le propriétaire est ce nœud. Ceci est particulièrement important " +"pour les scènes instanciée par un script, parce que ces scènes n'ont pas de " +"propriétaire.\n" +"[b]Note :[/b] Comme cette méthode liste tous les descendants d'un nœud, " +"c'est le moyen le plus lent d'obtenir une référence à un autre nœud. Dans la " +"mesure du possible, essayez plutôt d'utiliser [method get_node]. Pour éviter " +"d'utiliser [method find_node] trop souvent, essayez de mettre en chache la " +"référence de ce nœud dans une variable." #: doc/classes/Node.xml msgid "" @@ -48329,6 +49449,18 @@ msgid "" "[method get_node] instead. To avoid using [method find_parent] too often, " "consider caching the node reference into a variable." msgstr "" +"Trouve le premier parent de ce nœud dont le nom correspond à " +"[code]mask[/code] suivant le même fonctionnement que pour [method String." +"match] (c'est-à-dire sensible à la casse, que [code]\"*\"[/code] correspond " +"à un zéro au un seul caractère, et que [code]\"?\"[/code] correspond à " +"n'importe quel unique caractère sauf [code]\".\"[/code]).\n" +"[b]Note :[/b] La correspondance ne se fait pas sur le chemin complet mais " +"juste les noms des nœuds.\n" +"[b]Note :[/b] Comme cette méthode liste tous les parents d'un nœud, c'est le " +"moyen le plus lent d'obtenir une référence à un autre nœud. Dans la mesure " +"du possible, essayez plutôt d'utiliser [method get_node]. Pour éviter " +"d'utiliser [method find_node] trop souvent, essayez de mettre en chache la " +"référence de ce nœud dans une variable." #: doc/classes/Node.xml msgid "" @@ -48336,6 +49468,9 @@ msgid "" "method is often used for iterating all children of a node.\n" "To access a child node via its name, use [method get_node]." msgstr "" +"Retourne un nœud enfant par son index (voir [method get_child_count)]. Cette " +"méthode est souvent utilisée pour itérer tous les enfants d'un nœud.\n" +"Pour accéder à un nœud enfant par son nom, utilisez [method get_node]." #: doc/classes/Node.xml msgid "Returns the number of child nodes." @@ -48363,17 +49498,38 @@ msgid "" " non_internal_groups.push_back(group)\n" "[/codeblock]" msgstr "" +"Retourne un tableau énumérant les groupes dont ce nœud est membre.\n" +"[b]Note :[/b] Pour des raisons de performance, l'ordre des groupes de nœuds " +"n'est [i]pas[/i] garanti. cet ordre des groupes de nœuds ne devrait pas être " +"utilisé car il peut varier entre les différents projets.\n" +"[b]Note :[/b] Le moteur utilise des noms de groupe en l'interne (tous " +"commençent par \"_\"). Pour éviter les conflits avec des groupes internes, " +"n'ajoutez pas de groupes personnalisés dont le nom commence par \"_\". Pour " +"exclure les groupes internes en boucle sur [method get_groups], utiliser le " +"code suivant:\n" +"[codeblock]\n" +"# Enregistre tous les nœuds des groupes non internes au moteur (dans un " +"tableau de String).\n" +"var non_internal_groups = []\n" +"for group in get_groups():\n" +" if not group.begins_with(\"_\"):\n" +" non_internal_groups.push_back(group)\n" +"[/codeblock]" #: doc/classes/Node.xml msgid "" "Returns the node's index, i.e. its position among the siblings of its parent." msgstr "" +"Retourne l'indice du nœud, c'est-à-dire sa position parmi les enfants de son " +"parent." #: doc/classes/Node.xml msgid "" "Returns the peer ID of the network master for this node. See [method " "set_network_master]." msgstr "" +"Retourne l'identifiant du pair du maître du réseau pour ce nœud. Voir " +"[method set_network_master]." #: doc/classes/Node.xml msgid "" @@ -48452,12 +49608,33 @@ msgid "" "[[CollisionShape2D:1161], [RectangleShape2D:1156], :extents]\n" "[/codeblock]" msgstr "" +"Récupère un nœud et une de ses ressources comme spécifié par le sous-nom de " +"son [NodePath] (ex.: [code]Area2D/CollisionShape2D:shape[/code]). Si " +"plusieurs ressources imbriquées sont spécifiées dans le [NodePath], seul le " +"dernier sera récupéré.\n" +"La valeur de retour est un tableau de 3 éléments : le premier élément est le " +"[Node] (ou [code]null[/code] s'il n'est pas trouvé), le deuxième élément est " +"la [Resource] (ou [code]null[/code] si elle n'est pas trouvée), et le " +"troisième élément est le reste du [NodePath], le cas échéant.\n" +"Par exemple, en supposant que [code]Area2D/CollisionShape2D[/code] est un " +"nœud valide et que sa propriété [code]shape[/code] a été assignée à une " +"ressource [RectangleShape2D], on pourrait avoir ce type de sortie:\n" +"[codeblock]\n" +"print(get_node_and_resource(\"Area2D/CollisionShape2D\")) # " +"[[CollisionShape2D:1161], Null, ]\n" +"print(get_node_and_resource(\"Area2D/CollisionShape2D:shape\")) # " +"[[CollisionShape2D:1161], [RectangleShape2D:1156], ]\n" +"print(get_node_and_resource(\"Area2D/CollisionShape2D:shape:extents\")) # " +"[[CollisionShape2D:1161], [RectangleShape2D:1156], :extents]\n" +"[/codeblock]" #: doc/classes/Node.xml msgid "" "Similar to [method get_node], but does not log an error if [code]path[/code] " "does not point to a valid [Node]." msgstr "" +"Semblable à [method get_node], mais n'affiche pas d'erreur si [code]path[/" +"code] ne pointe pas vers une valeur valide [Node]." #: doc/classes/Node.xml msgid "" @@ -48472,12 +49649,18 @@ msgid "" "Returns the absolute path of the current node. This only works if the " "current node is inside the scene tree (see [method is_inside_tree])." msgstr "" +"Retourne le chemin absolu du nœud actuel. Cela ne fonctionne que si le nœud " +"actuel est à l'intérieur de l'arborescence de la scène (voir [method " +"is_inside_tree)]." #: doc/classes/Node.xml msgid "" "Returns the relative [NodePath] from this node to the specified [code]node[/" "code]. Both nodes must be in the same scene or the function will fail." msgstr "" +"Retourne le chemin [NodePath] relatif de ce nœud par rapport au nœud " +"[code]nœud[/code] spécifié. Les deux nœuds doivent être dans la même scène " +"sinon la fonction échouera." #: doc/classes/Node.xml msgid "" @@ -48486,18 +49669,26 @@ msgid "" "processing unless the frames per second is changed via [member Engine." "iterations_per_second]." msgstr "" +"Retourne le temps écoulé (en secondes) depuis la dernière trame physique (" +"voir [method _physics_process]). C'est toujours une valeur constante dans le " +"traitement de la physique à moins que les trames par seconde ne soient " +"changés via [member Engine.iterations_per_second]." #: doc/classes/Node.xml msgid "" "Returns the node's order in the scene tree branch. For example, if called on " "the first child node the position is [code]0[/code]." msgstr "" +"Retourne l'ordre du nœud dans la branche de la scène. Par exemple, si on " +"l'appelle sur le premier nœud enfant, la position est [code]0[/code]." #: doc/classes/Node.xml msgid "" "Returns the time elapsed (in seconds) since the last process callback. This " "value may vary from frame to frame." msgstr "" +"Retourne le temps écoulé (en secondes) depuis le dernier rappel de process. " +"Cette valeur peut varier d'une trame à l'autre." #: doc/classes/Node.xml msgid "" @@ -48528,12 +49719,19 @@ msgid "" "shape[/code]. Properties with a non-[Resource] type (e.g. nodes or primitive " "math types) are not considered resources." msgstr "" +"Retourne [code]true[/code] si le [NodePath] désigne un nœud valide et son " +"sous-nom désigne une ressource valide, par exemple [code]Area2D/" +"CollisionShape2D:shape[/code]. Les propriétés avec un type qui n'est pas une " +"[Resource] (par exemple les nœuds ou les types mathématiques primitifs) ne " +"sont pas considérées comme des ressources." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if the given node is a direct or indirect child of " "the current node." msgstr "" +"Retourne [code]true[/code] si le nœud donné est un enfant direct ou indirect " +"du nœud actuel." #: doc/classes/Node.xml msgid "" @@ -48554,6 +49752,8 @@ msgid "" "Returns [code]true[/code] if this node is in the specified group. See notes " "in the description, and the group methods in [SceneTree]." msgstr "" +"Retourne [code]true[/code] si ce nœud est dans le groupe spécifié. Voir les " +"notes dans la description, et les méthodes de groupe dans [SceneTree]." #: doc/classes/Node.xml msgid "" @@ -48565,6 +49765,7 @@ msgstr "" msgid "" "Returns [code]true[/code] if the local system is the master of this node." msgstr "" +"Retourne [code]true[/code] si le système local est le maître de ce nœud." #: doc/classes/Node.xml msgid "" @@ -48574,6 +49775,11 @@ msgid "" "[b]and[/b] physics interpolation is enabled within the [SceneTree]. This can " "be tested using [method is_physics_interpolated_and_enabled]." msgstr "" +"Retourne [code]true[/code] si le drapeau interpolé de la physique est défini " +"pour ce nœud (voir [member physics_interpolation_mode)].\n" +"[b]Note :[/b] L'interpolation ne sera active que si le drapeau est défini " +"[b]et[/b] que l'interpolation physique est activée dans [SceneTree]. Ceci " +"peut être testé en utilisant [method is_physics_interpolated_and_enabled]." #: doc/classes/Node.xml msgid "" @@ -48584,36 +49790,52 @@ msgid "" "See [member SceneTree.physics_interpolation] and [member ProjectSettings." "physics/common/physics_interpolation]." msgstr "" +"Retourne [code]true[/code] si l'interpolation physique est activée (voir [" +"member physics_interpolation_mode]) [b]et[/b] activée dans [SceneTree].\n" +"Il s'agit d'une version pratique de [method is_physics_interpolated] qui " +"vérifie également si l'interpolation physique est activée globalement.\n" +"Voir [member SceneTree.physics_interpolation] et [member ProjectSettings." +"physics/common/physics_interpolation]." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if physics processing is enabled (see [method " "set_physics_process])." msgstr "" +"Retourne [code]true[/code] si le traitement physique est activé (voir " +"[method set_physics_process)]." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if internal physics processing is enabled (see " "[method set_physics_process_internal])." msgstr "" +"Retourne [code]true[/code] si le traitement physique interne est activé " +"(voir [method set_physics_process_internal)]." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if processing is enabled (see [method " "set_process])." msgstr "" +"Retourne [code]true[/code] si le traitement est activé (voir [method " +"set_process)]." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if the node is processing input (see [method " "set_process_input])." msgstr "" +"Retourne [code]true[/code] si le nœud gère l'entrée (voir [method " +"set_process_input)]." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if internal processing is enabled (see [method " "set_process_internal])." msgstr "" +"Retourne [code]true[/code] si le traitement interne est activé (voir [method " +"set_process_internal)]." #: doc/classes/Node.xml msgid "" @@ -48628,6 +49850,8 @@ msgid "" "Returns [code]true[/code] if the node is processing unhandled key input (see " "[method set_process_unhandled_key_input])." msgstr "" +"Retourne [code]true[/code] si le nœud gère l'entrée de touche non traitée " +"(voir [method set_process_unhandled_key_input)]." #: doc/classes/Node.xml msgid "" @@ -48635,12 +49859,17 @@ msgid "" "Since calls, signals, etc are performed by tree order, changing the order of " "children nodes may be useful." msgstr "" +"Déplace un nœud enfant à une position différente (ordre) parmi les autres " +"enfants. Comme les appels, les signaux, etc. sont effectués par l'ordre des " +"arborescences, changer l'ordre des nœuds d'enfants peut être utile." #: doc/classes/Node.xml msgid "" "Prints all stray nodes (nodes outside the [SceneTree]). Used for debugging. " "Works only in debug builds." msgstr "" +"Imprime tous les nœuds égarés (sauf le [SceneTree)]. Utilisé pour le " +"débogage. Fonctionne seulement dans les versions de débogage." #: doc/classes/Node.xml msgid "" @@ -48657,6 +49886,18 @@ msgid "" "TheGame/SplashScreen/Camera2D\n" "[/codeblock]" msgstr "" +"Imprime l'arborescence dans la console. Utilisé principalement à des fins de " +"débogage. Cette version affiche le chemin par rapport au nœud actuel, ce qui " +"est utile pour le copier/coller dans la fonction [method get_node].\n" +"[b]Exemple de sortie:[/b]\n" +"[codeblock]\n" +"TheGame\n" +"TheGame/Menu\n" +"TheGame/Menu/Label\n" +"TheGame/Menu/Camera2D\n" +"TheGame/SplashScreen\n" +"TheGame/SplashScreen/Camera2D\n" +"[/codeblock]" #: doc/classes/Node.xml msgid "" @@ -48673,6 +49914,19 @@ msgid "" " ┖╴Camera2D\n" "[/codeblock]" msgstr "" +"Comme [method print_tree], cela imprime l'arborescence dans la console. " +"Cette version affiche une représentation plus graphique semblable à ce qui " +"est affiché dans l'inspecteur de scène. C'est utile pour inspecter les " +"grands arborescences.\n" +"[b]Exemple de sortie:[/b]\n" +"[codeblock]\n" +" ┖╴TheGame\n" +" ┠╴Menu\n" +" ┃ ┠╴Label\n" +" ┃ ┖╴Camera2D\n" +" ┖╴SplashScreen\n" +" ┖╴Camera2D\n" +"[/codeblock]" #: doc/classes/Node.xml msgid "" @@ -48683,12 +49937,20 @@ msgid "" "[code]parent_first[/code] is [code]false[/code], the children will be called " "first." msgstr "" +"Appelle la méthode donnée (si présente) avec les arguments spécifiés dans " +"[code]args[/code] sur ce nœud et récursivement sur tous ses enfants. Si " +"l'argument [code]parent_first[/code] est [code]true[/code], la méthode sera " +"appelée d'abord sur le nœud courant, puis sur tous ses enfants. Si " +"[code]parent_first[/code] est [code]false[/code], les enfants seront appelés " +"en premier." #: doc/classes/Node.xml msgid "" "Notifies the current node and all its children recursively by calling " "[method Object.notification] on all of them." msgstr "" +"Notifie le nœud actuel et tous ses enfants de façon récursive en les " +"appelant [method Object.notification] sur tous." #: doc/classes/Node.xml msgid "" @@ -48703,6 +49965,17 @@ msgid "" "[method @GDScript.is_instance_valid] before attempting to call its methods " "or access its properties." msgstr "" +"Place le nœud dans une file d'attente pour la suppression à la fin de la " +"trame actuel. Lorsque supprimé, tous ses nœuds d'enfants seront supprimés " +"aussi. Cette méthode s'assure qu'il est sûr de supprimer le nœud, " +"contrairement [method Object.free]. Utilisez [method Object." +"is_queued_for_deletion] pour vérifier si un nœud sera supprimé à la fin de " +"la trame.\n" +"[b]Important:[/b] Si vous avez une variable pointant vers un nœud, il ne " +"sera [i]pas[/i] attribué à [code]null[/code] une fois le nœud libéré. Au " +"lieu de cela, il va pointer vers [i]l'instance précédemment libérée[/i] et " +"vous devez le valider avec [method @GDScript.is_instance_valid] avant de " +"risquer d'appeler des méthodes dessus ou d'accéder à ses propriétés." #: doc/classes/Node.xml msgid "" @@ -48713,6 +49986,12 @@ msgid "" "of it. After using [code]raise[/code], a Control will be drawn on top of its " "siblings." msgstr "" +"Déplace ce nœud vers le bas de la hiérarchie des enfants. Cela est souvent " +"utile dans les nœuds d'interface ([Control]), parce que leur ordre de dessin " +"dépend de leur ordre dans l'arborescence. Le Node en haut est dessiné " +"d'abord, puis les nœuds en dessous dans la hiérarchie qui sont " +"successivement dessinés. Après avoir utilisé [code]raise[/code], un contrôle " +"sera affiché par dessus les autres enfants." #: doc/classes/Node.xml msgid "" @@ -48720,6 +49999,9 @@ msgid "" "it exists). All event subscriptions that pass by the removed node will be " "unsubscribed." msgstr "" +"Retire un nœud et fixe tous ses enfants comme enfants du nœud parent (s'il " +"existe). Tous les souscriptions d'événement qui passent par le nœud retiré " +"seront aussi retirées." #: doc/classes/Node.xml msgid "" @@ -48728,12 +50010,19 @@ msgid "" "(or its descendants) to be [code]null[/code], if that [member owner] is no " "longer a parent or ancestor." msgstr "" +"Retire un nœud d'enfant. Le nœud n'est PAS supprimé et doit être supprimé " +"manuellement.\n" +"[b]Note :[/b] Cette fonction peut définir le [member owner] du nœud enlevé " +"(ou ses descendants) comme [code]null[/code], si ce [member owner] n'est " +"plus un parent." #: doc/classes/Node.xml msgid "" "Removes a node from a group. See notes in the description, and the group " "methods in [SceneTree]." msgstr "" +"Retire un nœud d'un groupe. Voir les notes dans la description, et les " +"méthodes de groupe dans [SceneTree]." #: doc/classes/Node.xml msgid "" @@ -48745,6 +50034,13 @@ msgid "" "need to keep it in a variable for later use or free it using [method Object." "free]." msgstr "" +"Remplace un nœud dans une scène par celui donné. Les souscriptions qui " +"passent par ce nœud seront perdus.\n" +"[b]Note :[/b] Le nœud donné deviendra le nouveau parent de tous les nœuds " +"d'enfants que le nœud remplacé avait.\n" +"[b]Note :[/b] Le nœud remplacé n'est pas automatiquement libéré, donc vous " +"devez le garder dans une variable pour une utilisation ultérieure ou le " +"libérer en utilisant [method Object.free]." #: doc/classes/Node.xml msgid "" @@ -48756,6 +50052,13 @@ msgid "" "which case, [code]_ready[/code] will be called in the same order as it would " "normally)." msgstr "" +"Demande que [code]_ready[/code] soit de nouveau appelé. Notez que la méthode " +"va s'appeler immédiatement, mais qu'elle est prévue lorsque le nœud est " +"ajouté à l'arborescence de scène à nouveau (voir [method _ready)]. " +"[code]_ready[/code] est appelé seulement pour le nœud qui l'a demandé, ce " +"qui signifie que vous devez le demander pour chaque enfant si vous voulez " +"qu'ils appellent [code]_ready[/code] aussi (dans quel cas, [code]_ready[/" +"code] sera appelé dans le même ordre que normalement)." #: doc/classes/Node.xml msgid "" @@ -48771,6 +50074,17 @@ msgid "" "[b]Note:[/b] This function should be called [b]after[/b] moving the node, " "rather than before." msgstr "" +"Lorsque l'interpolation de la physique est active, déplacer un nœud vers une " +"transformation radicalement différente (comme le placement dans un niveau) " +"peut entraîner un glissement visible car l'objet est rendu lors de son " +"déplacement lors de la trame physique.\n" +"Ce glitch peut être évité en appelant [code]reset_physics_interpolation[/" +"code], qui annule temporairement l'interpolation jusqu'à ce que la trame " +"physique soit complète.\n" +"[constant NOTIFICATION_RESET_PHYSICS_INTERPOLATION] sera reçu par le nœud et " +"tous les enfants de façon récursive.\n" +"[b]Note :[/b] Cette fonction doit être appelée [b]après[/b] le déplacement " +"du nœud, plutôt qu'avant." #: doc/classes/Node.xml msgid "" @@ -48788,6 +50102,20 @@ msgid "" "like [code]server_disconnected[/code] or by checking [code]SceneTree." "network_peer.get_connection_status() == CONNECTION_CONNECTED[/code]." msgstr "" +"Envoie une requête d'appel de procédure à distance pour la [code]method[/" +"code] donnée aux pairs sur le réseau (et localement), en option en envoyant " +"tous les arguments supplémentaires comme arguments à la méthode appelée par " +"le RPC. La requête d'appel ne sera reçue que par des nœuds ayant le même " +"[NodePath], y compris le même nom de nœud. Le comportement dépend de la " +"configuration RPC pour la méthode donnée, voir [method rpc_config]. Les " +"méthodes ne sont pas exposées aux RPC par défaut. Voir aussi [method rset] " +"et [method rset_config] pour les propriétés. Retourne [code]null[/code].\n" +"[b]Note :[/b] Vous pouvez seulement utiliser RPC en toute sécurité sur les " +"clients après avoir reçu le signal [code]connected_to_server[/code] du " +"[SceneTree]. Vous devez également suivre l'état de connexion, soit par les " +"signaux [SceneTree] comme [code]server_disconnected[/code] ou en vérifiant " +"[code]SceneTree.network_peer.get_connection_status() == " +"CONNECTION_CONNECTED[/code]." #: doc/classes/Node.xml msgid "" @@ -48799,6 +50127,13 @@ msgid "" "By default, methods are not exposed to networking (and RPCs). See also " "[method rset] and [method rset_config] for properties." msgstr "" +"Change le mode RPC pour la [code]method[/code] donné pour le " +"[code]mode[/code] spécifié. Voir [enum MultiplayerAPI.RPCMode]. Une " +"alternative est d'annoter les méthodes et les propriétés avec les mots-clés " +"correspondants ([code]remote[/code], [code]master[/code], [code]puppet[/code]" +", [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code])" +". Par défaut, les méthodes ne sont pas exposées au réseaut (et aux RPC). " +"Voir aussi [method rset] et [method rset_config] pour les propriétés." #: doc/classes/Node.xml msgid "" @@ -48806,6 +50141,9 @@ msgid "" "(see [method NetworkedMultiplayerPeer.set_target_peer]). Returns [code]null[/" "code]." msgstr "" +"Envoie un [method rpc] à un pair spécifique identifié par [code]peer_id[/" +"code] (voir [method NetworkedMultiplayerPeer.set_target_peer]). Retourne " +"[code]null[/code]." #: doc/classes/Node.xml msgid "" @@ -48820,6 +50158,9 @@ msgid "" "using an unreliable protocol (see [method NetworkedMultiplayerPeer." "set_target_peer]). Returns [code]null[/code]." msgstr "" +"Envoie un [method rpc] à un pair spécifique identifié par [code]peer_id[/" +"code] en utilisant un protocole non fiable (voir [method " +"NetworkedMultiplayerPeer.set_target_peer]). Retourne [code]null[/code]." #: doc/classes/Node.xml msgid "" @@ -48828,6 +50169,10 @@ msgid "" "rset_config]. See also [method rpc] for RPCs for methods, most information " "applies to this method as well." msgstr "" +"Change une propriété distante sur d'autres pairs (et localement). Le " +"comportement dépend de la configuration du RPC pour la propriété donnée, " +"voir [method rset_config]. Voir aussi [method rpc] pour les RPC sur les " +"méthodes, la plupart des informations s'appliquent aussi à cette méthode." #: doc/classes/Node.xml msgid "" @@ -48839,6 +50184,13 @@ msgid "" "By default, properties are not exposed to networking (and RPCs). See also " "[method rpc] and [method rpc_config] for methods." msgstr "" +"Change le mode RPC pour la [code]property[/code] donnée au [code]mode[/code] " +"spécifié. Voir [enum MultiplayerAPI.RPCMode]. Une alternative est " +"l'annotation des méthodes et des propriétés avec les mots-clés " +"correspondants ([code]remote[/code], [code]master[/code], [code]puppet[/code]" +", [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code])" +". Par défaut, les propriétés ne sont pas exposées au réseau (et au RPC). " +"Voir aussi [method rpc] et [method rpc_config] pour les méthodes." #: doc/classes/Node.xml msgid "" @@ -49086,11 +50438,13 @@ msgid "" msgstr "" #: doc/classes/Node.xml -#, fuzzy msgid "" "Notification received when the node is about to exit a [SceneTree].\n" "This notification is emitted [i]after[/i] the related [signal tree_exiting]." -msgstr "La notification reçue quand le nœud va quitter le [SceneTree]." +msgstr "" +"La notification reçue quand le nœud va quitter le [SceneTree].\n" +"Cette notification est émise [i]après[/i] le signal [signal tree_exiting] " +"correspondant." #: doc/classes/Node.xml msgid "Notification received when the node is moved in the parent." @@ -49384,9 +50738,8 @@ msgid "" msgstr "" #: doc/classes/NodePath.xml -#, fuzzy msgid "Pre-parsed scene tree path." -msgstr "Chemin de l'arborescence des scènes pré-analysé." +msgstr "Le chemin pré-analysé de l'arborescence des scènes." #: doc/classes/NodePath.xml msgid "" @@ -50417,19 +51770,16 @@ msgid "Sets an individual hole point position." msgstr "Définit la position d'un trou simple." #: doc/classes/OccluderShapePolygon.xml -#, fuzzy msgid "Sets an individual polygon point position." -msgstr "Définit la position d'un polygone simple." +msgstr "Définit la position d'un seul point d'un polygone." #: doc/classes/OccluderShapePolygon.xml -#, fuzzy msgid "Allows changing the hole geometry from code." -msgstr "Dessine une géométrie simple à partir du code." +msgstr "" #: doc/classes/OccluderShapePolygon.xml -#, fuzzy msgid "Allows changing the polygon geometry from code." -msgstr "Dessine une géométrie simple à partir du code." +msgstr "" #: doc/classes/OccluderShapePolygon.xml msgid "" @@ -50503,8 +51853,14 @@ msgid "See [enum ShadowDetail]." msgstr "Voir [enum ShadowDetail]." #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." -msgstr "Voir [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." +msgstr "" #: doc/classes/OmniLight.xml msgid "" @@ -50515,7 +51871,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -50692,18 +52049,16 @@ msgid "Returns the text of the item at index [code]idx[/code]." msgstr "Retourne le texte de l'élément à l'index [code]idx[/code]." #: doc/classes/OptionButton.xml -#, fuzzy msgid "Returns the tooltip of the item at index [code]idx[/code]." -msgstr "Retourne le texte de l'élément à l'index [code]idx[/code]." +msgstr "Retourne l'infobulle de l'élément à l'index [code]idx[/code]." #: doc/classes/OptionButton.xml -#, fuzzy msgid "" "Returns the ID of the selected item, or [code]-1[/code] if no item is " "selected." msgstr "" -"Retourne la position de l’élément qui a actuellement le focus. Ou retourne " -"[code]-1[/code] si aucun n'a le focus." +"Retourne l'identifiant de l’élément sélectionné, ou [code]-1[/code] si aucun " +"n'est sélectionné." #: doc/classes/OptionButton.xml msgid "" @@ -50756,9 +52111,8 @@ msgid "Sets the text of the item at index [code]idx[/code]." msgstr "Définit le texte pour l'élément à l'index [code]idx[/code]." #: doc/classes/OptionButton.xml -#, fuzzy msgid "Sets the tooltip of the item at index [code]idx[/code]." -msgstr "Définit le texte pour l'élément à l'index [code]idx[/code]." +msgstr "Définit l'infobulle pour l'élément à l'index [code]idx[/code]." #: doc/classes/OptionButton.xml msgid "" @@ -50881,9 +52235,8 @@ msgstr "" "fils d'exécutions." #: doc/classes/OS.xml -#, fuzzy msgid "Centers the window on the screen if in windowed mode." -msgstr "Définit la position du nœud spécifié." +msgstr "" #: doc/classes/OS.xml msgid "" @@ -51042,18 +52395,16 @@ msgid "" msgstr "" #: doc/classes/OS.xml -#, fuzzy msgid "Returns the scancode of the given string (e.g. \"Escape\")." -msgstr "Renvoie le reste de deux vecteurs." +msgstr "" #: doc/classes/OS.xml msgid "Returns the total number of available audio drivers." msgstr "Retourne le nombre total de périphériques audio." #: doc/classes/OS.xml -#, fuzzy msgid "Returns the audio driver name for the given index." -msgstr "Retourne le sommet à l’index donné." +msgstr "" #: doc/classes/OS.xml msgid "" @@ -51472,14 +52823,13 @@ msgid "" msgstr "" #: doc/classes/OS.xml -#, fuzzy msgid "Returns the epoch time of the operating system in milliseconds." -msgstr "Retourne le temps epoch du système d'exploitation en millisecondes." +msgstr "" +"Retourne l'heure de l'époque du système d'exploitation en millisecondes." #: doc/classes/OS.xml -#, fuzzy msgid "Returns the epoch time of the operating system in seconds." -msgstr "Retourne le temps epoch du système d'exploitation en secondes." +msgstr "Retourne l'heure de l'époque du système d'exploitation en secondes." #: doc/classes/OS.xml msgid "" @@ -51596,9 +52946,8 @@ msgid "" msgstr "" #: doc/classes/OS.xml -#, fuzzy msgid "Returns the number of video drivers supported on the current platform." -msgstr "Renvoie le nombre de points sur l'axe de mélange." +msgstr "" #: doc/classes/OS.xml msgid "" @@ -51646,9 +52995,8 @@ msgid "" msgstr "" #: doc/classes/OS.xml -#, fuzzy msgid "Returns [code]true[/code] if there is content on the clipboard." -msgstr "Retourne [code]true[/code] si l'[AABB] est plate ou vide." +msgstr "Retourne [code]true[/code] si le presse-papiers n'est pas vide." #: doc/classes/OS.xml msgid "" @@ -51670,19 +53018,19 @@ msgid "" msgstr "" #: doc/classes/OS.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the device has a touchscreen or emulates one." -msgstr "Retourne [code]true[/code] (vrai) si la chaîne de caractères est vide." +msgstr "" +"Retourne [code]true[/code] si le périphérique à un écran tactile ou en " +"simule un." #: doc/classes/OS.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the platform has a virtual keyboard, " "[code]false[/code] otherwise." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères est vide, ou " -"[code]false[/code] le cas échéant." +"Retourne [code]true[/code] si la plateforme à un clavier virtuel (non " +"physique), ou [code]false[/code] sinon." #: doc/classes/OS.xml msgid "Hides the virtual keyboard if it is shown, does nothing otherwise." @@ -51717,11 +53065,10 @@ msgid "" msgstr "" #: doc/classes/OS.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the input scancode corresponds to a Unicode " "character." -msgstr "Retourne [code]true[/code] si l'[AABB] chevauche une autre." +msgstr "" #: doc/classes/OS.xml msgid "" @@ -52026,7 +53373,6 @@ msgstr "" "Windows." #: doc/classes/OS.xml -#, fuzzy msgid "" "Requests the OS to open a resource with the most appropriate program. For " "example:\n" @@ -52053,12 +53399,12 @@ msgstr "" "d'accueil de Godot dans le navigateur web par défaut.\n" "- [code]OS.shell_open(\"mailto:example@example.com\")[/code] ouvrira le " "client mail par défaut avec le champs destinataire définit à " -"[code]example@example.com[/code]. Voir [url=https://blog.escapecreative.com/" -"customizing-mailto-links/]Personnaliser les liens [code]mailto:[/code][/url] " -"pour la liste des champs qui peuvent être ajoutés.\n" +"[code]example@example.com[/code]. Voir [url=https://datatracker.ietf.org/doc/" +"html/rfc2368]RFC 2368 - The [code]mailto[/code] URL scheme[/url] pour la " +"liste des champs qui peuvent être ajoutés.\n" "Utilisez [method ProjectSettings.globalize_path] pour convertir un chemin " -"[code]res://[/code] ou [code]user://[/code] en chemin système pour utiliser " -"avec cette méthode.\n" +"[code]res://[/code] ou [code]user://[/code] en chemin système qui peut être " +"utilisé avec cette méthode.\n" "[b]Note :[/b] Cette méthode est implémentée sous Android, iOS, HTML5, Linux, " "macOS et Windows." @@ -52102,12 +53448,12 @@ msgid "" msgstr "" #: doc/classes/OS.xml -#, fuzzy msgid "" "If [code]true[/code], the engine tries to keep the screen on while the game " "is running. Useful on mobile." msgstr "" -"Si [code]true[/code], le mouvement linéaire à travers l’axe Z est limité." +"Si [code]true[/code], Le moteur tente de garder l'écran allumé quand le jeu " +"est lancé. Utile sur les mobiles." #: doc/classes/OS.xml msgid "" @@ -53165,9 +54511,8 @@ msgid "" msgstr "" #: doc/classes/Particles.xml -#, fuzzy msgid "Maximum number of draw passes supported." -msgstr "Nombre maximal de passes de tirage prises en charge." +msgstr "Le nombre maximal de passes de dessin supporté." #: doc/classes/Particles2D.xml msgid "GPU-based 2D particle emitter." @@ -53845,11 +55190,10 @@ msgstr "" "dans les versions finales." #: doc/classes/Performance.xml -#, fuzzy msgid "Available static memory. Not available in release builds." msgstr "" "La mémoire statique disponible. N'est pas utilisable dans les versions " -"finales." +"exportés sans le mode débogage." #: doc/classes/Performance.xml msgid "Available dynamic memory. Not available in release builds." @@ -54682,9 +56026,8 @@ msgid "" msgstr "" #: doc/classes/Physics2DServer.xml -#, fuzzy msgid "Returns the value of a damped spring joint parameter." -msgstr "Renvoie la valeur opposée du paramètre." +msgstr "" #: doc/classes/Physics2DServer.xml #, fuzzy @@ -54692,8 +56035,8 @@ msgid "" "Sets a damped spring joint parameter. See [enum DampedStringParam] for a " "list of available parameters." msgstr "" -"Définit la valeur d’un paramètre de zone. Voir [enum AreaParameter] pour une " -"liste de paramètres disponibles." +"Définit la valeur d’un paramètre de zone. Voir [enum DampedStringParam] pour " +"une liste de paramètres disponibles." #: doc/classes/Physics2DServer.xml msgid "" @@ -55661,18 +57004,16 @@ msgid "Creates a [SliderJoint]." msgstr "Crée un [SliderJoint]." #: doc/classes/PhysicsServer.xml -#, fuzzy msgid "Gets the priority value of the Joint." -msgstr "Renvoie la valeur opposée du paramètre." +msgstr "" #: doc/classes/PhysicsServer.xml msgid "Returns the type of the Joint." msgstr "Retourne le type de Joint." #: doc/classes/PhysicsServer.xml -#, fuzzy msgid "Sets the priority value of the Joint." -msgstr "Renvoie la valeur opposée du paramètre." +msgstr "Définit la priorité de la valeur du Joint." #: doc/classes/PhysicsServer.xml msgid "" @@ -55953,20 +57294,17 @@ msgid "" msgstr "" #: doc/classes/PhysicsServer.xml -#, fuzzy msgid "If set, linear motion is possible within the given limits." msgstr "" -"Si [code]set[/code] il y a un mouvement linéaire possible dans les limites " -"données." +"Si définit, le mouvement linéaire est possible dans les limites données." #: doc/classes/PhysicsServer.xml msgid "If set, rotational motion is possible." msgstr "Si définit, la rotation est possible." #: doc/classes/PhysicsServer.xml -#, fuzzy msgid "If set, there is a rotational motor across these axes." -msgstr "La vitesse de toutes les rotations à travers l’axe X." +msgstr "" #: doc/classes/PhysicsServer.xml msgid "" @@ -56027,14 +57365,12 @@ msgid "Sets the [Shape] that will be used for collision/intersection queries." msgstr "" #: doc/classes/PhysicsShapeQueryParameters.xml -#, fuzzy msgid "If [code]true[/code], the query will take [Area]s into account." -msgstr "Si [code]true[/code], la texture sera centrée." +msgstr "Si [code]true[/code], le requête prendra les [Area] en compte." #: doc/classes/PhysicsShapeQueryParameters.xml -#, fuzzy msgid "If [code]true[/code], the query will take [PhysicsBody]s into account." -msgstr "Si [code]true[/code], la texture sera centrée." +msgstr "Si [code]true[/code], le requête prendra les [PhysicsBody] en compte." #: doc/classes/PinJoint.xml #, fuzzy @@ -56060,13 +57396,10 @@ msgid "" msgstr "" #: doc/classes/PinJoint.xml -#, fuzzy msgid "" "If above 0, this value is the maximum value for an impulse that this Joint " "produces." msgstr "" -"Retourne quand la mot clé [code]keyword[/code] spécifié a une couleur de " -"défini ou non." #: doc/classes/PinJoint2D.xml #, fuzzy @@ -56105,11 +57438,8 @@ msgid "" msgstr "" #: doc/classes/Plane.xml -#, fuzzy msgid "Creates a plane from the three points, given in clockwise order." -msgstr "" -"Crée un plan à partir des trois points, donné dans le sens des aiguilles " -"d’une montre." +msgstr "Crée un plan à partir de trois points, spécifiés dans le sens horaire." #: doc/classes/Plane.xml msgid "Creates a plane from the normal and the plane's distance to the origin." @@ -56337,9 +57667,8 @@ msgid "Returns the path to the node associated with the specified bone." msgstr "Retourne le chemin d’accès au nœud associé à l’os spécifié." #: doc/classes/Polygon2D.xml -#, fuzzy msgid "Returns the height values of the specified bone." -msgstr "Retourne la hauteur de l'os spécifié." +msgstr "Retourne les valeurs de hauteur de l'os spécifié." #: doc/classes/Polygon2D.xml msgid "Sets the path to the node associated with the specified bone." @@ -56610,9 +57939,8 @@ msgstr "Change l'octet à la position donnée." #: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml #: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml #: doc/classes/PoolVector3Array.xml -#, fuzzy msgid "Sorts the elements of the array in ascending order." -msgstr "Retire l' élément du tableau à l'index donné." +msgstr "Tris les éléments du tableau dans l'ordre croissant." #: doc/classes/PoolByteArray.xml msgid "" @@ -56624,7 +57952,6 @@ msgstr "" "nouveau [PoolByteArray]. Chaque index négatif partira de la fin du tableau." #: doc/classes/PoolColorArray.xml -#, fuzzy msgid "A pooled array of [Color]s." msgstr "Un tableau compacté de [Color]." @@ -56789,9 +58116,8 @@ msgid "Changes the int at the given index." msgstr "Modifie le [int] à l’index donné." #: doc/classes/PoolRealArray.xml -#, fuzzy msgid "A pooled array of real numbers ([float])." -msgstr "Un tableau compacté de flottants ([float])." +msgstr "Un tableau compacté de nombres réels (des flottants, [float])." #: doc/classes/PoolRealArray.xml msgid "" @@ -56870,7 +58196,6 @@ msgid "Changes the float at the given index." msgstr "Change la flottant à la position donnée." #: doc/classes/PoolStringArray.xml -#, fuzzy msgid "A pooled array of [String]s." msgstr "Un tableau compacté de [String]." @@ -56949,7 +58274,6 @@ msgid "Changes the [String] at the given index." msgstr "Change la [String] à la position donnée." #: doc/classes/PoolVector2Array.xml -#, fuzzy msgid "A pooled array of [Vector2]s." msgstr "Un tableau compacté de [Vector2]." @@ -57031,7 +58355,6 @@ msgid "A pooled array of [Vector3]." msgstr "Un tableau compacté de [Vector3]." #: doc/classes/PoolVector3Array.xml -#, fuzzy msgid "" "An array specifically designed to hold [Vector3]. Optimized for memory " "usage, does not fragment the memory.\n" @@ -57194,9 +58517,8 @@ msgstr "" "[WindowDialog]." #: doc/classes/PopupDialog.xml -#, fuzzy msgid "Sets a custom [StyleBox] for the panel of the [PopupDialog]." -msgstr "[StyleBox] par défaut pour le [Button]." +msgstr "" #: doc/classes/PopupMenu.xml msgid "PopupMenu displays a list of options." @@ -57426,7 +58748,6 @@ msgid "" msgstr "" #: doc/classes/PopupMenu.xml -#, fuzzy msgid "" "Returns the tooltip associated with the specified index [code]idx[/code]." msgstr "Retourne l'infobulle associée avec l'index [code]idx[/code] spécifié." @@ -57489,9 +58810,8 @@ msgid "" msgstr "" #: doc/classes/PopupMenu.xml -#, fuzzy msgid "Sets the currently focused item as the given [code]index[/code]." -msgstr "Retourne la position du point à l'index [code]point[/code]." +msgstr "" #: doc/classes/PopupMenu.xml msgid "Hides the [PopupMenu] when the window loses focus." @@ -57581,11 +58901,10 @@ msgstr "" "spécifié." #: doc/classes/PopupMenu.xml -#, fuzzy msgid "" "Toggles the check state of the item of the specified index [code]idx[/code]." msgstr "" -"Active l'état de contrôle de l'élément de l'index spécifié [code]idx[/code]." +"Bascule l'état de contrôle de l'élément de l'index [code]idx[/code] spécifié." #: doc/classes/PopupMenu.xml msgid "" @@ -57999,9 +59318,8 @@ msgid "" msgstr "" #: doc/classes/ProceduralSky.xml -#, fuzzy msgid "Amount of energy contribution from the sun." -msgstr "Montant de la contribution énergétique du ciel." +msgstr "La quantité de contribution énergétique du ciel." #: doc/classes/ProceduralSky.xml msgid "The sun's height using polar coordinates." @@ -58253,6 +59571,16 @@ msgid "" "specify the offset in bytes to the start of the resource pack. This is only " "supported for .pck files." msgstr "" +"Charge le contenu du fichier .pck ou .zip spécifié par [code]pack[/code] " +"dans le système de fichiers de ressources ([code]res://[/code]). Retourne " +"[code]true[/code] en cas de succès.\n" +"[b]Note :[/b] Si un fichier de [code]pack[/code] partage le même chemin " +"qu'un fichier déjà dans le système de fichiers de ressources, toute " +"tentative de charger ce fichier utilisera le fichier de [code]pack[/code] " +"sauf si [code]replace_files[/code] est défini à [code]false[/code].\n" +"[b]Note :[/b] Le paramètre optionnel [code]offset[/code] peut être utilisé " +"pour spécifier le décalage en octets au début du pack de ressources. Ceci " +"n'est pris en charge que pour les fichiers .pck." #: doc/classes/ProjectSettings.xml msgid "" @@ -58260,18 +59588,25 @@ msgid "" "to the absolute, native OS [code]path[/code]. See also [method " "globalize_path]." msgstr "" +"Retourne le chemin localisé (démarrant par [code]res://[/code]) " +"correspondant au chemin [code]path[/code] absolu et natif du système " +"d'exploitation. Voir aussi [method globalize_path]." #: doc/classes/ProjectSettings.xml msgid "" "Returns [code]true[/code] if the specified property exists and its initial " "value differs from the current value." msgstr "" +"Retourne [code]true[/code] si la propriété spécifiée existe et sa valeur " +"initiale diffère de la valeur actuelle." #: doc/classes/ProjectSettings.xml msgid "" "Returns the specified property's initial value. Returns [code]null[/code] if " "the property does not exist." msgstr "" +"Retourne la valeur initiale de la propriété spécifiée. Retourne " +"[code]null[/code] si la propriété n'existe pas." #: doc/classes/ProjectSettings.xml msgid "" @@ -58281,6 +59616,12 @@ msgid "" "want to change project settings in exported projects, use [method " "save_custom] to save [code]override.cfg[/code] file." msgstr "" +"Enregistre la configuration du fichier [code]project.godot[/code].\n" +"[b]Note :[/b] Cette méthode est destinée à être utilisée par les greffons de " +"l'éditeur, puisque [ProjectSettings] ne peut pas être modifié puis chargé " +"directement dans une application lancée. Si vous voulez modifier les " +"paramètres de projet depuis un projet exporté, utilisez [method save_custom] " +"pour enregistrer le fichier [code]override.cfg[/code]." #: doc/classes/ProjectSettings.xml msgid "" @@ -58290,18 +59631,28 @@ msgid "" "code] file, which is also text, but can be used in exported projects unlike " "other formats." msgstr "" +"Enregistre la configuration vers un fichier personnalisé. L'extension de " +"fichier doit être [code].godot[/code] (pour enregistrer dans le format " +"[ConfigFile] au format texte) ou [code].binary[/code] (pour enregistrer au " +"format binaire). Vous pouvez également enregistrer le fichier [code]override." +"cfg[/code], qui est également au format texte, mais peut être utilisé dans " +"des projets exportés contrairement aux autres formats." #: doc/classes/ProjectSettings.xml msgid "" "Sets the specified property's initial value. This is the value the property " "reverts to." msgstr "" +"Définit la valeur initiale de la propriété spécifiée. C'est cette valeur qui " +"sera rétablie pour cette propriété." #: doc/classes/ProjectSettings.xml msgid "" "Sets the order of a configuration value (influences when saved to the config " "file)." msgstr "" +"Définit l'ordre d'une valeur de configuration (qui a une influence quand " +"sauvegardée dans le fichier de configuration)." #: doc/classes/ProjectSettings.xml msgid "" @@ -58313,6 +59664,14 @@ msgid "" "This can also be used to erase custom project settings. To do this change " "the setting value to [code]null[/code]." msgstr "" +"Définit la valeur d'un réglage.\n" +"[b]Exemple :[/b]\n" +"[codeblock]\n" +"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" +"/[codeblock]\n" +"Cela peut également être utilisé pour effacer les paramètres de projet " +"personnalisés. Pour ce faire, utilisez la valeur [code]null[/code] pour le " +"réglage." #: doc/classes/ProjectSettings.xml msgid "" @@ -58337,6 +59696,9 @@ msgid "" "(preserving the aspect ratio) when the engine starts. If [code]false[/code], " "the engine will leave it at the default pixel size." msgstr "" +"Si [code]true[/code], étire l'image au lancement du jeu suivant la taille de " +"la fenêtre (et préserve le ratio). Si [code]false[/code], l'image sera " +"affichée par défaut suivant sa taille en pixels." #: doc/classes/ProjectSettings.xml msgid "" @@ -58345,6 +59707,10 @@ msgid "" "[b]Note:[/b] Only effective if [member application/boot_splash/show_image] " "is [code]true[/code]." msgstr "" +"Le chemin vers une image utilisée au lancement du jeu. Si vide, l'image avec " +"le logo de Godot sera affichée à la place.\n" +"[b]Note :[/b] Ne fonctionne que si [member application/boot_splash/" +"show_image] est [code]true[/code]." #: doc/classes/ProjectSettings.xml msgid "" @@ -58353,6 +59719,10 @@ msgid "" "displays the plain color specified in [member application/boot_splash/" "bg_color]." msgstr "" +"Si [code]true[/code], affiche l'image spécifiée dans [member application/" +"boot_splash/image] lorsque le moteur démarre. Si [code]false[/code], affiche " +"seulement la couleur spécifiée dans [member application/boot_splash/" +"bg_color]." #: doc/classes/ProjectSettings.xml msgid "" @@ -58360,6 +59730,10 @@ msgid "" "(recommended for high-resolution artwork). If [code]false[/code], uses " "nearest-neighbor interpolation (recommended for pixel art)." msgstr "" +"Si [code]true[/code], applique le filtrage linéaire pour l'étirement de " +"l'image (recommandé pour les images à haute résolution.) Si " +"[code]false[/code], utilise l'interpolation la plus proche (recommandée pour " +"le pixel-art)." #: doc/classes/ProjectSettings.xml msgid "" @@ -58373,24 +59747,41 @@ msgid "" "The [member application/config/use_custom_user_dir] setting must be enabled " "for this to take effect." msgstr "" +"Ce dossier utilisateur est utilisé pour stocker des données persistantes (le " +"système de fichiers [code]user://[/code]). Si laissé vide, " +"[code]user://[/code] va pointer vers un dossier spécifique au projet suivant " +"la configuration de Godot (voir [method OS.get_user_data_dir]). Si un nom de " +"dossier personnalisé est défini, ce nom sera utilisé à la place, puis ajouté " +"au dossier de données utilisateur spécifique au système (le même dossier " +"parent que celui configuration Godot documenté dans [method OS." +"get_user_data_dir]).\n" +"Le paramètre [member application/config/use_custom_user_dir] doit être actif " +"pour que cela fonctionne." #: doc/classes/ProjectSettings.xml msgid "" "The project's description, displayed as a tooltip in the Project Manager " "when hovering the project." msgstr "" +"La description du projet, affichée en tant qu'infobulle dans le Gestionnaire " +"de projet quand le projet est survolé." #: doc/classes/ProjectSettings.xml msgid "" "Icon used for the project, set when project loads. Exporters will also use " "this icon when possible." msgstr "" +"L'icône utilisée pour le projet, défini au chargement du projet. Les " +"exportateurs utiliseront également cette icône si possible." #: doc/classes/ProjectSettings.xml msgid "" "Icon set in [code].icns[/code] format used on macOS to set the game's icon. " "This is done automatically on start by calling [method OS.set_native_icon]." msgstr "" +"L'icône définit dans le format [code].icns[/code] utilisé sur macOS pour " +"définir l'icône du jeu. Ceci est fait automatiquement au lancement en " +"appelant [method OS.set_native_icon]." #: doc/classes/ProjectSettings.xml msgid "" @@ -58439,12 +59830,28 @@ msgid "" "default can impact compatibility with some external tools or plugins which " "expect the default [code].import[/code] folder." msgstr "" +"Si [code]true[/code], le projet utilisera un dossier caché ([code]." +"import[/code]) pour stocker des données spécifiques au projet (métadonnées, " +"cache des shaders, etc.)\n" +"Si [code]false[/code], un dossier non caché ([code]import[/code]) sera " +"utilisé à la place.\n" +"[b]Note :[/b] Vous devez redémarrer l'application après avoir modifié ce " +"réglage.\n" +"[b]Note :[/b] Changer cette valeur peut aider sur les plateformes ou avec " +"des outils tiers où les modèles de dossier cachés ne sont pas autorisés. Il " +"suffit de modifier ce paramètre si vous savez que votre environnement " +"l'exige, car le changer par défaut peut impacter la compatibilité avec " +"certains outils ou greffons externes qui s'attendent à ce que le dossier par " +"défaut soit [code].import[/code]." #: doc/classes/ProjectSettings.xml msgid "" "Icon set in [code].ico[/code] format used on Windows to set the game's icon. " "This is done automatically on start by calling [method OS.set_native_icon]." msgstr "" +"L'icône définit dans le format [code].ico[/code] utilisé sur Windows pour " +"définir l'icône du jeu. Ceci est fait automatiquement au lancement en " +"appelant [method OS.set_native_icon]." #: doc/classes/ProjectSettings.xml msgid "" @@ -58674,11 +60081,10 @@ msgstr "" "ne généreront pas d'avertissements." #: doc/classes/ProjectSettings.xml -#, fuzzy msgid "" "If [code]true[/code], enables warnings when the type of the default value " "set to an exported variable is different than the specified export type." -msgstr "Si [code]true[/code], le filtrage est activé." +msgstr "" #: doc/classes/ProjectSettings.xml msgid "" @@ -58830,17 +60236,14 @@ msgstr "" "qui n'est pas garantie d'exister dans la classe à la compilation." #: doc/classes/ProjectSettings.xml -#, fuzzy msgid "" "If [code]true[/code], enables warnings when a function parameter is unused." msgstr "" -"Si [code]true[/code], le mouvement linéaire à travers l’axe Z est limité." #: doc/classes/ProjectSettings.xml -#, fuzzy msgid "" "If [code]true[/code], enables warnings when a member variable is unused." -msgstr "Si [code]true[/code], le filtrage est activé." +msgstr "" #: doc/classes/ProjectSettings.xml msgid "If [code]true[/code], enables warnings when a signal is unused." @@ -58930,42 +60333,57 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "Maximum call stack in visual scripting, to avoid infinite recursion." msgstr "" +"Le nombre maximal de la pile d'appels dans le script visuel, pour éviter une " +"récursion infinie." #: doc/classes/ProjectSettings.xml msgid "" "Color of the contact points between collision shapes, visible when \"Visible " "Collision Shapes\" is enabled in the Debug menu." msgstr "" +"La couleur des points de contact entre les formes de collision, visible " +"lorsque \"Formes de collision visibles\" est activé dans le menu Débogage." #: doc/classes/ProjectSettings.xml msgid "" "Sets whether 2D physics will display collision outlines in game when " "\"Visible Collision Shapes\" is enabled in the Debug menu." msgstr "" +"Définit si la physique 2D affichera les contours de collision dans le jeu " +"lorsque \"Formes de collision visibles\" est activé dans le menu Débogage." #: doc/classes/ProjectSettings.xml msgid "" "Maximum number of contact points between collision shapes to display when " "\"Visible Collision Shapes\" is enabled in the Debug menu." msgstr "" +"Le nombre maximal de points de contact entre les formes de collision à " +"afficher lorsque \"Formes de collision visibles\" est activé dans le menu " +"Débogage." #: doc/classes/ProjectSettings.xml msgid "" "Color of the collision shapes, visible when \"Visible Collision Shapes\" is " "enabled in the Debug menu." msgstr "" +"La couleur des formes de collision, visible lorsque \"Formes de collision " +"visibles\" est activé dans le menu Débogage." #: doc/classes/ProjectSettings.xml msgid "" "Color of the disabled navigation geometry, visible when \"Visible " "Navigation\" is enabled in the Debug menu." msgstr "" +"La couleur de la géométrie de navigation désactivée, visible lorsque " +"\"Navigation visible\" est activée dans le menu Débogage." #: doc/classes/ProjectSettings.xml msgid "" "Color of the navigation geometry, visible when \"Visible Navigation\" is " "enabled in the Debug menu." msgstr "" +"La couleur de la géométrie de navigation, visible lorsque \"Navigation " +"visible\" est activée dans le menu Débogage." #: doc/classes/ProjectSettings.xml msgid "Custom image for the mouse cursor (limited to 256×256)." @@ -59162,18 +60580,25 @@ msgid "" "Load the previously opened VCS plugin when the editor starts up. This is set " "to [code]true[/code] whenever a new VCS plugin is initialized." msgstr "" +"Charge le greffon VCS précédemment ouvert dès que l'éditeur démarre. Ceci " +"est défini à [code]true[/code] chaque fois qu'un nouveau greffon VCS est " +"initialisé." #: doc/classes/ProjectSettings.xml msgid "" "Last loaded VCS plugin name. Used to autoload the plugin when the editor " "starts up." msgstr "" +"Le dernier nom de greffon VCS chargé. Utilisé pour recharger le greffon dès " +"que l'éditeur démarre." #: doc/classes/ProjectSettings.xml msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" +"La valeur par défaut pour [member ScrollContainer.scroll_deadzone], qui sera " +"utilisé pour tous les [ScrollContainer] à moins d'être surchargé." #: doc/classes/ProjectSettings.xml msgid "" @@ -59193,6 +60618,8 @@ msgid "" "If [code]true[/code], swaps OK and Cancel buttons in dialogs on Windows and " "UWP to follow interface conventions." msgstr "" +"Si [code]true[/code], échange des boutons OK et Annuler dans les dialogues " +"sur Windows et UWP pour suivre les conventions d'interface." #: doc/classes/ProjectSettings.xml msgid "" @@ -59205,6 +60632,8 @@ msgid "" "Path to a custom [Font] resource to use as default for all GUI elements of " "the project." msgstr "" +"Le chemin vers une [Font] personnalisée à utiliser par défaut pour tous les " +"éléments graphiques du projet." #: doc/classes/ProjectSettings.xml msgid "If [code]true[/code], makes sure the theme used works with HiDPI." @@ -59408,208 +60837,278 @@ msgid "" "If [code]true[/code], sends mouse input events when tapping or swiping on " "the touchscreen." msgstr "" +"Si [code]true[/code], envoie des événements d'entrée de la souris lorsque " +"vous tapez ou glissez sur l'écran tactile." #: doc/classes/ProjectSettings.xml msgid "" "If [code]true[/code], sends touch input events when clicking or dragging the " "mouse." msgstr "" +"Si [code]true[/code], envoie des événements d'entrée tactile lorsque vous " +"cliquez ou faites glisser la souris." #: doc/classes/ProjectSettings.xml msgid "Default delay for touch events. This only affects iOS devices." msgstr "" +"Un retard par défaut pour les événements tactiles. Cela n'affecte que les " +"appareils iOS." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 1. If left empty, the layer will " "display as \"Layer 1\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 1. Si vide, le " +"calque s'affichera comme \"Calque 1\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 10. If left empty, the layer will " "display as \"Layer 10\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 10. Si vide, la " +"calque s'affichera comme \"Calque 10\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 11. If left empty, the layer will " "display as \"Layer 11\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 11. Si vide, la " +"calque s'affichera comme \"Calque 11\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 12. If left empty, the layer will " "display as \"Layer 12\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 12. Si vide, la " +"calque s'affichera comme \"Calque 12\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 13. If left empty, the layer will " "display as \"Layer 13\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 13. Si vide, la " +"calque s'affichera comme \"Calque 13\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 14. If left empty, the layer will " "display as \"Layer 14\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 14. Si vide, la " +"calque s'affichera comme \"Calque 14\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 15. If left empty, the layer will " "display as \"Layer 15\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 15. Si vide, la " +"calque s'affichera comme \"Calque 15\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 16. If left empty, the layer will " "display as \"Layer 16\"." msgstr "" +"Nom facultatif pour la calque de navigation 2D numéro 16. Si vide, la calque " +"s'affichera comme \"Calque 16\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 17. If left empty, the layer will " "display as \"Layer 17\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 17. Si vide, la " +"calque s'affichera comme \"Calque 17\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 18. If left empty, the layer will " "display as \"Layer 18\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 18. Si vide, la " +"calque s'affichera comme \"Calque 18\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 19. If left empty, the layer will " "display as \"Layer 19\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 19. Si vide, la " +"calque s'affichera comme \"Calque 19\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 2. If left empty, the layer will " "display as \"Layer 2\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 2. Si vide, la " +"calque affichera comme « calque 2 »." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 20. If left empty, the layer will " "display as \"Layer 20\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 20. Si vide, la " +"calque s'affichera comme \"Calque 20\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 21. If left empty, the layer will " "display as \"Layer 21\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 21. Si vide, la " +"calque s'affichera comme \"Calque 21\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 22. If left empty, the layer will " "display as \"Layer 22\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 22. Si vide, la " +"calque s'affichera comme \"Calque 22\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 23. If left empty, the layer will " "display as \"Layer 23\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 23. Si vide, la " +"calque s'affichera comme \"Calque 23\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 24. If left empty, the layer will " "display as \"Layer 24\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 24. Si vide, la " +"calque s'affichera comme \"Calque 24\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 25. If left empty, the layer will " "display as \"Layer 25\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 25. Si vide, la " +"calque s'affichera comme \"Calque 25\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 26. If left empty, the layer will " "display as \"Layer 26\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 26. Si vide, la " +"calque s'affichera comme \"Calque 26\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 27. If left empty, the layer will " "display as \"Layer 27\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 27. Si vide, la " +"calque s'affichera comme \"Calque 27\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 28. If left empty, the layer will " "display as \"Layer 28\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 28. Si vide, la " +"calque s'affichera comme \"Calque 28\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 29. If left empty, the layer will " "display as \"Layer 29\"." msgstr "" +"Nom facultatif pour la calque de navigation 2D numéro 29. Si vide, la calque " +"s'affichera comme \"Calque 29\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 3. If left empty, the layer will " "display as \"Layer 3\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 3. Si vide, la " +"calque s'affichera comme « calque 3 »." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 30. If left empty, the layer will " "display as \"Layer 30\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 30. Si vide, la " +"calque s'affichera comme \"Calque 30\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 31. If left empty, the layer will " "display as \"Layer 31\"." msgstr "" +"Nom facultatif pour la calque de navigation 2D numéro 31. Si vide, la calque " +"s'affichera comme \"Calque 31\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 32. If left empty, the layer will " "display as \"Layer 32\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 32. Si vide, la " +"calque s'affichera comme \"Calque 32\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 4. If left empty, the layer will " "display as \"Layer 4\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 4. Si vide, la " +"calque apparaîtra comme \"Calque 4\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 5. If left empty, the layer will " "display as \"Layer 5\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 5. Si vide, le " +"calque affichera comme \"Calque 5\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 6. If left empty, the layer will " "display as \"Layer 6\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 6. Si vide, la " +"calque apparaîtra comme \"Calque 6\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 7. If left empty, the layer will " "display as \"Layer 7\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 7. Si vide, la " +"calque s'affichera comme « calque 7 »." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 8. If left empty, the layer will " "display as \"Layer 8\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 8. Si vide, la " +"calque s'affichera comme \"Calque 8\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 2D navigation layer 9. If left empty, the layer will " "display as \"Layer 9\"." msgstr "" +"Le nom optionnel pour la calque de navigation 2D numéro 9. Si vide, la " +"calque s'affichera comme \"Calque 9\"." #: doc/classes/ProjectSettings.xml msgid "Optional name for the 2D physics layer 1." @@ -59824,192 +61323,256 @@ msgid "" "Optional name for the 3D navigation layer 1. If left empty, the layer will " "display as \"Layer 1\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 1. Si vide, le " +"calque s'affichera comme \"Calque 1\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 10. If left empty, the layer will " "display as \"Layer 10\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 10. Si vide, la " +"calque s'affichera comme \"Calque 10\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 11. If left empty, the layer will " "display as \"Layer 11\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 11. Si vide, la " +"calque s'affichera comme \"Calque 11\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 12. If left empty, the layer will " "display as \"Layer 12\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 12. Si vide, la " +"calque s'affichera comme \"Calque 12\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 13. If left empty, the layer will " "display as \"Layer 13\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 13. Si vide, la " +"calque s'affichera comme \"Calque 13\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 14. If left empty, the layer will " "display as \"Layer 14\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 14. Si vide, la " +"calque s'affichera comme \"Calque 14\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 15. If left empty, the layer will " "display as \"Layer 15\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 15. Si vide, la " +"calque s'affichera comme \"Calque 15\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 16. If left empty, the layer will " "display as \"Layer 16\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 16. Si vide, la " +"calque s'affichera comme \"Calque 16\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 17. If left empty, the layer will " "display as \"Layer 17\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 17. Si vide, la " +"calque s'affichera comme \"Calque 17\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 18. If left empty, the layer will " "display as \"Layer 18\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 18. Si vide, la " +"calque s'affichera comme \"Calque 18\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 19. If left empty, the layer will " "display as \"Layer 19\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 19. Si vide, la " +"calque s'affichera comme \"Calque 19\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 2. If left empty, the layer will " "display as \"Layer 2\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 2. Si vide, la " +"calque affichera comme « calque 2 »." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 20. If left empty, the layer will " "display as \"Layer 20\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 20. Si vide, la " +"calque s'affichera comme \"Calque 20\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 21. If left empty, the layer will " "display as \"Layer 21\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 21. Si vide, la " +"calque s'affichera comme \"Calque 21\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 22. If left empty, the layer will " "display as \"Layer 22\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 22. Si vide, la " +"calque s'affichera comme \"Calque 22\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 23. If left empty, the layer will " "display as \"Layer 23\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 23. Si vide, la " +"calque s'affichera comme \"Calque 23\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 24. If left empty, the layer will " "display as \"Layer 24\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 24. Si vide, la " +"calque s'affichera comme \"Calque 24\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 25. If left empty, the layer will " "display as \"Layer 25\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 25. Si vide, la " +"calque s'affichera comme \"Calque 25\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 26. If left empty, the layer will " "display as \"Layer 26\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 26. Si vide, la " +"calque s'affichera comme \"Calque 26\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 27. If left empty, the layer will " "display as \"Layer 27\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 27. Si vide, la " +"calque s'affichera comme \"Calque 27\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 28. If left empty, the layer will " "display as \"Layer 28\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 28. Si vide, la " +"calque s'affichera comme \"Calque 28\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 29. If left empty, the layer will " "display as \"Layer 29\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 29. Si vide, la " +"calque s'affichera comme \"Calque 29\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 3. If left empty, the layer will " "display as \"Layer 3\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 3. Si vide, la " +"calque s'affichera comme « calque 3 »." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 30. If left empty, the layer will " "display as \"Layer 30\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 30. Si vide, la " +"calque s'affichera comme \"Calque 30\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 31. If left empty, the layer will " "display as \"Layer 31\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 31. Si vide, la " +"calque s'affichera comme \"Calque 31\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 32. If left empty, the layer will " "display as \"Layer 32\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 32. Si vide, la " +"calque s'affichera comme \"Calque 32\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 4. If left empty, the layer will " "display as \"Layer 4\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 4. Si vide, la " +"calque apparaîtra comme \"Calque 4\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 5. If left empty, the layer will " "display as \"Layer 5\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 5. Si vide, le " +"calque affichera comme \"Calque 5\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 6. If left empty, the layer will " "display as \"Layer 6\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 6. Si vide, la " +"calque apparaîtra comme \"Calque 6\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 7. If left empty, the layer will " "display as \"Layer 7\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 7. Si vide, la " +"calque s'affichera comme « calque 7 »." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 8. If left empty, the layer will " "display as \"Layer 8\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 8. Si vide, la " +"calque s'affichera comme \"Calque 8\"." #: doc/classes/ProjectSettings.xml msgid "" "Optional name for the 3D navigation layer 9. If left empty, the layer will " "display as \"Layer 9\"." msgstr "" +"Le nom optionnel pour la calque de navigation 3D numéro 9. Si vide, la " +"calque s'affichera comme \"Calque 9\"." #: doc/classes/ProjectSettings.xml msgid "Optional name for the 3D physics layer 1." @@ -60224,6 +61787,8 @@ msgid "" "The locale to fall back to if a translation isn't available in a given " "language. If left empty, [code]en[/code] (English) will be used." msgstr "" +"Le langage de repli si une traduction n'est pas disponible dans une langue " +"donnée. Si laissé vide, [code]en[/code] (anglais) sera utilisé." #: doc/classes/ProjectSettings.xml msgid "" @@ -60242,6 +61807,9 @@ msgid "" "Desktop override for [member logging/file_logging/enable_file_logging], as " "log files are not readily accessible on mobile/Web platforms." msgstr "" +"Le surcharge du bureau pour [member logging/file_logging/enable_file_logging]" +", car les fichiers de journaux ne sont pas facilement accessibles sur les " +"plateformes mobiles et web." #: doc/classes/ProjectSettings.xml msgid "" @@ -61042,6 +62610,12 @@ msgid "" "[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/" "shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]." msgstr "" +"La valeur par défaut est une surcharge très conservatrice pour [member " +"rendering/gles3/shaders/max_simultaneous_compiles].\n" +"Selon les appareils spécifiques que vous ciblez, vous pouvez vouloir " +"l'augmenter.\n" +"[b]Note :[/b] Ce paramètre n'est utile que si [nomm rendering/gles3/shaders/" +"shader_compilation_mode] n'est [b]pas[/b] à [code]Synchrone[/code]." #: doc/classes/ProjectSettings.xml msgid "" @@ -61052,6 +62626,12 @@ msgid "" "[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/" "shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]." msgstr "" +"La valeur par défaut est une surcharge très conservatrice pour [member " +"rendering/gles3/shaders/max_simultaneous_compiles].\n" +"Selon les navigateurs spécifiques que vous ciblez, vous pouvez vouloir " +"l'augmenter.\n" +"[b]Note :[/b] Ce paramètre n'est utile que si [nomm rendering/gles3/shaders/" +"shader_compilation_mode] n'est [b]pas[/b] à [code]Synchrone[/code]." #: doc/classes/ProjectSettings.xml msgid "" @@ -61061,6 +62641,11 @@ msgid "" "[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/" "shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]." msgstr "" +"La taille maximale, en mégaoctets, que le cache de ubershader peut " +"atteindre. Au démarrage, les entrées les moins récemment utilisées seront " +"supprimées jusqu'à ce que la taille totale soit dans les limites.\n" +"[b]Note :[/b] Ce paramètre n'est utile que si [nomm rendering/gles3/shaders/" +"shader_compilation_mode] est défini à [code]Synchrone + Cache[/code]." #: doc/classes/ProjectSettings.xml msgid "" @@ -61070,6 +62655,11 @@ msgid "" "[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/" "shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]." msgstr "" +"Une surcharge pour [member rendering/gles3/shaders/shader_cache_size_mb], de " +"sorte qu'une taille maximale plus petite peut être configurée pour les " +"plates-formes mobiles, où l'espace de stockage est plus limité.\n" +"[b]Note :[/b] Ce paramètre n'est utile que si [nomm rendering/gles3/shaders/" +"shader_compilation_mode] est défini à [code]Synchrone + Cache[/code]." #: doc/classes/ProjectSettings.xml msgid "" @@ -61081,6 +62671,13 @@ msgid "" "[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/" "shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]." msgstr "" +"Une surcharge pour [member rendering/gles3/shaders/shader_cache_size_mb], de " +"sorte qu'une taille maximale plus petite peut être configurée pour les " +"plateformes web, où l'espace de stockage est plus limité.\n" +"[b]Note :[/b] Actuellement, le caisson d'ombrage n'est généralement pas " +"disponible sur les plateformes Web.\n" +"[b]Note :[/b] Ce paramètre n'est utile que si [nomm rendering/gles3/shaders/" +"shader_compilation_mode] est défini à [code]Synchrone + Cache[/code]." #: doc/classes/ProjectSettings.xml msgid "" @@ -61130,24 +62727,33 @@ msgid "" "Max buffer size for blend shapes. Any blend shape bigger than this will not " "work." msgstr "" +"La capacité maximale de la mémoire tampon pour les formes de mélange. Toute " +"forme de mélange plus grande que cela ne fonctionnera pas." #: doc/classes/ProjectSettings.xml msgid "" "Max buffer size for drawing polygons. Any polygon bigger than this will not " "work." msgstr "" +"La capacity maximale de la mémoire tampon pour dessiner des polygones. Tout " +"polygone plus grand que cela ne fonctionnera pas." #: doc/classes/ProjectSettings.xml msgid "" "Max index buffer size for drawing polygons. Any polygon bigger than this " "will not work." msgstr "" +"La capacity maximale de la mémoire tampon pour le dessin des polygones. Tout " +"polygone plus grand que cela ne fonctionnera pas." #: doc/classes/ProjectSettings.xml msgid "" "Max buffer size for drawing immediate objects (ImmediateGeometry nodes). " "Nodes using more than this size will not work." msgstr "" +"La capacity maximale de la mémoire tampon pour le dessin d'objets immédiats (" +"les nœuds ImmediateGeometry). Les nœuds utilisant plus que cette taille ne " +"fonctionneront pas." #: doc/classes/ProjectSettings.xml msgid "" @@ -61193,13 +62799,10 @@ msgid "" msgstr "" #: doc/classes/ProjectSettings.xml -#, fuzzy msgid "" "If [code]true[/code], the texture importer will import lossless textures " "using the PNG format. Otherwise, it will default to using WebP." msgstr "" -"Si [code]true[/code], la [SpinBox] sera modifiable. Sinon, elle sera en " -"lecture seule." #: doc/classes/ProjectSettings.xml msgid "" @@ -61209,6 +62812,12 @@ msgid "" "Note that compression levels above 6 are very slow and offer very little " "savings." msgstr "" +"Le niveau de compression par défaut pour le format WebP sans perte. Des " +"niveaux plus élevés entraînent des fichiers plus petits mais une plus lente " +"vitesse de compression. La vitesse de décompression ne dépend pas du niveau " +"de compression. Les valeurs supportées vont de 0 à 9. Notez que les niveaux " +"de compression supérieurs à 6 sont très lents et offrent une très petite " +"réduction du poids du fichier." #: doc/classes/ProjectSettings.xml msgid "" @@ -61217,6 +62826,11 @@ msgid "" "attributes data. Recommended to be enabled if targeting mobile devices. " "Requires manual reimport of meshes after toggling." msgstr "" +"À l'importation, les données des sommets de maillage seront divisées en deux " +"flux dans une seule mémoire tampon pour les sommets, l'une pour les données " +"de position et l'autre pour les données d'attributs. Recommandé si vous " +"ciblez des appareils mobiles. Nécessite de réimporter manuellement toutes " +"les meshes après l'activation." #: doc/classes/ProjectSettings.xml msgid "" @@ -61228,6 +62842,14 @@ msgid "" "A greater number of polygons can potentially cull more objects, however the " "cost of culling calculations scales with the number of occluders." msgstr "" +"Détermine le nombre maximal d'occulteurs de polygones qui seront utilisés à " +"tout moment.\n" +"Même si vous pouvez avoir de nombreux occulteurs dans une même scène, à " +"chaque trame, le système choisira parmi ces plus pertinents basés sur une " +"métrique de l'espace à l'écran, afin de donner la meilleure performance " +"globale.\n" +"Un plus grand nombre de polygones peut potentiellement masquer plus " +"d'objets, cependant les performances baissent avec le nombre d'occulteurs." #: doc/classes/ProjectSettings.xml msgid "" @@ -61237,6 +62859,12 @@ msgid "" "choose from these the most relevant based on a screen space metric, in order " "to give the best overall performance." msgstr "" +"Détermine le nombre maximal d'occulteurs de sphère qui seront utilisés à " +"tout moment.\n" +"Même si vous pouvez avoir de nombreux occulteurs dans une même scène, à " +"chaque trame, le système choisira parmi ces plus pertinents basés sur une " +"métrique de l'espace à l'écran, afin de donner la meilleure performance " +"globale." #: doc/classes/ProjectSettings.xml msgid "" @@ -61247,6 +62875,12 @@ msgid "" "It will flip named portal meshes (i.e. [code]-portal[/code]) on the initial " "conversion to [Portal] nodes." msgstr "" +"La convention par défaut est de pointer vers l'extérieur (la face vers " +"l'extérieur) de la salle source.\n" +"Si vous construisez accidentellement votre niveau avec des portails faisant " +"face de la mauvaise manière, ce réglage peut corriger le problème.\n" +"Cela va inverser le maillages nommés de portail (c'est-à-dire finissant par " +"[code]-portal[/code]) pour les nœuds [Portal]." #: doc/classes/ProjectSettings.xml msgid "" @@ -61257,14 +62891,11 @@ msgstr "" "[b]Note :[/b] Cela sera automatiquement désactivé dans les exports." #: doc/classes/ProjectSettings.xml -#, fuzzy msgid "" "If [code]true[/code], gameplay callbacks will be sent as [code]signals[/" "code]. If [code]false[/code], they will be sent as [code]notifications[/" "code]." msgstr "" -"Si [code]true[/code], l’état de la clé est pressé. Si [code]false[/code], " -"l’état de la clé est libéré." #: doc/classes/ProjectSettings.xml msgid "" @@ -61280,6 +62911,8 @@ msgid "" "Show logs during PVS generation.\n" "[b]Note:[/b] This will automatically be disabled in exports." msgstr "" +"Afficher les journaux pendant la génération du PVS.\n" +"[b]Note :[/b] Cela sera automatiquement désactivé dans les exportations." #: doc/classes/ProjectSettings.xml msgid "" @@ -61614,6 +63247,9 @@ msgid "" "Lower-end override for [member rendering/quality/shadows/filter_mode] on " "mobile devices, due to performance concerns or driver support." msgstr "" +"Surcharge pour les appareils bas de gamme pour [le rendu de membre/qualité/" +"shadows/filter_mode] sur les appareils mobiles, en raison de performance " +"plus faibles ou du support des pilotes." #: doc/classes/ProjectSettings.xml msgid "" @@ -61774,6 +63410,8 @@ msgid "" "Objects can use this signal to restrict reading of settings only to " "situations where a change has been made." msgstr "" +"Les objets peuvent utiliser ce signal pour restreindre leur lecture aux " +"seuls paramètres modifiés." #: doc/classes/PropertyTweener.xml msgid "Interpolates an [Object]'s property over time." @@ -61787,6 +63425,11 @@ msgid "" "to create [PropertyTweener]. Any [PropertyTweener] created manually will not " "function correctly." msgstr "" +"[PropertyTweener] est utilisé pour interpoler une propriété dans un objet. " +"Voir [method SceneTreeTween.tween_property] pour plus d'informations.\n" +"[b]Note :[/b] [method SceneTreeTween.tween_property] est le seul moyen " +"correct de créer un [PropertyTweener]. Les [PropertyTweener] créés " +"manuellement ne fonctionneront pas correctement." #: doc/classes/PropertyTweener.xml msgid "" @@ -61798,6 +63441,13 @@ msgid "" "as_relative() #the node will move by 100 pixels to the right\n" "[/codeblock]" msgstr "" +"Quand appellé, la valeur finale sera utilisée comme valeur relative. Par " +"exemple :\n" +"[codeblock]\n" +"var tween = get_tree().create_tween()\n" +"tween.tween_property(self, \"position\", Vector2.RIGHT * 100, 1)." +"as_relative() # Le nœud sera déplacé de 100 pixels sur la droite\n" +"/[codeblock]" #: doc/classes/PropertyTweener.xml msgid "" @@ -61809,6 +63459,14 @@ msgid "" "(200, 100)\n" "[/codeblock]" msgstr "" +"Définit une valeur initiale personnalisée pour le [PropertyTweener]. Par " +"exemple :\n" +"[codeblock]\n" +"var tween = get_tree().create_tween()\n" +"tween.tween_property(self, \"position\", Vector2(200, 100), 1).from(Vector2(" +"100, 100) # Ça déplacera le nœud de la position (100, 100) jusqu'à (200, 100)" +"\n" +"/[codeblock]" #: doc/classes/PropertyTweener.xml msgid "" @@ -61823,6 +63481,16 @@ msgid "" "from_current()\n" "[/codeblock]" msgstr "" +"Fait que ce [PropertyTweener] utilisera la valeur de propriété actuelle " +"(c'est-à-dire au moment de créer ce [PropertyTweener]) comme point de " +"départ. Ceci est pareil que [method from] avec la valeur actuelle. Ces deux " +"appels sont identiques :\n" +"[codeblock]\n" +"tween.tween_property(self, \"position\", Vector2(200, 100), 1).from(position)" +"\n" +"tween.tween_property(self, \"position\", Vector2(200, 100), 1).from_current()" +"\n" +"/[codeblock]" #: doc/classes/PropertyTweener.xml msgid "" @@ -61833,9 +63501,8 @@ msgstr "" "interpolation. Par défaut, il n'y a pas de délai." #: doc/classes/ProximityGroup.xml -#, fuzzy msgid "General-purpose 3D proximity detection node." -msgstr "Nœud de détection de proximité pour usage général." +msgstr "Un nœud de détection de proximité 3D pour un usage général." #: doc/classes/ProximityGroup.xml msgid "" @@ -61907,11 +63574,16 @@ msgid "" "If the [member dispatch_mode] is set to [constant MODE_PROXY] (the default), " "all calls are delegated to their respective parent [Node]." msgstr "" +"Appelle la méthode et les paramètres donnés à tous les [ProximityGroup] qui " +"s'intersectent.\n" +"Si le [member dispatch_mode] est [constant MODE_PROXY] (par défaut), tous " +"les appels sont délégués à leur parent [Node] respectif." #: doc/classes/ProximityGroup.xml msgid "" "Specifies which node gets contacted on a call of method [method broadcast]." msgstr "" +"Spécifie quel nœud est contacté sur un appel de méthode [method broadcast]." #: doc/classes/ProximityGroup.xml msgid "" @@ -61921,6 +63593,11 @@ msgid "" "proximity checks at the cost of performance, since more groups will be " "created." msgstr "" +"La taille de l'espace en unités 3D. Cela définit également la quantité de " +"coordonnées requises pour calculer si deux nœuds [ProximityGroup] sont en " +"intersection ou non. Des valeurs plus petites de [member grid_radius] " +"peuvent être utilisées pour des vérifications de proximité plus précises " +"mais avec de moins bonnes performances, car plus de groupes seront créés." #: doc/classes/ProximityGroup.xml msgid "" @@ -61947,13 +63624,15 @@ msgstr "" #: doc/classes/ProximityGroup.xml msgid "This [ProximityGroup]'s parent will be target of [method broadcast]." -msgstr "" +msgstr "Le parent de ce [ProximityGroup] sera la cible de [method broadcast]." #: doc/classes/ProximityGroup.xml msgid "" "This [ProximityGroup] will emit the [signal broadcast] [i]signal[/i] when " "calling the [method broadcast] [i]method[/i]." msgstr "" +"Ce [ProximityGroup] émettra le [i]signal[/i] [signal broadcast] lors de " +"l'appel de la [i]méthode[/i] [method broadcast]." #: doc/classes/QuadMesh.xml msgid "Class representing a square mesh." @@ -62016,9 +63695,8 @@ msgstr "" "spécifié. L'axe doit être un vecteur normalisé." #: doc/classes/Quat.xml -#, fuzzy msgid "Constructs a quaternion defined by the given values." -msgstr "Construit une nouvelle chaîne de caractères à partir du [Plane] donné." +msgstr "" #: doc/classes/Quat.xml msgid "" @@ -62036,6 +63714,9 @@ msgid "" "code], this vector, [code]b[/code], and [code]post_b[/code], by the given " "amount [code]weight[/code]." msgstr "" +"Exécute une interpolation sphérique cubique entre les quaternions " +"[code]pre_a[/code], ce vecteur, [code]b[/code], et [code]post_b[/code], par " +"la quantité [code]weight[/code] spécifiée." #: doc/classes/Quat.xml msgid "Returns the dot product of two quaternions." @@ -62048,6 +63729,10 @@ msgid "" "quaternion. Returned vector contains the rotation angles in the format (X " "angle, Y angle, Z angle)." msgstr "" +"Retourne les angles d'Euler (selon la convention YXZ : lors de la " +"décomposition, d'abord Z, puis X, et enfin Y) correspondant à la rotation " +"représentée par un quaternion d'unité. Le vecteur retourné contient les " +"angles de rotation dans le format (angle X, angle Y, angle Z)." #: doc/classes/Quat.xml msgid "Returns the inverse of the quaternion." @@ -62084,6 +63769,8 @@ msgid "" "Sets the quaternion to a rotation which rotates around axis by the specified " "angle, in radians. The axis must be a normalized vector." msgstr "" +"Définit le quaternion avec une rotation qui tourne autour de l'axe par " +"l'angle spécifié, en radians. L'axe doit être un vecteur normalisé." #: doc/classes/Quat.xml msgid "" @@ -62091,6 +63778,9 @@ msgid "" "convention: when decomposing, first Z, then X, and Y last), given in the " "vector format as (X angle, Y angle, Z angle)." msgstr "" +"Définit le quaternion avec une rotation spécifiée par les angles d'Euler (" +"selon la convention YXZ : lors de la décomposition, d'abord Z, puis X, et " +"enfin Y), donnée dans le format vectoriel comme (angle X, angle Y, angle Z)." #: doc/classes/Quat.xml msgid "" @@ -62098,6 +63788,10 @@ msgid "" "quaternion and [code]to[/code] by amount [code]weight[/code].\n" "[b]Note:[/b] Both quaternions must be normalized." msgstr "" +"Retourne le résultat de l'interpolation linéaire sphérique entre ce " +"quaternion et [code]to[/code] par la quantité [code]weight[/code] spécifiée." +"\n" +"[b]Note :[/b] Les deux quaternions doivent être normalisés." #: doc/classes/Quat.xml msgid "" @@ -62105,6 +63799,9 @@ msgid "" "quaternion and [code]to[/code] by amount [code]weight[/code], but without " "checking if the rotation path is not bigger than 90 degrees." msgstr "" +"Retourne le résultat de l'interpolation linéaire sphérique entre ce " +"quaternion et [code]to[/code] par la quantité [code]weight[/code] spécifiée, " +"mais sans vérifier si la rotation n'est pas supérieure à 90 degrés." #: doc/classes/Quat.xml msgid "Returns a vector transformed (multiplied) by this quaternion." @@ -62148,6 +63845,9 @@ msgid "" "[Basis] matrix. If a vector is transformed by an identity quaternion, it " "will not change." msgstr "" +"La quaternion d'identité, sans rotation. Équivalent à la matrice [Basis] " +"d'identité. Si un vecteur est transformé par un quaternion d'identité, il ne " +"changera pas." #: doc/classes/RandomNumberGenerator.xml msgid "A class for generating pseudo-random numbers." @@ -62313,22 +64013,21 @@ msgstr "" "avec une valeur personnalisée, utilisez plutôt [member seed]." #: doc/classes/Range.xml -#, fuzzy msgid "Abstract base class for range-based controls." -msgstr "Classe de base abstraite pour les contrôles basés sur la portée." +msgstr "Une classe de base abstraite pour les contrôles basés sur la portée." #: doc/classes/Range.xml -#, fuzzy msgid "" "Range is a base class for [Control] nodes that change a floating-point " "[member value] between a [member min_value] and [member max_value], using a " "configured [member step] and [member page] size. See e.g. [ScrollBar] and " "[Slider] for examples of higher level nodes using Range." msgstr "" -"Range est une classe de base des nœuds [Control] qui change une [code]value[/" -"code] flottante entre le [code]minimum[/code] et le [code]maximum[/code], " -"par étape [code]step[/code] et par [code]page[/code], par exemple un " -"[ScrollBar]." +"Range est une classe de base des nœuds [Control] qui change une " +"[code]value[/code] flottante entre le [code]minimum[/code] et le " +"[code]maximum[/code], par étape [code]step[/code] et par [code]page[/code], " +"par exemple un [ScrollBar]. Voir [ScrollBar] et [Slider] pour des exemples " +"de nœuds de haut niveau utilisant des Range." #: doc/classes/Range.xml msgid "" @@ -62339,7 +64038,7 @@ msgstr "" #: doc/classes/Range.xml msgid "Stops the [Range] from sharing its member variables with any other." -msgstr "" +msgstr "Arrête le [Range] de partager ses variables membres avec les autres." #: doc/classes/Range.xml msgid "" @@ -62360,6 +64059,9 @@ msgid "" "If [code]true[/code], and [code]min_value[/code] is greater than 0, " "[code]value[/code] will be represented exponentially rather than linearly." msgstr "" +"Si [code]true[/code], et [code]min_value[/code] est supérieur à 0, " +"[code]value[/code] sera représenté de façon exponentielle plutôt que " +"linéaire." #: doc/classes/Range.xml msgid "" @@ -62383,6 +64085,9 @@ msgid "" "multiplied by [code]page[/code] over the difference between [code]min_value[/" "code] and [code]max_value[/code]." msgstr "" +"La taille de la page. Utilisé principalement pour [ScrollBar]. La longueur " +"de la barre de défilement est multipliée par [code]page[/code] divisé par la " +"différence entre [code]min_value[/code] et [code]max_value[/code]." #: doc/classes/Range.xml msgid "The value mapped between 0 and 1." @@ -62487,12 +64192,17 @@ msgid "" "[code]0[/code] if no object is intersecting the ray (i.e. [method " "is_colliding] returns [code]false[/code])." msgstr "" +"Retourne l'identifiant de forme du premier objet que le rayon intersecte, ou " +"[code]0[/code] si aucun objet n'intersecte le rayon (c'est-à-dire [method " +"is_colliding] renvoie [code]false[/code])." #: doc/classes/RayCast.xml msgid "" "Returns [code]true[/code] if the bit index passed is turned on.\n" "[b]Note:[/b] Bit indices range from 0-19." msgstr "" +"Retourne [code]true[/code] si l'index de bit est activé.\n" +"[b]Note :[/b] Les indices de bit vont de 0 à 19." #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -62504,6 +64214,10 @@ msgid "" "Returns the collision point at which the ray intersects the closest object.\n" "[b]Note:[/b] This point is in the [b]global[/b] coordinate system." msgstr "" +"Retourne le point de collision où le rayon intersecte l'objet le plus proche." +"\n" +"[b]Note :[/b] Ce point se trouve dans le système de coordonnées " +"[b]global[/b]." #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -62534,21 +64248,24 @@ msgid "" "Sets the bit index passed to the [code]value[/code] passed.\n" "[b]Note:[/b] Bit indexes range from 0-19." msgstr "" +"Définit l'index de bit transmis à la [code]valeur[/code] passée.\n" +"[b]Note :[/b] Les index de bit vont de 0-19." #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" "The ray's destination point, relative to the RayCast's [code]position[/code]." msgstr "" +"Le point de destination du rayon, par rapport à la [code]position[/code] du " +"RayCast." #: doc/classes/RayCast.xml -#, fuzzy msgid "If [code]true[/code], collision with [Area]s will be reported." -msgstr "Si [code]true[/code], les collisions seront signalées." +msgstr "Si [code]true[/code], les collisions avec les [Area] seront signalées." #: doc/classes/RayCast.xml -#, fuzzy msgid "If [code]true[/code], collision with [PhysicsBody]s will be reported." -msgstr "Si [code]true[/code], les collisions seront signalées." +msgstr "" +"Si [code]true[/code], les collisions avec les [PhysicsBody] seront signalées." #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -62581,11 +64298,12 @@ msgid "If [code]true[/code], collisions will be reported." msgstr "Si [code]true[/code], les collisions seront signalées." #: doc/classes/RayCast.xml -#, fuzzy msgid "" "If [code]true[/code], collisions will be ignored for this RayCast's " "immediate parent." -msgstr "Si [code]true[/code], les collisions seront signalées." +msgstr "" +"Si [code]true[/code], les collisions seront ignorées avec le parent direct " +"de ce RayCast." #: doc/classes/RayCast2D.xml msgid "" @@ -62611,6 +64329,8 @@ msgid "" "Sets or clears individual bits on the collision mask. This makes selecting " "the areas scanned easier." msgstr "" +"Définit ou efface des bits individuels sur le masque de collision. Cela " +"facilite le choix des aires scannées." #: doc/classes/RayCast2D.xml msgid "If [code]true[/code], collision with [Area2D]s will be reported." @@ -62642,6 +64362,10 @@ msgid "" "itself from whatever is touching its far endpoint. It's often useful for " "characters." msgstr "" +"Une forme en rayon pour les collisions en 3D, qui peuvt être placée dans un " +"[PhysicsBody] ou une [Area]. Un rayon n'est pas vraiment un corps de " +"collision ; il tente plutôt de se séparer de ce qui touche son point " +"d'extrémité lointain. Il est souvent utile pour les caractères." #: doc/classes/RayShape.xml doc/classes/RayShape2D.xml msgid "The ray's length." @@ -62663,11 +64387,13 @@ msgid "" "it tries to separate itself from whatever is touching its far endpoint. It's " "often useful for characters." msgstr "" +"Une forme en rayon pour les collisions 2D. Un rayon n'est pas vraiment un " +"corps de collision ; il tente plutôt de se séparer de ce qui touche son " +"point d'extrémité lointain. Il est souvent utile pour les caractères." #: doc/classes/Rect2.xml -#, fuzzy msgid "2D axis-aligned bounding box." -msgstr "Boîte de délimitation alignée sur l'axe." +msgstr "La boîte de délimitation 2D alignée sur les axes." #: doc/classes/Rect2.xml msgid "" @@ -62695,6 +64421,9 @@ msgid "" "top-left corner is the origin and [code]width[/code] and [code]height[/code] " "are positive." msgstr "" +"Retourne un [Rect2] avec la même position et aire, modifié de sorte que le " +"coin supérieur gauche est l'origine et [code]width[/code] et " +"[code]height[/code] soient positifs." #: doc/classes/Rect2.xml msgid "Returns the intersection of this [Rect2] and b." @@ -62716,11 +64445,19 @@ msgid "" "var rect2 = rect.expand(Vector2(0, -1))\n" "[/codeblock]" msgstr "" +"Retourne une copie de ce [Rect2] élargi pour inclure le point donné.\n" +"[b]Exemple :[/b]\n" +"[codeblock]\n" +"# position (-3, 2), size (1, 1)\n" +"var rect = Rect2(Vector2(-3, 2), Vector2(1, 1))\n" +"# position (-3, -1), size (3, 4), contient donc à la fois `rect` et Vector2(" +"0, -1)\n" +"var rect2 = rect.expand(Vector2(0, -1))\n" +"/[codeblock]" #: doc/classes/Rect2.xml -#, fuzzy msgid "Returns the area of the [Rect2]. See also [method has_no_area]." -msgstr "Retourne la zone du [Rect2]." +msgstr "Retourne l'aire du [Rect2]. Voir aussi [method has_no_area]." #: doc/classes/Rect2.xml msgid "" @@ -62735,12 +64472,16 @@ msgid "" "Returns a copy of the [Rect2] grown a given amount of units towards all the " "sides." msgstr "" +"Retourne une copie du [Rect2] aggrandi par une quantité donnée d'unités vers " +"tous les côtés." #: doc/classes/Rect2.xml msgid "" "Returns a copy of the [Rect2] grown a given amount of units towards each " "direction individually." msgstr "" +"Retourne une copie du [Rect2] aggrandi par une quantité donnée d'unités vers " +"chaque direction individuellement." #: doc/classes/Rect2.xml msgid "" @@ -62757,6 +64498,10 @@ msgid "" "[b]Note:[/b] If the [Rect2] has a negative size and is not flat or empty, " "[method has_no_area] will return [code]true[/code]." msgstr "" +"Retourne [code]true[/code] si le [Rect2] est plat ou vide, ou " +"[code]false[/code] sinon. Voir aussi [method get_area].\n" +"[b]Note :[/b] Si le [Rect2] a une taille négative et n'est pas plat ou vide, " +"[method has_no_area] retournera [code]true[/code]." #: doc/classes/Rect2.xml msgid "" @@ -62775,6 +64520,11 @@ msgid "" "If [code]include_borders[/code] is [code]true[/code], they will also be " "considered overlapping if their borders touch, even without intersection." msgstr "" +"Retourne [code]true[/code] si le [Rect2] se chevauche avec [code]b[/code] " +"(c'est-à-dire qu'ils ont au moins un point en commun).\n" +"Si [code]include_borders[/code] est [code]true[/code], ils seront également " +"considérés comme se chevauchant si leurs bordures touchent, même sans " +"intersection." #: doc/classes/Rect2.xml msgid "" @@ -62782,6 +64532,9 @@ msgid "" "approximately equal, by calling [code]is_equal_approx[/code] on each " "component." msgstr "" +"Retourne [code]true[/code] si ce [Rect2] et [code]rect[/code] sont " +"approximativement égaux, en appelant [code]is_equal_approx[/code] sur chaque " +"composant." #: doc/classes/Rect2.xml msgid "Returns a larger [Rect2] that contains this [Rect2] and [code]b[/code]." @@ -62798,12 +64551,16 @@ msgid "" "Rectangle shape for 2D collisions. This shape is useful for modeling box-" "like 2D objects." msgstr "" +"Une forme rectangulaire pour les collisions 2D. Cette forme est utile pour " +"les objets 2D de type boîte." #: doc/classes/RectangleShape2D.xml msgid "" "The rectangle's half extents. The width and height of this shape is twice " "the half extents." msgstr "" +"La demi-taille du rectangle. La largeur et la hauteur de cette forme sont " +"deux fois plus grandes." #: doc/classes/Reference.xml msgid "Base class for reference-counted objects." @@ -62832,6 +64589,9 @@ msgid "" "what you are doing.\n" "Returns whether the initialization was successful." msgstr "" +"Initialise le compteur de référence interne. Utilisez ceci seulement si vous " +"savez vraiment ce que vous faites.\n" +"Retourne si l'initialisation a été réussie." #: doc/classes/Reference.xml msgid "" @@ -62840,6 +64600,10 @@ msgid "" "Returns [code]true[/code] if the increment was successful, [code]false[/" "code] otherwise." msgstr "" +"Augmente le compteur de référence interne. Utilisez ceci seulement si vous " +"savez vraiment ce que vous faites.\n" +"Retourne [code]true[/code] si l'augmentation a réussi, [code]false[/code] " +"sinon." #: doc/classes/Reference.xml msgid "" @@ -62848,6 +64612,10 @@ msgid "" "Returns [code]true[/code] if the decrement was successful, [code]false[/" "code] otherwise." msgstr "" +"Diminue le compteur de référence interne. Utilisez ceci seulement si vous " +"savez vraiment ce que vous faites.\n" +"Retourne [code]true[/code] si la diminution a réussi, [code]false[/code] " +"sinon." #: doc/classes/ReferenceRect.xml msgid "Reference frame for GUI." @@ -62860,6 +64628,10 @@ msgid "" "display a rectangle filled with a solid color, consider using [ColorRect] " "instead." msgstr "" +"Une boîte rectangulaire qui n'affiche que la couleur [member border_color] " +"sur ses bordures. [ReferenceRect] n'a pas de [Color] de remplissage. Si vous " +"devez afficher un rectangle rempli avec une couleur, utilisez plutôt " +"[ColorRect]." #: doc/classes/ReferenceRect.xml msgid "Sets the border [Color] of the [ReferenceRect]." @@ -62870,19 +64642,24 @@ msgid "" "Sets the border width of the [ReferenceRect]. The border grows both inwards " "and outwards with respect to the rectangle box." msgstr "" +"Définit la largeur de la bordure du [ReferenceRect]. La bordure va à la fois " +"vers l'intérieur et vers l'extérieur par rapport aux limites du rectangle." #: doc/classes/ReferenceRect.xml msgid "" "If set to [code]true[/code], the [ReferenceRect] will only be visible while " "in editor. Otherwise, [ReferenceRect] will be visible in game." msgstr "" +"Si définit à [code]true[/code], le [ReferenceRect] ne sera visible que dans " +"l'éditeur. Sinon, [ReferenceRect] sera aussi visible dans le jeu." #: doc/classes/ReflectionProbe.xml -#, fuzzy msgid "" "Captures its surroundings to create fast, accurate reflections from a given " "point." -msgstr "Capture son environnement pour créer des réflexions." +msgstr "" +"Capture son environnement pour créer des réflexions rapides et précises " +"depuis un point donné." #: doc/classes/ReflectionProbe.xml msgid "" @@ -62958,6 +64735,8 @@ msgid "" "Sets the ambient light color to be used when this probe is set to [member " "interior_enable]." msgstr "" +"Définit la couleur de la lumière ambiante à utiliser lorsque cette sonde est " +"définie à [membrer interior_enable]." #: doc/classes/ReflectionProbe.xml msgid "" @@ -62965,22 +64744,25 @@ msgid "" "light for this reflection probe when set to [member interior_enable]. Useful " "so that ambient light matches the color of the room." msgstr "" +"Définit la valeur de contribution pour la quantité de lumière ambiante " +"affectée par la réflexion pour cette sonde que [member interior_enable] est " +"activé. Utile pour que la lumière ambiante corresponde à la couleur de la " +"pièce." #: doc/classes/ReflectionProbe.xml msgid "" "Sets the energy multiplier for this reflection probe's ambient light " "contribution when set to [member interior_enable]." msgstr "" +"Définit le multiplicateur d'énergie pour cette sonde de réflexion de la " +"lumière ambiante quand défini à [member interior_enable]." #: doc/classes/ReflectionProbe.xml -#, fuzzy msgid "" "If [code]true[/code], reflections will ignore sky contribution. Ambient " "lighting is then controlled by the [code]interior_ambient_*[/code] " "properties." msgstr "" -"Retourne la profondeur de la texture. La profondeur est la 3ème dimension " -"(généralement l'axe Z)." #: doc/classes/ReflectionProbe.xml msgid "" @@ -63528,9 +65310,8 @@ msgid "" msgstr "" #: doc/classes/ResourceImporter.xml -#, fuzzy msgid "Base class for the implementation of core resource importers." -msgstr "Classe de base pour une implémentation d’interface AR / VR." +msgstr "" #: doc/classes/ResourceImporter.xml msgid "" @@ -63544,9 +65325,8 @@ msgid "Import plugins" msgstr "Importer des plugins" #: doc/classes/ResourceImporter.xml -#, fuzzy msgid "The default import order." -msgstr "La police par défaut du thème." +msgstr "" #: doc/classes/ResourceImporter.xml msgid "" @@ -63569,13 +65349,10 @@ msgid "" msgstr "" #: doc/classes/ResourceInteractiveLoader.xml -#, fuzzy msgid "" "Returns the loaded resource if the load operation completed successfully, " "[code]null[/code] otherwise." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères commence par la chaîne " -"de caractères donnée, ou [code]false[/code] le cas échéant." #: doc/classes/ResourceInteractiveLoader.xml msgid "" @@ -63977,9 +65754,8 @@ msgid "" msgstr "" #: doc/classes/RichTextLabel.xml -#, fuzzy msgid "Returns the current selection text. Does not include BBCodes." -msgstr "Retourne le numéro de la ligne actuelle." +msgstr "" #: doc/classes/RichTextLabel.xml msgid "" @@ -64275,24 +66051,20 @@ msgid "Makes text fill width." msgstr "Rempli le texte en largeur." #: doc/classes/RichTextLabel.xml -#, fuzzy msgid "Aligns top of the inline image to the top of the text." -msgstr "La hauteur de la boite mesuré depuis son centre." +msgstr "" #: doc/classes/RichTextLabel.xml -#, fuzzy msgid "Aligns center of the inline image to the center of the text." -msgstr "Aligne les enfants avec le centre du conteneur." +msgstr "" #: doc/classes/RichTextLabel.xml -#, fuzzy msgid "Aligns bottom of the inline image to the baseline of the text." -msgstr "La hauteur de la boite mesuré depuis son centre." +msgstr "" #: doc/classes/RichTextLabel.xml -#, fuzzy msgid "Aligns bottom of the inline image to the bottom of the text." -msgstr "Aligne les enfants avec le centre du conteneur." +msgstr "" #: doc/classes/RichTextLabel.xml msgid "Each list item has a number marker." @@ -64373,7 +66145,6 @@ msgid "The default text font." msgstr "La police par défaut du texte." #: doc/classes/RichTextLabel.xml -#, fuzzy msgid "The background used when the [RichTextLabel] is focused." msgstr "L'arrière-plan utilisé quand le [RichTextLabel] a le focus." @@ -64515,16 +66286,15 @@ msgid "Locks the specified linear or rotational axis." msgstr "Verrouille l'axe linéaire et de rotation spécifié." #: doc/classes/RigidBody.xml -#, fuzzy msgid "" "Damps the body's rotational forces. If this value is different from -1.0 it " "will be added to any angular damp derived from the world or areas.\n" "See [member ProjectSettings.physics/3d/default_angular_damp] for more " "details about damping." msgstr "" -"La vitesse à laquelle les objets arrêtent de tourner dans cette zone. " -"Représente la vitesse angulaire perdue par seconde.\n" -"Voir [membre ProjectSettings.physics/2d/default_angular_damp] pour plus de " +"Amortit les forces de rotation du corps. Si cette valeur est différente de -" +"1.0, elle sera ajoutée aux amortissements obtenues du monde et des aires.\n" +"Voir [membre ProjectSettings.physics/3d/default_angular_damp] pour plus de " "détails sur l'amortissement." #: doc/classes/RigidBody.xml @@ -64847,9 +66617,8 @@ msgid "The body's total applied force." msgstr "La force appliquée totale du corps." #: doc/classes/RigidBody2D.xml -#, fuzzy msgid "The body's total applied torque." -msgstr "La force appliquée totale du corps." +msgstr "La force totale appliquée au corps." #: doc/classes/RigidBody2D.xml msgid "" @@ -65411,9 +67180,8 @@ msgid "Path to an [AnimationTree] node to use as a basis for root motion." msgstr "" #: doc/classes/RootMotionView.xml -#, fuzzy msgid "The grid's cell size in 3D units." -msgstr "La taille de cellule du TileMap." +msgstr "La taille de cellule de la grille en unités 3D." #: doc/classes/RootMotionView.xml msgid "The grid's color." @@ -65426,14 +67194,11 @@ msgid "" msgstr "" #: doc/classes/RootMotionView.xml -#, fuzzy msgid "" "If [code]true[/code], the grid's points will all be on the same Y coordinate " "([i]local[/i] Y = 0). If [code]false[/code], the points' original Y " "coordinate is preserved." msgstr "" -"Si [code]true[/code], l’état de la clé est pressé. Si [code]false[/code], " -"l’état de la clé est libéré." #: doc/classes/SceneState.xml msgid "A script interface to a scene file's data." @@ -65830,13 +67595,11 @@ msgid "" msgstr "" #: doc/classes/SceneTree.xml -#, fuzzy msgid "" "If [code]true[/code], the application automatically accepts quitting.\n" "For mobile platforms, see [member quit_on_go_back]." msgstr "" -"Si [code]true[/code], l'application accepte automatiquement de se fermer. " -"Activé par défaut.\n" +"Si [code]true[/code], l'application accepte automatiquement de se fermer.\n" "Pour les plateformes mobiles, voir [method set_quit_on_go_back]." #: doc/classes/SceneTree.xml @@ -65923,9 +67686,8 @@ msgstr "" "les nouvelles connexions entrantes." #: doc/classes/SceneTree.xml -#, fuzzy msgid "The [SceneTree]'s root [Viewport]." -msgstr "La [Window] racine de [SceneTree]." +msgstr "La [Viewport] racine du [SceneTree]." #: doc/classes/SceneTree.xml msgid "" @@ -65963,9 +67725,8 @@ msgid "" msgstr "" #: doc/classes/SceneTree.xml -#, fuzzy msgid "Emitted whenever global menu item is clicked." -msgstr "Émis lorsqu’un élément est sélectionné." +msgstr "Émis quand le menu global est cliqué." #: doc/classes/SceneTree.xml msgid "" @@ -66007,9 +67768,8 @@ msgid "Emitted whenever a node is removed from the [SceneTree]." msgstr "Émit quand un nœud est retiré du [SceneTree]." #: doc/classes/SceneTree.xml -#, fuzzy msgid "Emitted whenever a node is renamed." -msgstr "Émis chaque fois qu’un nœud est renommé." +msgstr "Émis quand un nœud est renommé." #: doc/classes/SceneTree.xml msgid "" @@ -66109,7 +67869,6 @@ msgid "One-shot timer." msgstr "Minuteur à un coup." #: doc/classes/SceneTreeTimer.xml -#, fuzzy msgid "" "A one-shot timer managed by the scene tree, which emits [signal timeout] on " "completion. See also [method SceneTree.create_timer].\n" @@ -66135,16 +67894,16 @@ msgstr "" " yield(get_tree().create_timer(1.0), \"timeout\")\n" " print(\"Minuteur terminé.\")\n" "[/codeblock]\n" -"Le minuteur sera automatiquement une fois terminé." +"Le minuteur sera automatiquement une fois terminé. Pour garder le minuteur, " +"vous pouvez maintenir une référence vers lui. Voir [Reference]." #: doc/classes/SceneTreeTimer.xml msgid "The time remaining (in seconds)." msgstr "Le temps restant (en secondes)." #: doc/classes/SceneTreeTimer.xml doc/classes/Timer.xml -#, fuzzy msgid "Emitted when the timer reaches 0." -msgstr "Émis lorsque la minuterie atteint 0." +msgstr "Émis quand le minuteur atteint 0." #: doc/classes/SceneTreeTween.xml msgid "" @@ -66522,7 +68281,6 @@ msgstr "" "[/codeblock]" #: doc/classes/SceneTreeTween.xml -#, fuzzy msgid "" "Creates and appends an [IntervalTweener]. This method can be used to create " "delays in the tween animation, as an alternative to using the delay in other " @@ -66552,7 +68310,7 @@ msgstr "" "délais des autres [Tweener] ou quand il n'y a pas d'animation (dans ce cas " "le [SceneTreeTween] se comportement comme un minuteur). [code]time[/code] " "est le durée du délai, en secondes.\n" -"Exemple : créer un délai de 2s dans l'exécution du code.\n" +"Exemple : créer un délai dans l'exécution du code.\n" "[codeblock]\n" "# ... du code\n" "yield(create_tween().tween_interval(2), \"finished\")\n" @@ -66626,7 +68384,6 @@ msgstr "" "[/codeblock]" #: doc/classes/SceneTreeTween.xml -#, fuzzy msgid "" "Creates and appends a [PropertyTweener]. This method tweens a " "[code]property[/code] of an [code]object[/code] between an initial value and " @@ -66668,14 +68425,14 @@ msgstr "" "tween.tween_property($Sprite, \"position\", Vector2(200, 300), 1)\n" "[/codeblock]\n" "déplacera la sprite de sa position actuelle à la position (100, 200) puis " -"ensuite à (200, 300). Si vous utilisez [method PropertyTweener.from] ou " -"[method PropertyTweener.from_current], la position de départ sera celle " +"ensuite à (200, 300). Si vous utilisez [method PropertyTweener.from] ou [" +"method PropertyTweener.from_current], la position de départ sera celle " "spécifiée et non l'actuelle. Voir les autres méthodes de [PropertyTweener] " "pour connaitre les possibilités.\n" "[b]Note :[/b] Vous pouvez trouver les noms corrects des propriétés en " "survolant ces propriétés dans l'inspecteur de Godot. Vous pouvez aussi " -"fournir un seul composant de cette propriété directement en utilisant " -"[code]\"property:component\"[/code] (ex. [code]position:x[/code]), alors " +"fournir un seul composant de cette propriété directement en utilisant [code]" +"\"property:component\"[/code] (ex. [code]position:x[/code]), alors " "l'interpolation ne se fera que sur cet unique composant.\n" "Exemple : déplacer un objet deux fois depuis la même position vers " "différentes positions, avec différents types de transition.\n" @@ -66723,11 +68480,10 @@ msgid "If [SceneTree] is paused, the [SceneTreeTween] will also pause." msgstr "Si le [SceneTree] est en pause, le [SceneTreeTween] le sera aussi." #: doc/classes/SceneTreeTween.xml -#, fuzzy msgid "" "The [SceneTreeTween] will process regardless of whether [SceneTree] is " "paused." -msgstr "Arrête la mise à jour quand le [SceneTree] est en pause." +msgstr "" #: doc/classes/Script.xml msgid "A class stored as a resource." @@ -67063,7 +68819,6 @@ msgid "" msgstr "" #: doc/classes/Shader.xml -#, fuzzy msgid "A custom shader program." msgstr "Un programme de shader personnalisé." @@ -67413,9 +69168,8 @@ msgid "" msgstr "" #: doc/classes/Skeleton.xml -#, fuzzy msgid "Sets the pose transform for bone [code]bone_idx[/code]." -msgstr "Définit le décalage à partir de [code]0.5[/code]." +msgstr "" #: doc/classes/Skeleton.xml msgid "Sets the rest transform for bone [code]bone_idx[/code]." @@ -67755,14 +69509,12 @@ msgid "" msgstr "" #: doc/classes/SoftBody.xml -#, fuzzy msgid "Returns local translation of a vertex in the surface array." -msgstr "Renvoie la matrice de transformation d’une forme dans une zone." +msgstr "" #: doc/classes/SoftBody.xml -#, fuzzy msgid "Returns [code]true[/code] if vertex is set to pinned." -msgstr "Retourne [code]true[/code] si l'[AABB] est plate ou vide." +msgstr "" #: doc/classes/SoftBody.xml msgid "" @@ -67798,13 +69550,10 @@ msgid "[NodePath] to a [CollisionObject] this SoftBody should avoid clipping." msgstr "" #: doc/classes/SoftBody.xml -#, fuzzy msgid "" "If [code]true[/code], the [SoftBody] is simulated in physics. Can be set to " "[code]false[/code] to pause the physics simulation." msgstr "" -"Si [code]true[/code], l’état de la clé est pressé. Si [code]false[/code], " -"l’état de la clé est libéré." #: doc/classes/SoftBody.xml msgid "If [code]true[/code], the [SoftBody] will respond to [RayCast]s." @@ -68525,7 +70274,6 @@ msgstr "" "à un point donné." #: doc/classes/SpatialMaterial.xml -#, fuzzy msgid "" "Forces a conversion of the [member albedo_texture] from sRGB space to linear " "space." @@ -68717,11 +70465,10 @@ msgid "" msgstr "" #: doc/classes/SpatialMaterial.xml -#, fuzzy msgid "" "If [code]true[/code], enables the vertex grow setting. See [member " "params_grow_amount]." -msgstr "Si [code]true[/code], active le drapeau spécifié." +msgstr "" #: doc/classes/SpatialMaterial.xml msgid "Grows object vertices in the direction of their normals." @@ -69008,9 +70755,8 @@ msgid "Texture specifying per-pixel depth." msgstr "La texture spécifiant la profondeur par pixel." #: doc/classes/SpatialMaterial.xml -#, fuzzy msgid "Texture specifying per-pixel subsurface scattering." -msgstr "La texture spécifiant par pixel de diffusion souterraine." +msgstr "La texture spécifiant la transluminescence par pixel." #: doc/classes/SpatialMaterial.xml msgid "Texture specifying per-pixel transmission color." @@ -69222,10 +70968,9 @@ msgstr "" "emission_texture]." #: doc/classes/SpatialMaterial.xml -#, fuzzy msgid "Use alpha scissor. Set by [member params_use_alpha_scissor]." msgstr "" -"Utilise un ciseau pour l'alpha. Définit par [member " +"Utilise un ciseau pour l'opacité. Définit par [member " "params_use_alpha_scissor]." #: doc/classes/SpatialMaterial.xml @@ -69649,9 +71394,8 @@ msgstr "" "collision." #: doc/classes/SpringArm.xml -#, fuzzy msgid "Returns the spring arm's current length." -msgstr "Retourne la chaîne de caractères convertie en minuscules." +msgstr "" #: doc/classes/SpringArm.xml msgid "" @@ -69879,20 +71623,28 @@ msgstr "La taille d'un des pixels de la sprite pour définir sa taille en 3D." msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " "This is because opaque objects are not sorted, while transparent objects are " "sorted from back to front (subject to priority)." msgstr "" +"Définit la priorité de rendu pour le texte. Les objets plus prioritaires " +"seront affichés par-dessus les objets les moins prioritaites.\n" +"[b]Note :[/b] Cela ne s'applique que si [member alpha_cut] est défini à [" +"constant ALPHA_CUT_DISABLED] (c'est la valeur par défaut).\n" +"[b]Note :[/b] Cela ne s'applique qu'au tri des objets transparents. Cela " +"n'affectera pas la façon dont les objets transparents sont triés par rapport " +"aux objets opaques. C'est parce que les objets opaques ne sont pas triés, " +"alors que les objets transparents sont triés de l'arrière vers l'avant (et " +"suivant leur priorité)." #: doc/classes/SpriteBase3D.xml -#, fuzzy msgid "" "If [code]true[/code], the [Light] in the [Environment] has effects on the " "sprite." -msgstr "Si [code]true[/code], ce [HTTPClient] a une réponse disponible." +msgstr "" #: doc/classes/SpriteBase3D.xml msgid "" @@ -69952,13 +71704,10 @@ msgid "Removes all animations. A \"default\" animation will be created." msgstr "Retire toutes les animations. Une animation \"défaut\" sera créée." #: doc/classes/SpriteFrames.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the given animation is configured to loop when " "it finishes playing. Otherwise, returns [code]false[/code]." msgstr "" -"Retourne [code]true[/code] si la piste donnée est importée. Sinon retourne " -"[code]false[/code]." #: doc/classes/SpriteFrames.xml msgid "" @@ -70280,9 +72029,8 @@ msgid "" msgstr "" #: doc/classes/StreamPeerBuffer.xml -#, fuzzy msgid "Data buffer stream peer." -msgstr "Homologue de flux SSL." +msgstr "" #: doc/classes/StreamPeerBuffer.xml msgid "" @@ -71181,22 +72929,20 @@ msgstr "" "répétitions est donné en argument." #: doc/classes/String.xml -#, fuzzy msgid "" "Replaces occurrences of a case-sensitive substring with the given one inside " "the string." msgstr "" -"Remplacer les occurrences d'une sous-chaine sensible à la casse avec l'autre " -"donnée." +"Remplace les occurrences sensibles à la casse à l'intérieur d'une chaine par " +"la sous-chaine donnée." #: doc/classes/String.xml -#, fuzzy msgid "" "Replaces occurrences of a case-insensitive substring with the given one " "inside the string." msgstr "" -"Remplacer les occurrences d'une sous-chaine insensible à la casse avec " -"l'autre donnée." +"Remplace les occurrences insensibles à la casse à l'intérieur d'une chaine " +"par la sous-chaine donnée." #: doc/classes/String.xml msgid "" @@ -71713,7 +73459,6 @@ msgstr "" "[code]corner[/code] spécifié. Voir [enum Corner] pour les valeurs possibles." #: doc/classes/StyleBoxFlat.xml -#, fuzzy msgid "Sets the corner radius to [code]radius[/code] pixels for all corners." msgstr "" "Définit le rayon d’angle sur [code]radius[/code] pixels pour tous les coins." @@ -72449,11 +74194,11 @@ msgstr "" "est désactivé." #: doc/classes/TabContainer.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the tab at index [code]tab_idx[/code] is hidden." msgstr "" -"Retourne [code]true[/code] si la piste à l'index [code]idx[/code] est active." +"Retourne [code]true[/code] si l'onglet à l'index [code]tab_idx[/code] est " +"masqué." #: doc/classes/TabContainer.xml doc/classes/Tabs.xml msgid "" @@ -72521,13 +74266,10 @@ msgid "" msgstr "" #: doc/classes/TabContainer.xml -#, fuzzy msgid "" "If [code]true[/code], all tabs are drawn in front of the panel. If " "[code]false[/code], inactive tabs are drawn behind the panel." msgstr "" -"Si [code]true[/code], l’état de la clé est pressé. Si [code]false[/code], " -"l’état de la clé est libéré." #: doc/classes/TabContainer.xml msgid "" @@ -72678,12 +74420,11 @@ msgid "Tabs control." msgstr "Contrôle des onglets." #: doc/classes/Tabs.xml -#, fuzzy msgid "" "Simple tabs control, similar to [TabContainer] but is only in charge of " "drawing tabs, not interacting with children." msgstr "" -"Contrôle des onglets simples, similaire à [TabContainer] mais il est " +"Un contrôle simple des onglets, similaire à [TabContainer] mais il est " "uniquement chargé du dessin des onglets, et non de l’interaction avec les " "enfants." @@ -72761,12 +74502,10 @@ msgid "Select tab at index [code]tab_idx[/code]." msgstr "Sélectionne l'onglet à l'index [code]tab_idx[/code]." #: doc/classes/Tabs.xml -#, fuzzy msgid "" "if [code]true[/code], the mouse's scroll wheel can be used to navigate the " "scroll view." msgstr "" -"Si [code]true[/code], l’état du bouton de la souris est un double-clic." #: doc/classes/Tabs.xml msgid "The alignment of all tabs. See [enum TabAlign] for details." @@ -73009,9 +74748,8 @@ msgid "Returns the amount of total lines in the text." msgstr "Retourne le nombre total de lignes dans le texte." #: doc/classes/TextEdit.xml -#, fuzzy msgid "Returns the height of a largest line." -msgstr "Retourne la hauteur du contenu." +msgstr "" #: doc/classes/TextEdit.xml msgid "" @@ -73022,14 +74760,12 @@ msgstr "" "code]." #: doc/classes/TextEdit.xml -#, fuzzy msgid "Returns the number of times the given line is wrapped." -msgstr "Renvoie le nombre de lignes visibles." +msgstr "" #: doc/classes/TextEdit.xml -#, fuzzy msgid "Returns an array of [String]s representing each wrapped index." -msgstr "Retourne une représentation [String] de l'évènement." +msgstr "" #: doc/classes/TextEdit.xml msgid "" @@ -73074,19 +74810,16 @@ msgid "Returns the selection end line." msgstr "Retourne la ligne de fin de sélection." #: doc/classes/TextEdit.xml -#, fuzzy msgid "Returns the total width of all gutters and internal padding." -msgstr "Retourne le nombre de pistes dans l'animation." +msgstr "" #: doc/classes/TextEdit.xml -#, fuzzy msgid "Returns the total amount of lines that could be drawn." -msgstr "Retourne la position du contact sur le collisionneur." +msgstr "" #: doc/classes/TextEdit.xml -#, fuzzy msgid "Returns the number of visible lines, including wrapped text." -msgstr "Renvoie le nombre de lignes visibles." +msgstr "" #: doc/classes/TextEdit.xml msgid "" @@ -73129,34 +74862,26 @@ msgstr "" "marque-page." #: doc/classes/TextEdit.xml -#, fuzzy msgid "" "Returns [code]true[/code] when the specified [code]line[/code] has a " "breakpoint." msgstr "" -"Retourne [code]true[/code] si la piste à l'index [code]idx[/code] est active." #: doc/classes/TextEdit.xml -#, fuzzy msgid "" "Returns [code]true[/code] when the specified [code]line[/code] is marked as " "safe." msgstr "" -"Retourne [code]true[/code] si la piste à l'index [code]idx[/code] est active." #: doc/classes/TextEdit.xml -#, fuzzy msgid "Returns if the given line is wrapped." -msgstr "Renvoie le texte de la colonne donnée." +msgstr "" #: doc/classes/TextEdit.xml -#, fuzzy msgid "" "Returns whether the mouse is over selection. If [code]edges[/code] is " "[code]true[/code], the edges are considered part of the selection." msgstr "" -"Renvoie [code]true[/code] (vrai) si [code]a[/code] et [code]b[/code] sont " -"approximativement égaux l'un à l'autre." #: doc/classes/TextEdit.xml msgid "Returns [code]true[/code] if the selection is active." @@ -73233,13 +74958,13 @@ msgstr "Définit le texte pour la ligne spécifiée." #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" -"Ajoute un marque-page pour la ligne [code]line[/code] si [code]bookmark[/" -"code] est [code]true[/code]. Supprime le marque-page si [code]bookmark[/" -"code] est [code]false[/code].\n" +"Ajoute un marque-page pour la ligne [code]line[/code] si " +"[code]bookmark[/code] est [code]true[/code]. Supprime le marque-page si " +"[code]bookmark[/code] est [code]false[/code].\n" "Les marque-pages sont affichés dans [member breakpoint_gutter]." #: doc/classes/TextEdit.xml @@ -73305,9 +75030,8 @@ msgid "If [code]true[/code], a right-click displays the context menu." msgstr "Si [code]true[/code], un clic droit affiche le menu contextuel." #: doc/classes/TextEdit.xml -#, fuzzy msgid "If [code]true[/code], allow drag and drop of selected text." -msgstr "Si [code]true[/code], la valeur peut être sélectionnée et modifiée." +msgstr "" #: doc/classes/TextEdit.xml msgid "" @@ -73411,13 +75135,10 @@ msgid "" msgstr "" #: doc/classes/TextEdit.xml -#, fuzzy msgid "" "If [code]true[/code], any custom color properties that have been set for " "this [TextEdit] will be visible." msgstr "" -"Si [code]true[/code], les présélections de couleurs enregistrées sont " -"visibles." #: doc/classes/TextEdit.xml msgid "String value of the [TextEdit]." @@ -73567,9 +75288,8 @@ msgstr "" "Définit le [StyleBox] de ce [TextEdit] quand [member readonly] est activé." #: doc/classes/TextMesh.xml -#, fuzzy msgid "Generate an [PrimitiveMesh] from the text." -msgstr "Générer un [TriangleMesh] à partir du maillage." +msgstr "Génère un [PrimitiveMesh] à partir du texte." #: doc/classes/TextMesh.xml msgid "" @@ -73594,9 +75314,8 @@ msgid "" msgstr "" #: doc/classes/TextMesh.xml -#, fuzzy msgid "[Font] used for the [TextMesh]'s text." -msgstr "[Font] utilisée pour le texte du [Label]." +msgstr "La [Font] utilisée pour le texte du [TextMesh]." #: doc/classes/TextMesh.xml msgid "" @@ -73605,14 +75324,12 @@ msgid "" msgstr "" #: doc/classes/TextMesh.xml -#, fuzzy msgid "The size of one pixel's width on the text to scale it in 3D." -msgstr "La taille d'un des pixels de la sprite pour définir sa taille en 3D." +msgstr "La taille d'un des pixels du texte pour définir sa taille en 3D." #: doc/classes/TextMesh.xml -#, fuzzy msgid "The text to generate mesh from." -msgstr "Le type à partir duquel obtenir la constante." +msgstr "" #: doc/classes/Texture.xml msgid "Texture for 2D and 3D." @@ -73670,9 +75387,8 @@ msgid "Returns the texture width." msgstr "Renvoie la largeur de texture." #: doc/classes/Texture.xml -#, fuzzy msgid "Returns [code]true[/code] if this [Texture] has an alpha channel." -msgstr "Retourne [code]true[/code] (vrai) si la chaîne de caractères est vide." +msgstr "" #: doc/classes/Texture.xml msgid "" @@ -73731,9 +75447,8 @@ msgid "Texture is a video surface." msgstr "La texture est une surface vidéo." #: doc/classes/Texture3D.xml -#, fuzzy msgid "Texture with 3 dimensions." -msgstr "Retourne les dimensions de bitmap." +msgstr "" #: doc/classes/Texture3D.xml msgid "" @@ -74317,46 +76032,33 @@ msgid "Clears all values on the theme." msgstr "Efface toutes les valeurs de ce thème." #: doc/classes/Theme.xml -#, fuzzy msgid "" "Clears the [Color] at [code]name[/code] if the theme has [code]node_type[/" "code]." -msgstr "Multiplie le transform [code]a[/code] par le transform [code]b[/code]." +msgstr "" #: doc/classes/Theme.xml -#, fuzzy msgid "" "Clears the constant at [code]name[/code] if the theme has [code]node_type[/" "code]." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères est vide (longueur de " -"la chaîne égale à [code]0[/code])." #: doc/classes/Theme.xml -#, fuzzy msgid "" "Clears the [Font] at [code]name[/code] if the theme has [code]node_type[/" "code]." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères est vide (longueur de " -"la chaîne égale à [code]0[/code])." #: doc/classes/Theme.xml -#, fuzzy msgid "" "Clears the icon at [code]name[/code] if the theme has [code]node_type[/code]." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères est vide (longueur de " -"la chaîne égale à [code]0[/code])." #: doc/classes/Theme.xml -#, fuzzy msgid "" "Clears [StyleBox] at [code]name[/code] if the theme has [code]node_type[/" "code]." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères est vide (longueur de " -"la chaîne égale à [code]0[/code])." #: doc/classes/Theme.xml msgid "" @@ -74379,13 +76081,10 @@ msgid "Sets the theme's values to a copy of a given theme." msgstr "Définit les valeurs du thème à partir d'une copie d'un thème donné." #: doc/classes/Theme.xml -#, fuzzy msgid "" "Returns the [Color] at [code]name[/code] if the theme has [code]node_type[/" "code]." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères est vide (longueur de " -"la chaîne égale à [code]0[/code])." #: doc/classes/Theme.xml msgid "" @@ -74400,13 +76099,10 @@ msgid "" msgstr "" #: doc/classes/Theme.xml -#, fuzzy msgid "" "Returns the constant at [code]name[/code] if the theme has [code]node_type[/" "code]." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères est vide (longueur de " -"la chaîne égale à [code]0[/code])." #: doc/classes/Theme.xml msgid "" @@ -74442,13 +76138,10 @@ msgid "" msgstr "" #: doc/classes/Theme.xml -#, fuzzy msgid "" "Returns the icon [Texture] at [code]name[/code] if the theme has " "[code]node_type[/code]." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères est vide (longueur de " -"la chaîne égale à [code]0[/code])." #: doc/classes/Theme.xml msgid "" @@ -74525,11 +76218,9 @@ msgid "" msgstr "" #: doc/classes/Theme.xml -#, fuzzy msgid "" "Returns a list of all type variations for the given [code]base_type[/code]." msgstr "" -"Retourne l'index de l'élément avec l'identifiant [code]id[/code] spécifié." #: doc/classes/Theme.xml msgid "" @@ -74549,13 +76240,10 @@ msgid "" msgstr "" #: doc/classes/Theme.xml -#, fuzzy msgid "" "Returns [code]true[/code] if this theme has a valid [member default_font] " "value." msgstr "" -"Retourne [code]true[/code] si la chaîne de caractères est vide (longueur de " -"la chaîne égale à [code]0[/code])." #: doc/classes/Theme.xml msgid "" @@ -74589,13 +76277,10 @@ msgid "" msgstr "" #: doc/classes/Theme.xml -#, fuzzy msgid "" "Returns [code]true[/code] if [code]theme_type[/code] is marked as a " "variation of [code]base_type[/code]." msgstr "" -"Retourne [code]true[/code] si la piste donnée est importée. Sinon retourne " -"[code]false[/code]." #: doc/classes/Theme.xml msgid "" @@ -74722,9 +76407,8 @@ msgid "" msgstr "" #: doc/classes/Theme.xml -#, fuzzy msgid "Theme's [Color] item type." -msgstr "Le type [Color] du thème." +msgstr "Le type de l'élément [Color] du thème." #: doc/classes/Theme.xml msgid "Theme's constant item type." @@ -74893,13 +76577,10 @@ msgid "" msgstr "" #: doc/classes/TileMap.xml -#, fuzzy msgid "" "Returns an array of all cells with the given tile index specified in " "[code]id[/code]." msgstr "" -"Renvoie la texture de l’atlas de police de caractères à l’index [code]idx[/" -"code]." #: doc/classes/TileMap.xml msgid "Returns a rectangle enclosing the used (non-empty) tiles of the map." @@ -75014,9 +76695,8 @@ msgid "" msgstr "" #: doc/classes/TileMap.xml -#, fuzzy msgid "If [code]true[/code], this TileMap bakes a navigation region." -msgstr "Si [code]true[/code], l'animation nommée existe." +msgstr "" #: doc/classes/TileMap.xml #, fuzzy @@ -75050,11 +76730,10 @@ msgstr "" "valeurs possibles." #: doc/classes/TileMap.xml -#, fuzzy msgid "" "If [code]true[/code], the TileMap's direct children will be drawn in order " "of their Y coordinate." -msgstr "Si [code]true[/code], la frontière de la ligne sera anti-aliasée." +msgstr "" #: doc/classes/TileMap.xml msgid "" @@ -75210,7 +76889,6 @@ msgid "Tile origin at its bottom-left corner." msgstr "Origine de tuile à son coin inférieur gauche." #: doc/classes/TileSet.xml -#, fuzzy msgid "Tile library for tilemaps." msgstr "La bibliothèque des tuiles pour les cartes." @@ -76052,7 +77730,6 @@ msgstr "" "[InputEventAction]." #: doc/classes/TouchScreenButton.xml -#, fuzzy msgid "The button's bitmask." msgstr "Le masque binaire du bouton." @@ -76463,9 +78140,8 @@ msgid "Clears the server from all translations." msgstr "Efface le serveur de toutes les traductions." #: doc/classes/TranslationServer.xml -#, fuzzy msgid "Returns an array of all loaded locales of the project." -msgstr "Renvoie la valeur absolue du paramètre." +msgstr "" #: doc/classes/TranslationServer.xml msgid "" @@ -76708,9 +78384,8 @@ msgid "" msgstr "" #: doc/classes/Tree.xml -#, fuzzy msgid "Causes the [Tree] to jump to the specified [TreeItem]." -msgstr "Définit la position du nœud spécifié." +msgstr "" #: doc/classes/Tree.xml msgid "" @@ -77148,13 +78823,10 @@ msgstr "" "[code]column[/code]." #: doc/classes/TreeItem.xml -#, fuzzy msgid "" "Returns the [Texture] of the button at index [code]button_idx[/code] in " "column [code]column[/code]." msgstr "" -"Rentourne [code]true[/code] (vrai) si le bouton d'index [code]button[/code] " -"est préssé. Voir [enum JoyButtonList]." #: doc/classes/TreeItem.xml msgid "" @@ -77169,13 +78841,10 @@ msgid "Returns the number of buttons in column [code]column[/code]." msgstr "Retourne le nombre de boutons dans la colonne [code]column[/code]." #: doc/classes/TreeItem.xml -#, fuzzy msgid "" "Returns the id for the button at index [code]button_idx[/code] in column " "[code]column[/code]." msgstr "" -"Rentourne [code]true[/code] (vrai) si le bouton d'index [code]button[/code] " -"est préssé. Voir [enum JoyButtonList]." #: doc/classes/TreeItem.xml msgid "" @@ -77186,9 +78855,8 @@ msgstr "" "[code]button_idx[/code] dans la colonne [code]column[/code]." #: doc/classes/TreeItem.xml -#, fuzzy msgid "Returns the column's cell mode." -msgstr "Retourne le mode de la cellule de la colonne." +msgstr "Retourne le mode des cellules de la colonne." #: doc/classes/TreeItem.xml msgid "" @@ -77210,9 +78878,8 @@ msgid "Returns [code]true[/code] if [code]expand_right[/code] is set." msgstr "Retourne [code]true[/code] si [code]expand_right[/code] est défini." #: doc/classes/TreeItem.xml -#, fuzzy msgid "Returns the given column's icon [Texture]. Error if no icon is set." -msgstr "Retourne l'alignement du texte de la colonne donnée." +msgstr "" #: doc/classes/TreeItem.xml msgid "Returns the column's icon's maximum width." @@ -77234,18 +78901,22 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" +"Retourne le TreeItem suivant dans l'arborescence, ou l'objet null s'il n'y " +"en a pas." #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." msgstr "" -"Retourne le TreeItem suivant visible dans l'arborescence ou null si aucun.\n" +"Retourne le TreeItem voisin suivant visible dans l'arborescence, ou null si " +"aucun.\n" "Si [code]wrap[/code] est activé, la méthode repartira depuis le premier " "élément visible de l'arborescence si elle est appelé sur le dernier élément, " "sinon elle retournera [code]null[/code]." @@ -77256,21 +78927,22 @@ msgstr "Renvoie le TreeItem parent ou un objet nul s’il n’y en a pas." #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" -"Retourne le TreeItem précédent dans l'arbre ou un objet nul s'il n'y en a " -"pas." +"Retourne le TreeItem précédent dans l'arborescence, ou l'objet null s'il n'y " +"en a pas." #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." msgstr "" -"Retourne le TreeItem précédent visible dans l'arborescence ou null si " -"aucun.\n" +"Retourne le TreeItem voisin précédent visible dans l'arborescence, ou null " +"si aucun.\n" "Si [code]wrap[/code] est activé, la méthode repartira depuis le dernier " "élément visible de l'arborescence si elle est appelé sur le premier élément, " "sinon elle retournera [code]null[/code]." @@ -77352,12 +79024,10 @@ msgid "Selects the column [code]column[/code]." msgstr "Sélectionne la colonne [code]column[/code]." #: doc/classes/TreeItem.xml -#, fuzzy msgid "" "Sets the given column's button [Texture] at index [code]button_idx[/code] to " "[code]button[/code]." msgstr "" -"Déplace l’élément de l’index [code]from_idx[/code] à [code]to_idx[/code]." #: doc/classes/TreeItem.xml msgid "" @@ -77657,7 +79327,6 @@ msgid "" msgstr "" #: doc/classes/Tween.xml -#, fuzzy msgid "" "Resets all tweens to their initial values (the ones given, not those before " "the tween)." @@ -78771,9 +80440,8 @@ msgid "Vertical box container." msgstr "Conteneur vertical." #: doc/classes/VBoxContainer.xml -#, fuzzy msgid "Vertical box container. See [BoxContainer]." -msgstr "Conteneur vertical. Voir [BoxContainer]." +msgstr "Conteneur de boites vertical. Voir [BoxContainer]." #: doc/classes/VBoxContainer.xml msgid "The vertical space between the [VBoxContainer]'s elements." @@ -78997,9 +80665,8 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml doc/classes/Vector3.xml -#, fuzzy msgid "Returns this vector projected onto the vector [code]b[/code]." -msgstr "Retourne le vecteur projeté sur le vecteur [code]b[/code]." +msgstr "Retourne ce vecteur projeté sur le vecteur [code]b[/code]." #: doc/classes/Vector2.xml msgid "" @@ -79008,13 +80675,12 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -#, fuzzy msgid "" "Returns the vector rotated by [code]angle[/code] (in radians). See also " "[method @GDScript.deg2rad]." msgstr "" -"Retourne le vecteur pivoté par [code]phi[/code] en radians. Voir aussi " -"[method @GDScript.deg2rad]." +"Retourne le vecteur pivoté par [code]angle[/code] (en radians). Voir aussi [" +"method @GDScript.deg2rad]." #: doc/classes/Vector2.xml doc/classes/Vector3.xml msgid "" @@ -79616,7 +81282,6 @@ msgid "" msgstr "" #: modules/gdnative/doc_classes/VideoStreamGDNative.xml -#, fuzzy msgid "[VideoStream] resource for video formats implemented via GDNative." msgstr "" "La ressource [VideoStream] pour les formats vidéo implémentés via GDNative." @@ -79772,12 +81437,10 @@ msgid "Returns the topmost modal in the stack." msgstr "Retourne la vue exclusive la plus en avant dans la pile." #: doc/classes/Viewport.xml -#, fuzzy msgid "" "Returns the mouse's position in this [Viewport] using the coordinate system " "of this [Viewport]." msgstr "" -"Retourne la position de la souris par rapport à la position de cet élément." #: doc/classes/Viewport.xml msgid "Returns information about the viewport from the rendering pipeline." @@ -79788,9 +81451,8 @@ msgid "Returns the [enum ShadowAtlasQuadrantSubdiv] of the specified quadrant." msgstr "" #: doc/classes/Viewport.xml -#, fuzzy msgid "Returns the size override set with [method set_size_override]." -msgstr "Renvoie le mode de remplacement de l’espace pour la zone." +msgstr "" #: doc/classes/Viewport.xml msgid "" @@ -79820,9 +81482,8 @@ msgid "" msgstr "" #: doc/classes/Viewport.xml -#, fuzzy msgid "Returns [code]true[/code] if there are visible modals on-screen." -msgstr "Retourne [code]true[/code] si la colonne donnée est cochée." +msgstr "" #: doc/classes/Viewport.xml msgid "Returns [code]true[/code] if the drag operation is successful." @@ -79885,9 +81546,8 @@ msgid "" msgstr "" #: doc/classes/Viewport.xml -#, fuzzy msgid "If [code]true[/code], the viewport will be used in AR/VR process." -msgstr "Si [code]true[/code], la texture sera centrée." +msgstr "" #: doc/classes/Viewport.xml msgid "If [code]true[/code], the viewport will process 2D audio streams." @@ -80071,10 +81731,8 @@ msgid "" msgstr "" #: doc/classes/Viewport.xml -#, fuzzy msgid "If [code]true[/code], the size override affects stretch as well." msgstr "" -"Si [code]true[/code], le mouvement linéaire à travers l’axe Z est limité." #: doc/classes/Viewport.xml msgid "" @@ -80105,9 +81763,8 @@ msgid "" msgstr "" #: doc/classes/Viewport.xml -#, fuzzy msgid "The custom [World] which can be used as 3D environment source." -msgstr "Une constante [Transform], qui peut être utilisée comme nœud d’entrée." +msgstr "" #: doc/classes/Viewport.xml msgid "The custom [World2D] which can be used as 2D environment source." @@ -80208,14 +81865,12 @@ msgid "Amount of surface changes in frame." msgstr "Le nombre de surfaces changées à chaque trame." #: doc/classes/Viewport.xml -#, fuzzy msgid "Amount of draw calls in frame." -msgstr "Le nombre d'appels d'affichage à chaque trame." +msgstr "Le nombre d'appels de dessin à chaque trame." #: doc/classes/Viewport.xml -#, fuzzy msgid "Amount of items or joined items in frame." -msgstr "Quantité d’objets dans le cadre." +msgstr "" #: doc/classes/Viewport.xml msgid "Represents the size of the [enum RenderInfo] enum." @@ -80462,15 +82117,14 @@ msgid "This enabler will stop [Particles2D] nodes." msgstr "Cet activateur arrêtera les nœuds [Particles2D]." #: doc/classes/VisibilityEnabler2D.xml -#, fuzzy msgid "This enabler will stop the parent's [method Node._process] function." -msgstr "Cet activateur arrêtera la fonction _process du parent." +msgstr "Cet activateur arrêtera la fonction [method Node._process] du parent." #: doc/classes/VisibilityEnabler2D.xml -#, fuzzy msgid "" "This enabler will stop the parent's [method Node._physics_process] function." -msgstr "Cet activateur arrêtera la fonction _physics_process du parent." +msgstr "" +"Cet activateur arrêtera la fonction [method Node._physics_process] du parent." #: doc/classes/VisibilityEnabler2D.xml msgid "This enabler will stop [AnimatedSprite] nodes animations." @@ -80524,15 +82178,12 @@ msgid "" msgstr "" #: doc/classes/VisibilityNotifier.xml -#, fuzzy msgid "Emitted when the VisibilityNotifier enters a [Camera]'s view." -msgstr "" -"Émis lorsque le VisibilityNotifier3D entre dans la vue d’un [Camera3D]." +msgstr "Émis lorsque le VisibilityNotifier entre dans la vue d’un [Camera]." #: doc/classes/VisibilityNotifier.xml -#, fuzzy msgid "Emitted when the VisibilityNotifier exits a [Camera]'s view." -msgstr "Émis lorsque le VisibilityNotifier3D quitte la vue d'un [Camera3D]." +msgstr "Émis lorsque le VisibilityNotifier quitte la vue d'un [Camera]." #: doc/classes/VisibilityNotifier.xml msgid "Emitted when the VisibilityNotifier enters the screen." @@ -80565,9 +82216,8 @@ msgid "" msgstr "" #: doc/classes/VisibilityNotifier2D.xml -#, fuzzy msgid "The VisibilityNotifier2D's bounding rectangle." -msgstr "Rectangle englobant de VisibilityNotifier2D." +msgstr "Le rectangle englobant du VisibilityNotifier2D." #: doc/classes/VisibilityNotifier2D.xml msgid "Emitted when the VisibilityNotifier2D enters the screen." @@ -80605,6 +82255,8 @@ msgid "" "Returns the [AABB] (also known as the bounding box) for this " "[VisualInstance]. See also [method get_transformed_aabb]." msgstr "" +"Retourne le [AABB] (\"bounding box\") pour cette [VisualInstance]. Voir " +"aussi [method get_transformed_aaabb]." #: doc/classes/VisualInstance.xml msgid "" @@ -80612,6 +82264,8 @@ msgid "" "example, if the Node is a [MeshInstance], this will return the RID of the " "associated [Mesh]." msgstr "" +"Retourne le RID de la ressource associée à cette [VisualInstance]. Par " +"exemple, si le nœud est une [MeshInstance], cela retournera le RID du [Mesh]." #: doc/classes/VisualInstance.xml msgid "" @@ -80619,12 +82273,18 @@ msgid "" "by [method VisualServer.instance_create]. This RID is needed if you want to " "call [VisualServer] functions directly on this [VisualInstance]." msgstr "" +"Retourne le RID de cette instance. Ce RID est le même que le RID retourné " +"par [method VisualServer.instance_create]. Ce RID est nécessaire si vous " +"voulez appeler les fonctions [VisualServer] directement sur cette " +"[VisualInstance]." #: doc/classes/VisualInstance.xml msgid "" "Returns [code]true[/code] when the specified layer is enabled in [member " "layers] and [code]false[/code] otherwise." msgstr "" +"Retourne [code]true[/code] si le calque spécifié est actif, ou " +"[code]false[/code] sinon." #: doc/classes/VisualInstance.xml msgid "" @@ -80633,6 +82293,11 @@ msgid "" "Transformed in this case means the [AABB] plus the position, rotation, and " "scale of the [Spatial]'s [Transform]. See also [method get_aabb]." msgstr "" +"Retourne la [AABB] (\"bounding box\") transformée pour cette " +"[VisualInstance].\n" +"Transformé dans ce cas veut dire la [AABB] plus sa position, la rotation et " +"la mise à l'échelle de la [Transform] du [Spatial]. Voir aussi [method " +"get_aabb]." #: doc/classes/VisualInstance.xml msgid "" @@ -80640,6 +82305,9 @@ msgid "" "changes how the engine handles the [VisualInstance] under the hood. " "Equivalent to [method VisualServer.instance_set_base]." msgstr "" +"Définit la ressource qui est instanciée par cette [VisualInstance] qui " +"modifie la façon dont le moteur gère la [VisualInstance] en interne. " +"Équivalent à [method VisualServer.instance_set_base]." #: doc/classes/VisualInstance.xml msgid "Enables a particular layer in [member layers]." @@ -80651,10 +82319,14 @@ msgid "" "This object will only be visible for [Camera]s whose cull mask includes the " "render object this [VisualInstance] is set to." msgstr "" +"Le(s) calque(s) de rendu où cette [VisualInstance] est dessinée.\n" +"Cet objet ne sera visible que pour les [Camera] où le masque de cull inclut " +"l'objet de rendu auquel [VisualInstance] est défini." #: modules/visual_script/doc_classes/VisualScript.xml msgid "A script implemented in the Visual Script programming environment." msgstr "" +"Un script implémenté dans l'environnement de programmation Visual Script." #: modules/visual_script/doc_classes/VisualScript.xml msgid "" @@ -80683,6 +82355,8 @@ msgid "" "Add a variable to the VisualScript, optionally giving it a default value or " "marking it as exported." msgstr "" +"Ajouter une variable au VisualScript, en option lui donnant une valeur par " +"défaut ou la marquant comme exporté." #: modules/visual_script/doc_classes/VisualScript.xml msgid "" @@ -80738,7 +82412,7 @@ msgstr "" #: modules/visual_script/doc_classes/VisualScript.xml msgid "Returns the id of a function's entry point node." -msgstr "" +msgstr "Retourne l'identifiant d'un nœud de point d'entrée de la fonction." #: modules/visual_script/doc_classes/VisualScript.xml msgid "Returns the position of the center of the screen for a given function." @@ -80765,6 +82439,8 @@ msgid "" "Returns the information for a given variable as a dictionary. The " "information includes its name, type, hint and usage." msgstr "" +"Retourne les informations d'une variable donnée dans un dictionnaire. Les " +"informations comprennent son nom, son type, un indice et son usage." #: modules/visual_script/doc_classes/VisualScript.xml msgid "Returns whether a signal exists with the specified name." @@ -80825,16 +82501,23 @@ msgid "" "Unlike [method data_connect], there isn't a [code]to_port[/code], since the " "target node can have only one sequence port." msgstr "" +"Connecte deux ports d'une séquence. L'exécution passera de " +"[code]from_output[/code] de [code]from_node[/code] vers [code]to_node[/code]." +"\n" +"Contrairement à [method data_connect], il n'y a pas ∂e [code]to_port[/code], " +"puisque le nœud cible ne peut avoir qu'un seul port dans la séquence." #: modules/visual_script/doc_classes/VisualScript.xml msgid "" "Disconnect two sequence ports previously connected with [method " "sequence_connect]." msgstr "" +"Déconnecte deux ports de séquence précédemment connectés avec [method " +"sequence_connect]." #: modules/visual_script/doc_classes/VisualScript.xml msgid "Position the center of the screen for a function." -msgstr "" +msgstr "Positionne le centre de l'écran sur une fonction." #: modules/visual_script/doc_classes/VisualScript.xml msgid "Set the base type of the script." @@ -80865,13 +82548,15 @@ msgstr "Émis quand les ports d'un nœud ont changés." #: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml msgid "A Visual Script node representing a constant from the base types." -msgstr "" +msgstr "Un nœud Visual Script représentant une constante d'un type de base." #: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml msgid "" "A Visual Script node representing a constant from base types, such as " "[constant Vector3.AXIS_X]." msgstr "" +"Un nœud Visual Script représentant une constante des types de base, comme [" +"constant Vector3.AXIS_X]." #: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml msgid "The type to get the constant from." @@ -80883,7 +82568,7 @@ msgstr "Le nom de la constante à retourner." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "A Visual Script node used to call built-in functions." -msgstr "" +msgstr "Un nœud Visual Script utilisé pour appeler des fonctions intégrées." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "" @@ -80891,6 +82576,9 @@ msgid "" "function or an utility function.\n" "See also [@GDScript], for the same functions in the GDScript language." msgstr "" +"Une fonction intégrée utilisée dans un [VisualScript]. C'est généralement " +"une fonction de mathématiques ou une fonction utilitaire.\n" +"Voir aussi @[GDScript], pour les mêmes fonctions dans le langage GDScript." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "The function to be executed." @@ -80937,6 +82625,8 @@ msgid "" "Return the arc tangent of the input, using the signs of both parameters to " "determine the exact angle." msgstr "" +"Retourner l'arc tangente de l'entrée, en utilisant les signes des deux " +"paramètres pour déterminer l'angle exact." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Return the square root of the input." @@ -80955,6 +82645,8 @@ msgid "" "Return the positive remainder of one input divided by the other, using " "floating-point numbers." msgstr "" +"Retourner le reste positif d'une entrée divisée par l'autre, en utilisant " +"des flottants." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Return the input rounded down." @@ -80977,6 +82669,8 @@ msgid "" "Return the sign of the input, turning it into 1, -1, or 0. Useful to " "determine if the input is positive or negative." msgstr "" +"Retourner le signe de l'entrée, le transformant en 1, -1, ou 0. Utile pour " +"déterminer si l'entrée est positive ou négative." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Return the input raised to a given power." @@ -80987,18 +82681,26 @@ msgid "" "Return the natural logarithm of the input. Note that this is not the typical " "base-10 logarithm function calculators use." msgstr "" +"Retourner le logarithme népérien de l'entrée. Notez que ce n'est pas " +"l'utilisation typique des calculatrices avec la fonction logarithme en " +"base-10." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "" "Return the mathematical constant [b]e[/b] raised to the specified power of " "the input. [b]e[/b] has an approximate value of 2.71828." msgstr "" +"Retourner la constante mathématique [b]e[/b] à la puissance spécifiée par " +"l'entrée. [b]e[/b] a une valeur approximativement égal à 2.71828." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "" "Return whether the input is NaN (Not a Number) or not. NaN is usually " "produced by dividing 0 by 0, though other ways exist." msgstr "" +"Retourne si l'entrée la valeur spéciale NaN qui signifie que ce n'est pas un " +"nombre (\"Not a Number\") ou non. NaN est généralement produit en divisant 0 " +"par 0, entre autre." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "" @@ -81006,6 +82708,8 @@ msgid "" "Infinity is usually produced by dividing a number by 0, though other ways " "exist." msgstr "" +"Retourne si l'entrée est un nombre flottant infini ou non. L'infini est " +"généralement produit en divisant un nombre par 0, entre autre." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "" @@ -81018,7 +82722,6 @@ msgstr "" "progressive." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml -#, fuzzy msgid "" "Return the number of digit places after the decimal that the first non-zero " "digit occurs." @@ -81028,13 +82731,16 @@ msgstr "" #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Return the input snapped to a given step." -msgstr "" +msgstr "Retourner l'entrée arrondie à l'étape donnée la plus proche." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "" "Return a number linearly interpolated between the first two inputs, based on " "the third input. Uses the formula [code]a + (a - b) * t[/code]." msgstr "" +"Retourner un nombre linéairement interpolé entre les deux premières entrées, " +"basé sur la troisième entrée. Utilise la formule [code]a + (a - b) * " +"t[/code]." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Moves the number toward a value, based on the third input." @@ -81061,12 +82767,17 @@ msgid "" "N (where N is smaller than 2^32 - 1), you can use it with the remainder " "function." msgstr "" +"Retourner une entier de 32 bits aléatoire. Pour obtenir une valeur aléatoire " +"entre 0 et N (où N est plus petit que 2^32 - 1), vous pouvez l'utiliser avec " +"la fonction modulo (retournant le reste de la division euclidienne)." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "" "Return a random floating-point value between 0 and 1. To obtain a random " "value between 0 to N, you can use it with multiplication." msgstr "" +"Retourner un flottant aléatoire entre 0 et 1. Pour obtenir une valeur " +"aléatoire entre 0 à N, vous pouvez multiplier cette valeur avec N." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Return a random floating-point value between the two inputs." @@ -81115,6 +82826,9 @@ msgid "" "never outside it. Equivalent to [code]min(max(input, range_low), range_high)" "[/code]." msgstr "" +"Retourner l'entrée limitée à l'intervalle donné, s'assurant que le résultat " +"n'est jamais en dehors de l'intervalle. Équivalent à [code]min(max(input, " +"minimum), maximum)[/code]." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Return the nearest power of 2 to the input." @@ -81137,6 +82851,8 @@ msgid "" "Return the type of the input as an integer. Check [enum Variant.Type] for " "the integers that might be returned." msgstr "" +"Retourner le type d'entrée en entier. Regardez [enum Variant.Type] pour les " +"valeurs des entiers qui peuvent être retournés." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Checks if a type is registered in the [ClassDB]." @@ -81189,6 +82905,8 @@ msgid "" "Return the [Color] with the given name and alpha ranging from 0 to 1.\n" "[b]Note:[/b] Names are defined in [code]color_names.inc[/code]." msgstr "" +"Retourner la [Color] avec le nom donné et alpha allant de 0 à 1.\n" +"[b]Note :[/b] Les noms sont définis dans [code]color_names.inc[/code]." #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "" @@ -81200,6 +82918,14 @@ msgid "" "return t * t * (3.0 - 2.0 * t)\n" "[/codeblock]" msgstr "" +"Retourner un nombre correctement interpolé entre les deux premières entrées, " +"en fonction de la troisième entrée. Comme [constant MATH_LERP], mais " +"interpole plus rapidement au début et plus lentement à la fin. Utiliser la " +"formule d'interpolation de Hermite:\n" +"[codeblock]\n" +"var t = clamp((weight - from) / (to - from), 0.0, 1.0)\n" +"return t * t * (3.0 - 2.0 * t)\n" +"[/codeblock]" #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Represents the size of the [enum BuiltinFunc] enum." @@ -81314,6 +83040,8 @@ msgid "" "A Visual Script node which calls a base type constructor. It can be used for " "type conversion as well." msgstr "" +"Un nœud Visual Script qui appelle un constructeur de type de base. Il peut " +"également être utilisé pour la conversion de type." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "A scripted Visual Script node." @@ -81322,6 +83050,8 @@ msgstr "Un nœud Visual Script scripté." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "A custom Visual Script node which can be scripted in powerful ways." msgstr "" +"Un nœud Visual Script personnalisé qui peut être scripté de plein de " +"manières." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "Return the node's title." @@ -81375,6 +83105,8 @@ msgid "" "Return the specified output port's hint. See the [enum @GlobalScope." "PropertyHint] hints." msgstr "" +"Retourne l'indice du port de sortie spécifié. Voir les indices dans [enum " +"@GlobalScope.PropertyHint]." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "Return the specified output port's hint string." @@ -81385,10 +83117,11 @@ msgid "Return the specified output port's name." msgstr "Retourne le nom du port de sortie spécifié." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml -#, fuzzy msgid "" "Return the specified output port's type. See the [enum Variant.Type] values." -msgstr "Représente la taille de l'énumération [enum Variant.Type]." +msgstr "" +"Retourne le type du port de sortie spécifié. Voir [enum Variant.Type] " +"valeurs." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "" @@ -81396,6 +83129,9 @@ msgid "" "[b]sequence[/b] port (if there is none, on the place that is usually taken " "by it)." msgstr "" +"Retourne le texte du nœud personnalisé, qui est affiché juste à côté du port " +"d'entrée [b]séquence[/b] (s'il n'y en a aucun, à l'emplacement où " +"habituellement pris par lui)." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "" @@ -81428,18 +83164,24 @@ msgstr "" #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "The start mode used the first time when [method _step] is called." msgstr "" +"Le mode de démarrage a utilisé la première fois que [method _step] est " +"appelée." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "" "The start mode used when [method _step] is called after coming back from a " "[constant STEP_PUSH_STACK_BIT]." msgstr "" +"Le mode de démarrage utilisé lorsque [method _step] est appelé après être " +"revenu de [constant STEP_PUSH_STACK_BIT]." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "" "The start mode used when [method _step] is called after resuming from " "[constant STEP_YIELD_BIT]." msgstr "" +"Le mode de démarrage utilisé lorsque [method _step] est appelé après être " +"revenu de [constant STEP_YIELD_BIT]." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "" @@ -81455,6 +83197,9 @@ msgid "" "Hint used by [method _step] to tell that control should return back, either " "hitting a previous [constant STEP_PUSH_STACK_BIT] or exiting the function." msgstr "" +"L'indice utilisé par [method _step] pour dire que la commande doit revenir, " +"soit en atteignant un précédent [constant STEP_PUSH_STACK_BIT] ou en sortant " +"de la fonction." #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "" @@ -81470,11 +83215,17 @@ msgid "" "Using this requires you to have at least one working memory slot, which is " "used for the [VisualScriptFunctionState]." msgstr "" +"L'indice utilisé par [method _step] pour dire que la fonction doit être " +"attendue.\n" +"En utilisant cela, vous devez avoir au moins un emplacement de mémoire " +"fonctionnel, qui est utilisé pour [VisualScriptFunctionState]." #: modules/visual_script/doc_classes/VisualScriptDeconstruct.xml msgid "" "A Visual Script node which deconstructs a base type instance into its parts." msgstr "" +"Un nœud Visual Script qui déconstruit une instance de type de base en ses " +"différentes parties." #: modules/visual_script/doc_classes/VisualScriptDeconstruct.xml msgid "The type to deconstruct." @@ -81485,12 +83236,16 @@ msgid "" "Add a custom Visual Script node to the editor. It'll be placed under " "\"Custom Nodes\" with the [code]category[/code] as the parameter." msgstr "" +"Ajoute un nœud Visual Script personnalisé à l'éditeur. Il sera placé sous " +"\"Nœuds personnalisés\" avec la [code]category[/code] en paramètre." #: modules/visual_script/doc_classes/VisualScriptEditor.xml msgid "" "Remove a custom Visual Script node from the editor. Custom nodes already " "placed on scripts won't be removed." msgstr "" +"Retire un nœud Visual Script personnalisé de l'éditeur. Les nœuds " +"personnalisés déjà placés sur des scripts ne seront pas supprimés." #: modules/visual_script/doc_classes/VisualScriptEditor.xml msgid "Emitted when a custom Visual Script node is added or removed." @@ -81508,6 +83263,11 @@ msgid "" "[b]Output Ports:[/b]\n" "- Sequence" msgstr "" +"Émet un signal spécifié quand il est exécuté.\n" +"[b]Ports d'entrée :[/b]\n" +"- Séquence : [code]emit[/code]\n" +"[b]Ports de sortie :[/b]\n" +"- Séquence" #: modules/visual_script/doc_classes/VisualScriptEmitSignal.xml msgid "The signal to emit." @@ -81515,16 +83275,15 @@ msgstr "Le signal à émettre." #: modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml msgid "A Visual Script node returning a singleton from [@GlobalScope]." -msgstr "" +msgstr "Un nœud Visual Script retournant un singleton parmi @[GlobalScope]." #: modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml msgid "The singleton's name." msgstr "Le nom du singleton." #: modules/visual_script/doc_classes/VisualScriptExpression.xml -#, fuzzy msgid "A Visual Script node that can execute a custom expression." -msgstr "Un nœud Visual Script utilisé pour annoter le script." +msgstr "Un nœud Visual Script qui peut exécuter une expression personnalisée." #: modules/visual_script/doc_classes/VisualScriptExpression.xml msgid "" @@ -81545,9 +83304,8 @@ msgid "" msgstr "" #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml -#, fuzzy msgid "A Visual Script node for calling a function." -msgstr "Un nœud Visual Script utilisé pour annoter le script." +msgstr "Un nœud Visual Script pour appeler une fonction." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "" @@ -81561,6 +83319,8 @@ msgid "" "The script to be used when [member call_mode] is set to [constant " "CALL_MODE_INSTANCE]." msgstr "" +"Le script à utiliser lorsque [member call_mode] est défini à [constant " +"CALL_MODE_INSTANCE]." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml #: modules/visual_script/doc_classes/VisualScriptYieldSignal.xml @@ -81568,18 +83328,24 @@ msgid "" "The base type to be used when [member call_mode] is set to [constant " "CALL_MODE_INSTANCE]." msgstr "" +"Le type de base à utiliser lorsque [member call_mode] est défini à [constant " +"CALL_MODE_INSTANCE]." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "" "The type to be used when [member call_mode] is set to [constant " "CALL_MODE_BASIC_TYPE]." msgstr "" +"Le type à utiliser lorsque [member call_mode] est défini à [constant " +"CALL_MODE_BASIC_TYPE]." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "" "[code]call_mode[/code] determines the target object on which the method will " "be called. See [enum CallMode] for options." msgstr "" +"[code]call_mode[/code] détermine l'objet cible sur lequel la méthode sera " +"appelée. Voir [enum CallMode] pour les options." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "The name of the function to be called." @@ -81591,12 +83357,16 @@ msgid "" "The node path to use when [member call_mode] is set to [constant " "CALL_MODE_NODE_PATH]." msgstr "" +"Le chemin nœud à utiliser lorsque [member call_mode] est défini à [constant " +"CALL_MODE_NODE_PATH]." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "" "The mode for RPC calls. See [method Node.rpc] for more details and [enum " "RPCCallMode] for available options." msgstr "" +"Le mode pour les appels RPC. Voir [method Node.rpc] pour plus de détails et [" +"enum RPCCallMode] pour les options disponibles." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "" @@ -81612,12 +83382,17 @@ msgid "" "Can't be higher than the number of available default arguments in the " "method's declaration." msgstr "" +"Le nombre d'arguments par défaut qui seront utilisés lors de l'appel de la " +"fonction. Ne peut être supérieur au nombre d'arguments par défaut " +"disponibles dans la déclaration de la méthode." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "" "If [code]false[/code], call errors (e.g. wrong number of arguments) will be " "ignored." msgstr "" +"Si [code]false[/code], les erreurs d'appel (par exemple le nombre erroné " +"d'arguments) seront ignorées." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "The method will be called on this [Object]." @@ -81626,12 +83401,15 @@ msgstr "La méthode sera appelée sur cet [Object]." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "The method will be called on the given [Node] in the scene tree." msgstr "" +"La méthode sera appelée sur le [Node] donné dans l'arborescence de la scène." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "" "The method will be called on an instanced node with the given type and " "script." msgstr "" +"La méthode sera appelée sur un nœud instancié avec le type et le script " +"donnés." #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "The method will be called on a GDScript basic type (e.g. [Vector2])." @@ -81663,6 +83441,8 @@ msgid "" "The method will be called remotely for the given peer, using an unreliable " "protocol." msgstr "" +"La méthode sera appelée à distance pour le pair donné, en utilisant un " +"protocole non fiable." #: modules/visual_script/doc_classes/VisualScriptFunctionState.xml msgid "A Visual Script node representing a function state." @@ -81673,12 +83453,16 @@ msgid "" "[VisualScriptFunctionState] is returned from [VisualScriptYield] and can be " "used to resume a paused function call." msgstr "" +"[VisualScriptFunctionState] est retourné depuis [VisualScriptYield] et peut " +"être utilisé pour reprendre un appel de fonction en pause." #: modules/visual_script/doc_classes/VisualScriptFunctionState.xml msgid "" "Connects this [VisualScriptFunctionState] to a signal in the given object to " "automatically resume when it's emitted." msgstr "" +"Connecte ce [VisualScriptFunctionState] à un signal dans l'objet donné pour " +"reprendre automatiquement lorsqu'il est émis." #: modules/visual_script/doc_classes/VisualScriptFunctionState.xml msgid "Returns whether the function state is valid." @@ -81687,61 +83471,63 @@ msgstr "Retourne si l'état de la fonction est valide." #: modules/visual_script/doc_classes/VisualScriptFunctionState.xml msgid "Resumes the function to run from the point it was yielded." msgstr "" +"Reprend la fonction à exécuter à partir du point où elle a été suspendue." #: modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml -#, fuzzy msgid "A Visual Script node returning a constant from [@GlobalScope]." -msgstr "Un nœud Visual Script utilisé pour annoter le script." +msgstr "Un nœud Visual Script retournant une constante de [@GlobalScope]." #: modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml msgid "The constant to be used." msgstr "La constante à utiliser." #: modules/visual_script/doc_classes/VisualScriptIndexGet.xml -#, fuzzy msgid "A Visual Script node for getting a value from an array or a dictionary." msgstr "" -"Nœud de script visuel utilisé pour créer un tableau à partir d’une liste " -"d’éléments." +"Un nœud Visual Script pour obtenir une valeur d'un tableau ou d'un " +"dictionnaire." #: modules/visual_script/doc_classes/VisualScriptIndexGet.xml msgid "" "[VisualScriptIndexGet] will return the value stored in an array or a " "dictionary under the given index." msgstr "" +"[VisualScriptIndexGet] retourne la valeur enregistrée dans un tableau ou un " +"dictionnaire à l'index donné." #: modules/visual_script/doc_classes/VisualScriptIndexSet.xml -#, fuzzy msgid "A Visual Script node for setting a value in an array or a dictionary." msgstr "" -"Nœud de script visuel utilisé pour créer un tableau à partir d’une liste " -"d’éléments." +"Un nœud Visual Script pour définir une valeur dans un tableau ou un " +"dictionnaire." #: modules/visual_script/doc_classes/VisualScriptIndexSet.xml msgid "" "[VisualScriptIndexSet] will set the value stored in an array or a dictionary " "under the given index to the provided new value." msgstr "" +"[VisualScriptIndexSet] définira la valeur enregistrée dans un tableau ou un " +"dictionnaire à l'index donné avec la nouvelle valeur fournie." #: modules/visual_script/doc_classes/VisualScriptInputAction.xml -#, fuzzy msgid "A Visual Script node returning a state of an action." -msgstr "Un nœud Visual Script utilisé pour annoter le script." +msgstr "Un nœud Visual Script retournant l'état de l'action." #: modules/visual_script/doc_classes/VisualScriptInputAction.xml msgid "" "[VisualScriptInputAction] can be used to check if an action is pressed or " "released." msgstr "" +"[VisualScriptInputAction] peut être utilisé pour vérifier si une action est " +"pressée ou relâchée." #: modules/visual_script/doc_classes/VisualScriptInputAction.xml msgid "Name of the action." msgstr "Le nom de l'action." #: modules/visual_script/doc_classes/VisualScriptInputAction.xml -#, fuzzy msgid "State of the action to check. See [enum Mode] for options." -msgstr "La fonction à calculer. Voir [enum Function] pour les options." +msgstr "L'état de l'action à vérifier. Voir [enum Mode] pour les options." #: modules/visual_script/doc_classes/VisualScriptInputAction.xml msgid "[code]True[/code] if action is pressed." @@ -81780,32 +83566,31 @@ msgstr "" #: modules/visual_script/doc_classes/VisualScriptLists.xml msgid "A Visual Script virtual class for in-graph editable nodes." msgstr "" +"Une classe virtuelle Visual Script pour les nœuds modifiables dans le graphe." #: modules/visual_script/doc_classes/VisualScriptLists.xml msgid "" "A Visual Script virtual class that defines the shape and the default " "behavior of the nodes that have to be in-graph editable nodes." msgstr "" +"Une classe virtuelle Visual Script qui définit la forme et le comportement " +"par défaut des nœuds qui doivent être des nœuds modifiables dans le graphe." #: modules/visual_script/doc_classes/VisualScriptLists.xml -#, fuzzy msgid "Adds an input port to the Visual Script node." -msgstr "Un nœud Visual Script scripté." +msgstr "Ajoute un port d'entrée au nœud Visual Script." #: modules/visual_script/doc_classes/VisualScriptLists.xml -#, fuzzy msgid "Adds an output port to the Visual Script node." -msgstr "Un nœud Visual Script scripté." +msgstr "Ajoute un port de sortie au nœud Visual Script." #: modules/visual_script/doc_classes/VisualScriptLists.xml -#, fuzzy msgid "Removes an input port from the Visual Script node." -msgstr "Supprime un nœud de la sélection." +msgstr "Supprime un port d'entrée du nœud Visual Script." #: modules/visual_script/doc_classes/VisualScriptLists.xml -#, fuzzy msgid "Removes an output port from the Visual Script node." -msgstr "Supprime un nœud de la sélection." +msgstr "Supprime un port de sortie du nœud Visual Script." #: modules/visual_script/doc_classes/VisualScriptLists.xml msgid "Sets the name of an input port." @@ -81938,13 +83723,15 @@ msgstr "" #: modules/visual_script/doc_classes/VisualScriptNode.xml msgid "Returns the [VisualScript] instance the node is bound to." -msgstr "" +msgstr "Retourne l'instance [VisualScript] liée à ce nœud." #: modules/visual_script/doc_classes/VisualScriptNode.xml msgid "" "Notify that the node's ports have changed. Usually used in conjunction with " "[VisualScriptCustomNode] ." msgstr "" +"Notifie quand les ports de ce nœud ont changé. Habituellement utilisé avec " +"[VisualScriptCustomNode] ." #: modules/visual_script/doc_classes/VisualScriptNode.xml msgid "Change the default value of a given port." @@ -81955,11 +83742,8 @@ msgid "Emitted when the available input/output ports are changed." msgstr "Émis quand les ports entrants/sortants sont changés." #: modules/visual_script/doc_classes/VisualScriptOperator.xml -#, fuzzy msgid "A Visual Script node that performs an operation on two values." -msgstr "" -"Nœud de script visuel utilisé pour créer un tableau à partir d’une liste " -"d’éléments." +msgstr "Un nœud Visual Script qui effectue une opération sur deux valeurs." #: modules/visual_script/doc_classes/VisualScriptOperator.xml msgid "" @@ -81971,21 +83755,18 @@ msgid "" msgstr "" #: modules/visual_script/doc_classes/VisualScriptOperator.xml -#, fuzzy msgid "" "The operation to be performed. See [enum Variant.Operator] for available " "options." msgstr "" -"Type de multiplication à effectuer. Voir [enum Operator] pour les options." +"Le type d'opération à effectuer. Voir [enum Variant.Operator] pour les " +"options disponibles." #: modules/visual_script/doc_classes/VisualScriptOperator.xml -#, fuzzy msgid "" "The type of the values for this operation. See [enum Variant.Type] for " "available options." msgstr "" -"Définit la valeur d’un paramètre de zone. Voir [enum AreaParameter] pour une " -"liste de paramètres disponibles." #: modules/visual_script/doc_classes/VisualScriptPreload.xml msgid "Creates a new [Resource] or loads one from the filesystem." @@ -82006,17 +83787,17 @@ msgid "The [Resource] to load." msgstr "La [Resource] à charger." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml -#, fuzzy msgid "A Visual Script node returning a value of a property from an [Object]." msgstr "" -"Nœud de script visuel utilisé pour créer un tableau à partir d’une liste " -"d’éléments." +"Un nœud Visual Script retournant une valeur d'une propriété d'un [Object]." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml msgid "" "[VisualScriptPropertyGet] can return a value of any property from the " "current object or other objects." msgstr "" +"[VisualScriptPropertyGet] peut renvoyer une valeur de toute propriété de " +"l'objet courant ou d'autres objets." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml @@ -82024,6 +83805,8 @@ msgid "" "The script to be used when [member set_mode] is set to [constant " "CALL_MODE_INSTANCE]." msgstr "" +"Le script à utiliser lorsque [member set_mode] est défini à [constant " +"CALL_MODE_INSTANCE]." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml @@ -82031,6 +83814,8 @@ msgid "" "The base type to be used when [member set_mode] is set to [constant " "CALL_MODE_INSTANCE]." msgstr "" +"Le type de base à utiliser lorsque [member set_mode] est défini à [constant " +"CALL_MODE_INSTANCE]." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml @@ -82038,12 +83823,16 @@ msgid "" "The type to be used when [member set_mode] is set to [constant " "CALL_MODE_BASIC_TYPE]." msgstr "" +"Le type à utiliser lorsque [member set_mode] est défini à [constant " +"CALL_MODE_BASIC_TYPE]." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml msgid "" "The indexed name of the property to retrieve. See [method Object." "get_indexed] for details." msgstr "" +"Le nom indexé de la propriété à récupérer. Voir [method Object.get_indexed] " +"pour plus de détails." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml @@ -82051,34 +83840,40 @@ msgid "" "The node path to use when [member set_mode] is set to [constant " "CALL_MODE_NODE_PATH]." msgstr "" +"Le chemin du nœud à utiliser lorsque [member set_mode] est défini à [" +"constant CALL_MODE_NODE_PATH]." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml msgid "" "The name of the property to retrieve. Changing this will clear [member " "index]." msgstr "" +"Le nom de la propriété à récupérer. Changer cela effecera [member index]." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml msgid "" "[code]set_mode[/code] determines the target object from which the property " "will be retrieved. See [enum CallMode] for options." msgstr "" +"[code]set_mode[/code] détermine l'objet cible à partir duquel la propriété " +"sera récupérée. Voir [enum CallMode] pour les options." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml msgid "The property will be retrieved from this [Object]." msgstr "La propriété sera récupérée depuis cet [Object]." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml -#, fuzzy msgid "The property will be retrieved from the given [Node] in the scene tree." msgstr "" -"Le propriété est sérialisé et sauvegardé dans le fichier de la scène(défaut)." +"La propriété sera récupérée du [Node] donné dans l'arborescence de la scène." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml msgid "" "The property will be retrieved from an instanced node with the given type " "and script." msgstr "" +"La propriété sera récupérée à partir d'un nœud instancié avec le type et le " +"script donnés." #: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml msgid "" @@ -82088,23 +83883,23 @@ msgstr "" "[Vector2])." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml -#, fuzzy msgid "A Visual Script node that sets a property of an [Object]." -msgstr "Un nœud Visual Script utilisé pour annoter le script." +msgstr "Un nœud de script visuel qui définit une propriété d'un [Object]." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "" "[VisualScriptPropertySet] can set the value of any property from the current " "object or other objects." msgstr "" +"[VisualScriptPropertySet] peut définir la valeur de toute propriété à partir " +"de l'objet courant ou d'autres objets." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml -#, fuzzy msgid "" "The additional operation to perform when assigning. See [enum AssignOp] for " "options." msgstr "" -"L'opérateur additionelle à effectuer lors de l'assignation. Voir [enum " +"L'opérateur d'addition à effectuer lors de l'assignation. Voir [enum " "AssignOp] pour les options." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml @@ -82112,32 +83907,37 @@ msgid "" "The indexed name of the property to set. See [method Object.set_indexed] for " "details." msgstr "" +"Le nom indexé de la propriété à définir. Voir [method Object.set_indexed] " +"pour plus de détails." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "" "The name of the property to set. Changing this will clear [member index]." -msgstr "" +msgstr "Le nom de la propriété à définir. Changer cela effecera [member index]." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "" "[code]set_mode[/code] determines the target object on which the property " "will be set. See [enum CallMode] for options." msgstr "" +"[code]set_mode[/code] détermine l'objet cible sur lequel la propriété sera " +"définie. Voir [enum CallMode] pour les options." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "The property will be set on this [Object]." msgstr "La propriété sera définie dans cet [Object]." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml -#, fuzzy msgid "The property will be set on the given [Node] in the scene tree." msgstr "" -"Le propriété est sérialisé et sauvegardé dans le fichier de la scène(défaut)." +"La propriété sera placée sur le [Node] donné dans l'arborescence de la scène." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "" "The property will be set on an instanced node with the given type and script." msgstr "" +"La propriété sera définie sur un nœud instancié avec le type et le script " +"donnés." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "The property will be set on a GDScript basic type (e.g. [Vector2])." @@ -82183,36 +83983,48 @@ msgid "" "A modulo operation will be performed on the property and the value. " "Equivalent of doing [code]%=[/code]." msgstr "" +"Une opération modulo sera effectuée sur la propriété et la valeur. Revient à " +"écrire [code]%=[/code]." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "" "The property will be binarly shifted to the left by the given value. " "Equivalent of doing [code]<<[/code]." msgstr "" +"La propriété sera transférée à gauche par la valeur donnée. Revient de " +"écrire [code]<<[/code]." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "" "The property will be binarly shifted to the right by the given value. " "Equivalent of doing [code]>>[/code]." msgstr "" +"La propriété sera transférée à droite par la valeur donnée. Revient de " +"écrire [code]>>[/code]." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "" "A binary [code]AND[/code] operation will be performed on the property. " "Equivalent of doing [code]&=[/code]." msgstr "" +"Une opération binaire [code]AND[/code] (et) sera effectuée sur la propriété. " +"Revient à écrire [code]&=[/code]." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "" "A binary [code]OR[/code] operation will be performed on the property. " "Equivalent of doing [code]|=[/code]." msgstr "" +"Une opération binaire [code]OR[/code] (ou) sera effectuée sur la propriété. " +"Revient à écrire [code]|=[/code]." #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "" "A binary [code]XOR[/code] operation will be performed on the property. " "Equivalent of doing [code]^=[/code]." msgstr "" +"Une opération binaire [code]XOR[/code] (ou exclusif) sera effectuée sur la " +"propriété. Revient à écrire [code]^=[/code]." #: modules/visual_script/doc_classes/VisualScriptReturn.xml msgid "Exits a function and returns an optional value." @@ -82347,9 +84159,8 @@ msgid "" msgstr "" #: modules/visual_script/doc_classes/VisualScriptTypeCast.xml -#, fuzzy msgid "A Visual Script node that casts the given value to another type." -msgstr "Un nœud Visual Script utilisé pour annoter le script." +msgstr "" #: modules/visual_script/doc_classes/VisualScriptTypeCast.xml msgid "" @@ -82417,9 +84228,8 @@ msgid "" msgstr "" #: modules/visual_script/doc_classes/VisualScriptYield.xml -#, fuzzy msgid "A Visual Script node used to pause a function execution." -msgstr "Un nœud Visual Script utilisé pour annoter le script." +msgstr "Un nœud Visual Script pour mettre en pause l'exécution d'une fonction." #: modules/visual_script/doc_classes/VisualScriptYield.xml msgid "" @@ -82428,11 +84238,11 @@ msgid "" msgstr "" #: modules/visual_script/doc_classes/VisualScriptYield.xml -#, fuzzy msgid "" "The mode to use for yielding. See [enum YieldMode] for available options." msgstr "" -"Type de multiplication à effectuer. Voir [enum Operator] pour les options." +"Le mode à utiliser pour suspendre. Voir [enum YieldMode] pour les options " +"disponibles." #: modules/visual_script/doc_classes/VisualScriptYield.xml msgid "The time to wait when [member mode] is set to [constant YIELD_WAIT]." @@ -82451,9 +84261,8 @@ msgid "Yields a function and waits the given time." msgstr "" #: modules/visual_script/doc_classes/VisualScriptYieldSignal.xml -#, fuzzy msgid "A Visual Script node yielding for a signal." -msgstr "Un nœud Visual Script utilisé pour annoter le script." +msgstr "Un nœud Visual Script pour attendre un signal." #: modules/visual_script/doc_classes/VisualScriptYieldSignal.xml msgid "" @@ -82468,6 +84277,8 @@ msgid "" "[code]call_mode[/code] determines the target object to wait for the signal " "emission. See [enum CallMode] for options." msgstr "" +"[code]call_mode[/code] détermine l'objet cible à attendre avant l'émission " +"du signal. Voir [enum CallMode] pour les options." #: modules/visual_script/doc_classes/VisualScriptYieldSignal.xml msgid "The signal name to be waited for." @@ -82479,11 +84290,11 @@ msgstr "Un signal depuis cet [Object] sera utilisé." #: modules/visual_script/doc_classes/VisualScriptYieldSignal.xml msgid "A signal from the given [Node] in the scene tree will be used." -msgstr "" +msgstr "Un signal du [Node] donné dans l'arborescence de la scène sera utilisé." #: modules/visual_script/doc_classes/VisualScriptYieldSignal.xml msgid "A signal from an instanced node with the given type will be used." -msgstr "" +msgstr "Un signal d'un nœud instancié avec le type donné sera utilisé." #: doc/classes/VisualServer.xml msgid "Server for anything visible." @@ -82522,12 +84333,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "Sets images to be rendered in the window margin." msgstr "" +"Définit des images dont le rendu sera fait dans les marges de la fenêtre." #: doc/classes/VisualServer.xml msgid "" "Sets margin size, where black bars (or images, if [method " "black_bars_set_images] was used) are rendered." msgstr "" +"Définit la taille de la marge, où des barres noires (ou des images, si [" +"method black_bars_set_images] est utilisé) sont rendues." #: doc/classes/VisualServer.xml msgid "" @@ -82592,6 +84406,10 @@ msgid "" "the vertical aspect ratio which is equivalent to [constant Camera." "KEEP_HEIGHT]." msgstr "" +"Si [code]true[/code], conserve le rapport d'aspect horizontal qui est " +"équivalent à [constant Camera.KEEP_WIDTH]. Si [code]false[/code], conserve " +"le rapport d'aspect vertical qui est équivalent à [constant Camera." +"KEEP_HEIGHT]." #: doc/classes/VisualServer.xml msgid "" @@ -82612,12 +84430,9 @@ msgid "Adds a circle command to the [CanvasItem]'s draw commands." msgstr "Ajouter un cercle aux commandes de dessin du [CanvasItem]." #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "If ignore is [code]true[/code], the VisualServer does not perform clipping." msgstr "" -"Si [code]true[/code], le multithreading est utilisé pour améliorer les " -"performances." #: doc/classes/VisualServer.xml msgid "Adds a line command to the [CanvasItem]'s draw commands." @@ -82632,6 +84447,8 @@ msgid "" "Adds a [MultiMesh] to the [CanvasItem]'s draw commands. Only affects its " "aabb at the moment." msgstr "" +"Ajoute un [MultiMesh] aux commandes d'affichage du [CanvasItem]. N'affecte " +"que son aabb pour le moment." #: doc/classes/VisualServer.xml msgid "" @@ -82653,6 +84470,8 @@ msgid "" "Adds a polyline, which is a line from multiple points with a width, to the " "[CanvasItem]'s draw commands." msgstr "" +"Ajoute une suite de lignes, qui est une ligne de plusieurs points avec une " +"largeur, aux commandes d'affichage du [CanvasItem]." #: doc/classes/VisualServer.xml msgid "Adds a primitive to the [CanvasItem]'s draw commands." @@ -82677,6 +84496,8 @@ msgstr "Ajouter un rectangle texturé aux commandes de dessin du [CanvasItem]." msgid "" "Adds a texture rect with region setting to the [CanvasItem]'s draw commands." msgstr "" +"Ajoute un rectangle de texture, avec des réglages de la région à afficher, " +"aux commandes d'affichage du [CanvasItem]." #: doc/classes/VisualServer.xml msgid "Adds a triangle array to the [CanvasItem]'s draw commands." @@ -82685,7 +84506,7 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "Clears the [CanvasItem] and removes all commands in it." -msgstr "" +msgstr "Efface le [CanvasItem] et enlève toutes les commandes." #: doc/classes/VisualServer.xml msgid "" @@ -82702,7 +84523,6 @@ msgstr "" "méthode statique [method free_rid] du VisualServer." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Sets clipping for the [CanvasItem]." msgstr "Définit la coupure pour le [CanvasItem]." @@ -82748,6 +84568,9 @@ msgid "" "Sets the parent for the [CanvasItem]. The parent can be another canvas item, " "or it can be the root canvas that is attached to the viewport." msgstr "" +"Définit le parent du [CanvasItem]. Le parent peut être un autre élément de " +"toile, ou il peut être la toile racine qui est attachée à la fenêtre " +"d'affichage." #: doc/classes/VisualServer.xml msgid "Sets the color that modulates the [CanvasItem] without children." @@ -82769,9 +84592,8 @@ msgid "Sets if the [CanvasItem] uses its parent's material." msgstr "Définit si le [CanvasItem] utilise le même matériau que son parent." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Sets if the canvas item (including its children) is visible." -msgstr "Masquer le [CanvasItem] s’il est actuellement visible." +msgstr "Définit si la toile (y compris ses enfants) est visible." #: doc/classes/VisualServer.xml msgid "" @@ -82854,9 +84676,8 @@ msgid "Sets a canvas light's energy." msgstr "Définit l'énergie d'une lumière du canevas." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Sets a canvas light's height." -msgstr "Définit la hauteur d’une toile." +msgstr "" #: doc/classes/VisualServer.xml msgid "" @@ -82870,19 +84691,23 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "The mode of the light, see [enum CanvasLightMode] constants." -msgstr "" +msgstr "Le mode de la lumière, voir les constantes [enum CanvasLightMode]." #: doc/classes/VisualServer.xml msgid "" "Sets the texture's scale factor of the light. Equivalent to [member Light2D." "texture_scale]." msgstr "" +"Définit le facteur d'échelle de la texture de lumière. Équivalent à [member " +"Light2D.texture_scale]" #: doc/classes/VisualServer.xml msgid "" "Sets the width of the shadow buffer, size gets scaled to the next power of " "two for this." msgstr "" +"Définit la largeur du tampon d'ombre, la taille est arrondie à la puissance " +"de deux suivante pour cela." #: doc/classes/VisualServer.xml msgid "Sets the color of the canvas light's shadow." @@ -82954,11 +84779,11 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "Sets the shape of the occluder polygon." -msgstr "" +msgstr "Définit la forme du polygone occulteur." #: doc/classes/VisualServer.xml msgid "Sets the shape of the occluder polygon as lines." -msgstr "" +msgstr "Définit la forme du polygone occulteur avec des lignes." #: doc/classes/VisualServer.xml msgid "" @@ -83020,6 +84845,8 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "Sets the ambient light parameters. See [Environment] for more details." msgstr "" +"Définit les paramètres de lumière ambiante. Voir [Environnement] pour plus " +"de détails." #: doc/classes/VisualServer.xml msgid "" @@ -83061,18 +84888,24 @@ msgid "" "Sets the variables to be used with the scene fog. See [Environment] for more " "details." msgstr "" +"Définit les variables à utiliser avec le brouillard de scène. Voir " +"[Environnement] pour plus de détails." #: doc/classes/VisualServer.xml msgid "" "Sets the variables to be used with the fog depth effect. See [Environment] " "for more details." msgstr "" +"Définit les variables à utiliser avec l'effet de profondeur du brouillard. " +"Voir [Environnement] pour plus de détails." #: doc/classes/VisualServer.xml msgid "" "Sets the variables to be used with the fog height effect. See [Environment] " "for more details." msgstr "" +"Définit les variables à utiliser avec l'effet de hauteur du brouillard. Voir " +"[Environnement] pour plus de détails." #: doc/classes/VisualServer.xml msgid "" @@ -83091,12 +84924,16 @@ msgid "" "Sets a custom field of view for the background [Sky]. Equivalent to [member " "Environment.background_sky_custom_fov]." msgstr "" +"Définit un angle de vue personnalisé pour le ciel [Sky] en arrière-plan. " +"Équivalent à [member Environnement.background_sky_custom_fov]" #: doc/classes/VisualServer.xml msgid "" "Sets the rotation of the background [Sky] expressed as a [Basis]. Equivalent " "to [member Environment.background_sky_orientation]." msgstr "" +"Définit la rotation du ciel [Sky] en arrière-plan exprimé avec une [Basis]. " +"Équivalent à [member Environnement.background_sky_orientation]" #: doc/classes/VisualServer.xml msgid "" @@ -83140,6 +84977,7 @@ msgstr "Essaye de supprimer un objet dans le VisualServer." #: doc/classes/VisualServer.xml msgid "Returns a certain information, see [enum RenderInfo] for options." msgstr "" +"Retourne une information précise, voir [enum RenderInfo] pour les options." #: doc/classes/VisualServer.xml msgid "Returns the id of the test cube. Creates one if none exists." @@ -83157,6 +84995,10 @@ msgid "" "[b]Note:[/b] When running a headless or server binary, this function returns " "an empty string." msgstr "" +"Retourne le nom de l'adaptateur vidéo (par exemple \"GeForce GTX 1080/PCIe/" +"SSE2\").\n" +"[b]Note :[/b] Lors de l'exécution d'une version sans graphique ou de " +"serveur, cette fonction retourne une chaîne vide." #: doc/classes/VisualServer.xml msgid "" @@ -83164,6 +85006,10 @@ msgid "" "[b]Note:[/b] When running a headless or server binary, this function returns " "an empty string." msgstr "" +"Retourne le vendeur de l'adaptateur vidéo (par exemple \"NVIDIA Corporation\"" +").\n" +"[b]Note :[/b] Lors de l'exécution d'une version sans graphique ou de " +"serveur, cette fonction retourne une chaîne vide." #: doc/classes/VisualServer.xml msgid "Returns the id of a white texture. Creates one if none exists." @@ -83206,21 +85052,24 @@ msgstr "" "Retourne la taille de la cellule définit par [method gi_probe_set_cell_size]." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns the data used by the GI probe." -msgstr "Renvoie l’espace affecté à la zone." +msgstr "Retourne les données utilisées par la sonde GI." #: doc/classes/VisualServer.xml msgid "" "Returns the dynamic range set for this GI probe. Equivalent to [member " "GIProbe.dynamic_range]." msgstr "" +"Retourne la gamme dynamique pour cette sonde GI. Équivalent à [member GIProbe" +".dynamic_range]" #: doc/classes/VisualServer.xml msgid "" "Returns the energy multiplier for this GI probe. Equivalent to [member " "GIProbe.energy]." msgstr "" +"Retourne le multiplicateur d'énergie pour cette sonde GI. Équivalent à [" +"member GIProbe.energy]" #: doc/classes/VisualServer.xml msgid "" @@ -83233,6 +85082,8 @@ msgid "" "Returns the propagation value for this GI probe. Equivalent to [member " "GIProbe.propagation]." msgstr "" +"Retourne la valeur de propagation de cette sonde GI. Équivalent à [member " +"GIProbe.propagation]" #: doc/classes/VisualServer.xml msgid "Returns the Transform set by [method gi_probe_set_to_cell_xform]." @@ -83243,15 +85094,14 @@ msgid "" "Returns [code]true[/code] if the GI probe data associated with this GI probe " "is compressed. Equivalent to [member GIProbe.compress]." msgstr "" +"Retourne [code]true[/code] si les données de cette sonde GI sont " +"compressées. Équivalent à [member GIProbe.compress]" #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the GI probe is set to interior, meaning it " "does not account for sky light. Equivalent to [member GIProbe.interior]." msgstr "" -"Si [code]true[/code], les réflexions ignoreront la contribution du ciel. " -"Équivalent à [member ReflectionProbe.interior]." #: doc/classes/VisualServer.xml msgid "" @@ -83317,9 +85167,8 @@ msgid "" msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Sets the to cell [Transform] for this GI probe." -msgstr "Retourne la matrice de transformation globale de cet élément." +msgstr "" #: doc/classes/VisualServer.xml msgid "" @@ -83402,9 +85251,8 @@ msgid "" msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Sets the material to be used to draw the [ImmediateGeometry]." -msgstr "Retourne le matériel affecté à la [ImmediateGeometry3D]." +msgstr "Définit le matériel utilisé pour afficher le [ImmediateGeometry]." #: doc/classes/VisualServer.xml msgid "" @@ -83686,13 +85534,10 @@ msgid "" msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "If [code]true[/code], light will subtract light instead of adding light. " "Equivalent to [member Light.light_negative]." msgstr "" -"Si [code]true[/code], les réflexions ignoreront la contribution du ciel. " -"Équivalent à [member ReflectionProbe.interior]." #: doc/classes/VisualServer.xml msgid "" @@ -83710,13 +85555,10 @@ msgid "" msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "If [code]true[/code], light will cast shadows. Equivalent to [member Light." "shadow_enabled]." msgstr "" -"Si [code]true[/code], les réflexions ignoreront la contribution du ciel. " -"Équivalent à [member ReflectionProbe.interior]." #: doc/classes/VisualServer.xml msgid "" @@ -83753,19 +85595,16 @@ msgstr "" "en utilisant la [method instance_set_base] utilisant le RID retourné." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns the size of the lightmap capture area." -msgstr "Renvoie le sinus du paramètre." +msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns the energy multiplier used by the lightmap capture." -msgstr "Renvoie le nombre de textures dans l’atlas BitmapFont." +msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns the octree used by the lightmap capture." -msgstr "Renvoie l’espace affecté à la zone." +msgstr "" #: doc/classes/VisualServer.xml msgid "" @@ -83773,9 +85612,8 @@ msgid "" msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns the cell transform for this lightmap capture's octree." -msgstr "Retourne la matrice de transformation de la toile de cet objet." +msgstr "" #: doc/classes/VisualServer.xml msgid "Returns [code]true[/code] if capture is in \"interior\" mode." @@ -83843,13 +85681,10 @@ msgid "Returns the value of a certain material's parameter." msgstr "Retourne la valeur du paramètre du matériau." #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "Returns the default value for the param if available. Returns [code]null[/" "code] otherwise." msgstr "" -"Retourne la valeur par défaut du paramètre nommé [code]name[/code] du " -"matériau." #: doc/classes/VisualServer.xml msgid "" @@ -83866,9 +85701,8 @@ msgid "Sets an object's next material." msgstr "Définit le prochain matériau d’un objet." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Sets a material's parameter." -msgstr "Définit le paramètre d’un matériau." +msgstr "Définit le paramètre d'un matériau." #: doc/classes/VisualServer.xml msgid "Sets a material's render priority." @@ -83931,7 +85765,7 @@ msgstr "Supprime la surface d'un maillage." #: doc/classes/VisualServer.xml #, fuzzy msgid "Sets a mesh's blend shape count." -msgstr "Retourne le nombre de formes de mélange d’un maillage." +msgstr "Définit le nombre de formes de mélange d’un maillage." #: doc/classes/VisualServer.xml msgid "Sets a mesh's blend shape mode." @@ -83946,19 +85780,16 @@ msgid "Returns a mesh's surface's aabb." msgstr "Retourne l’aabb de la surface d'un maillage." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns a mesh's surface's vertex buffer." -msgstr "Retourne l’aabb personnalisé d’un maillage." +msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns a mesh's surface's amount of indices." -msgstr "Renvoie le nombre de points de la Ligne2D." +msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns a mesh's surface's amount of vertices." -msgstr "Renvoie le nombre de points de la Ligne2D." +msgstr "" #: doc/classes/VisualServer.xml msgid "Returns a mesh's surface's buffer arrays." @@ -83969,32 +85800,28 @@ msgid "Returns a mesh's surface's arrays for blend shapes." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns the format of a mesh's surface." -msgstr "Retourne le nom de la méthode d'une piste de méthode." +msgstr "Retourne le format d'une surface d'un maillage." #: doc/classes/VisualServer.xml msgid "Function is unused in Godot 3.x." msgstr "Cette fonction n'est pas utilisée dans Godot 3.x." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns a mesh's surface's index buffer." -msgstr "Retourne le mode de forme de mélange d’un maillage." +msgstr "" #: doc/classes/VisualServer.xml msgid "Returns a mesh's surface's material." msgstr "Retourne le matériau de la surface du maillage." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns the primitive type of a mesh's surface." -msgstr "Retourne le nom de la méthode d'une piste de méthode." +msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns the aabb of a mesh's surface's skeleton." -msgstr "Retourne la traduction d’un message." +msgstr "" #: doc/classes/VisualServer.xml msgid "Sets a mesh's surface's material." @@ -84268,13 +86095,10 @@ msgid "" msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "If [code]true[/code], uses fractional delta which smooths the movement of " "the particles. Equivalent to [member Particles.fract_delta]." msgstr "" -"Si [code]true[/code], les réflexions ignoreront la contribution du ciel. " -"Équivalent à [member ReflectionProbe.interior]." #: doc/classes/VisualServer.xml msgid "" @@ -84344,13 +86168,12 @@ msgstr "" "retourné." #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "If [code]true[/code], reflections will ignore sky contribution. Equivalent " "to [member ReflectionProbe.interior_enable]." msgstr "" "Si [code]true[/code], les réflexions ignoreront la contribution du ciel. " -"Équivalent à [member ReflectionProbe.interior]." +"Équivalent à [member ReflectionProbe.interior_enable]." #: doc/classes/VisualServer.xml msgid "" @@ -84386,23 +86209,17 @@ msgid "" msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "Sets the ambient light color for this reflection probe when set to interior " "mode. Equivalent to [member ReflectionProbe.interior_ambient_color]." msgstr "" -"Si [code]true[/code], les réflexions ignoreront la contribution du ciel. " -"Équivalent à [member ReflectionProbe.interior]." #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "Sets the energy multiplier for this reflection probes ambient light " "contribution when set to interior mode. Equivalent to [member " "ReflectionProbe.interior_ambient_energy]." msgstr "" -"Si [code]true[/code], les réflexions ignoreront la contribution du ciel. " -"Équivalent à [member ReflectionProbe.interior]." #: doc/classes/VisualServer.xml msgid "" @@ -84520,9 +86337,8 @@ msgid "" msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Enables or disables occlusion culling." -msgstr "Active ou désactive une lumière du canevas." +msgstr "Active ou désactive le culling de l'occlusion." #: doc/classes/VisualServer.xml msgid "" @@ -84539,7 +86355,6 @@ msgstr "" "méthode statique [method free_rid] du VisualServer." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns a shader's code." msgstr "Retourne le code d'un shader." @@ -84552,7 +86367,6 @@ msgid "Returns the parameters of a shader." msgstr "Retourne les paramètres d'un shader." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Sets a shader's code." msgstr "Définit le code d'un shader." @@ -84637,14 +86451,12 @@ msgstr "" "utilisant la [method instance_set_base] utilisant le RID retourné." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Allocates the GPU memory for the texture." -msgstr "La largeur de la texture." +msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "Binds the texture to a texture slot." -msgstr "Alignez le texte à gauche." +msgstr "" #: doc/classes/VisualServer.xml msgid "" @@ -84667,9 +86479,8 @@ msgstr "" "Crée une texture, alloue l'espace pour une image, et remplit avec l'image." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns a list of all the textures and their information." -msgstr "Retourne le nombre de pistes dans l'animation." +msgstr "" #: doc/classes/VisualServer.xml msgid "" @@ -84688,9 +86499,8 @@ msgid "Returns the flags of a texture." msgstr "Retourne les drapeaux de la texture." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Returns the format of the texture's image." -msgstr "Renvoie le reste de deux vecteurs." +msgstr "" #: doc/classes/VisualServer.xml msgid "Returns the texture's height." @@ -84791,13 +86601,10 @@ msgid "" msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "If [code]true[/code], the image will be stored in the texture's images array " "if overwritten." msgstr "" -"Si [code]true[/code], la [SpinBox] sera modifiable. Sinon, elle sera en " -"lecture seule." #: doc/classes/VisualServer.xml msgid "Sets a viewport's camera." @@ -84808,7 +86615,6 @@ msgid "Sets a viewport's canvas." msgstr "Définit le canevas de la fenêtre d'affichage." #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "Copies viewport to a region of the screen specified by [code]rect[/code]. If " "[member Viewport.render_direct_to_screen] is [code]true[/code], then " @@ -84845,7 +86651,7 @@ msgstr "" " $Viewport.set_attach_to_screen_rect(Rect2(0, 0, 600, 600))\n" "[/codeblock]\n" "Utiliser cette méthode peut permettre d'améliorer considérablement les " -"performances, surtout sur les appareils peut puissants. Par contre, cela " +"performances, surtout sur les appareils peu puissants. Par contre, cela " "nécessite de gérer manuellement les fenêtres d'affichage. Pour plus " "d'optimisations, voir [method viewport_set_render_direct_to_screen]." @@ -84934,9 +86740,12 @@ msgstr "" "Définit la matrice de transformation globale de la fenêtre d'affichage." #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Si [code]true[/code], l'interpolation fait une boucle." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -85020,11 +86829,19 @@ msgid "" msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy msgid "" "Sets the viewport's 2D/3D mode. See [enum ViewportUsage] constants for " "options." -msgstr "Convertit le format de l’image. Voir les constantes [enum Format]." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "" @@ -85089,16 +86906,12 @@ msgid "Number of weights/bones per vertex." msgstr "Nombre de poids / os par sommet." #: doc/classes/VisualServer.xml -#, fuzzy msgid "The minimum Z-layer for canvas items." -msgstr "" -"Le niveau minimal du calque de profondeur pour les éléments de canevas." +msgstr "Le niveau minimal du calque de profondeur pour les éléments de canevas." #: doc/classes/VisualServer.xml -#, fuzzy msgid "The maximum Z-layer for canvas items." -msgstr "" -"Le niveau maximal du calque de profondeur pour les éléments de canevas." +msgstr "Le niveau maximal du calque de profondeur pour les éléments de canevas." #: doc/classes/VisualServer.xml msgid "" @@ -85160,7 +86973,6 @@ msgid "A 3-dimensional texture with width, height, and depth." msgstr "Une texture à 3 dimensions, largeur et hauteur, et profondeur." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Repeats the texture (instead of clamp to edge)." msgstr "Répète la texture (plutôt que de s'arrêter aux bordures)." @@ -85554,9 +87366,8 @@ msgid "Number of draw calls during this frame." msgstr "Nombre d'appels d'affichage pour cette trame." #: doc/classes/VisualServer.xml -#, fuzzy msgid "Number of 2d items drawn this frame." -msgstr "Nombre de changements de surface pendant cette image." +msgstr "Le nombre d'éléments 2D affichés dans cette trame." #: doc/classes/VisualServer.xml msgid "Number of 2d draw calls during this frame." @@ -86231,11 +88042,8 @@ msgstr "Sera traduit en [code]uniform bool[/code] dans le code du shader." #: doc/classes/VisualShaderNodeScalarUniform.xml #: doc/classes/VisualShaderNodeTransformUniform.xml #: doc/classes/VisualShaderNodeVec3Uniform.xml -#, fuzzy msgid "A default value to be assigned within the shader." msgstr "" -"Un opérateur scalaire à virgule flottante à utiliser dans le graphique du " -"nuanceur visuel." #: doc/classes/VisualShaderNodeBooleanUniform.xml #: doc/classes/VisualShaderNodeColorUniform.xml @@ -86528,7 +88336,6 @@ msgid "" msgstr "" #: doc/classes/VisualShaderNodeCompare.xml -#, fuzzy msgid "" "The result will be true if all of component in vector satisfy the comparison " "condition." @@ -86537,7 +88344,6 @@ msgstr "" "condition de comparaison." #: doc/classes/VisualShaderNodeCompare.xml -#, fuzzy msgid "" "The result will be true if any of component in vector satisfy the comparison " "condition." @@ -86546,11 +88352,8 @@ msgstr "" "condition de comparaison." #: doc/classes/VisualShaderNodeCubeMap.xml -#, fuzzy msgid "A [CubeMap] sampling node to be used within the visual shader graph." msgstr "" -"Un opérateur scalaire à virgule flottante à utiliser dans le graphique du " -"nuanceur visuel." #: doc/classes/VisualShaderNodeCubeMap.xml msgid "" @@ -86617,11 +88420,8 @@ msgid "" msgstr "" #: doc/classes/VisualShaderNodeCubeMapUniform.xml -#, fuzzy msgid "A [CubeMap] uniform node to be used within the visual shader graph." msgstr "" -"Un tableau uniforme de texture 2D à utiliser dans le graphique de l'ombrage " -"visuel." #: doc/classes/VisualShaderNodeCubeMapUniform.xml msgid "" @@ -87297,13 +89097,12 @@ msgid "Defaults to black color." msgstr "Par défaut à la couleur noire." #: doc/classes/VisualShaderNodeTextureUniformTriplanar.xml -#, fuzzy msgid "" "Performs a uniform texture lookup with triplanar within the visual shader " "graph." msgstr "" -"Effectue une recherche de texture uniforme avec triplanaire dans le " -"graphique de nuanceur visuel." +"Effectue une projection de texture uniforme en triplanaire dans le graphe du " +"Visual Shader." #: doc/classes/VisualShaderNodeTextureUniformTriplanar.xml msgid "" @@ -87312,12 +89111,11 @@ msgid "" msgstr "" #: doc/classes/VisualShaderNodeTransformCompose.xml -#, fuzzy msgid "" "Composes a [Transform] from four [Vector3]s within the visual shader graph." msgstr "" -"Compose un [Transform] à partir de quatre [Vector3] dans le graphique du " -"nuanceur visuel." +"Compose un [Transform] à partir de quatre [Vector3] dans le graphe du Visual " +"Shader." #: doc/classes/VisualShaderNodeTransformCompose.xml msgid "" @@ -87431,11 +89229,10 @@ msgid "Translated to [code]uniform mat4[/code] in the shader language." msgstr "Sera traduit en [code]uniform mat4[/code] dans le code du shader." #: doc/classes/VisualShaderNodeTransformVecMult.xml -#, fuzzy msgid "" "Multiplies a [Transform] and a [Vector3] within the visual shader graph." msgstr "" -"Multiplie un [Transform] et un [Vector3] dans le graphique de shader visuel." +"Multiplie un [Transform] et un [Vector3] dans le graphe du Visual Shader." #: doc/classes/VisualShaderNodeTransformVecMult.xml msgid "" @@ -87478,7 +89275,7 @@ msgstr "" #: doc/classes/VisualShaderNodeUniform.xml #, fuzzy msgid "A base type for the uniforms within the visual shader graph." -msgstr "Type de base pour les uniformes dans le graphique du nuanceur visuel." +msgstr "Le type de base pour les uniformes dans le graphe du Visual Shader." #: doc/classes/VisualShaderNodeUniform.xml msgid "" @@ -88035,10 +89832,9 @@ msgid "Closes this data channel, notifying the other peer." msgstr "Ferme ce canal de données, en notifiant l’autre homologue." #: modules/webrtc/doc_classes/WebRTCDataChannel.xml -#, fuzzy msgid "" "Returns the number of bytes currently queued to be sent over this channel." -msgstr "Retourne le nombre de traqueurs actuellement enregistrés." +msgstr "" #: modules/webrtc/doc_classes/WebRTCDataChannel.xml msgid "" @@ -88129,7 +89925,6 @@ msgid "The channel was created, but it's still trying to connect." msgstr "Le canal a été créé, mais il essaie toujours de se connecter." #: modules/webrtc/doc_classes/WebRTCDataChannel.xml -#, fuzzy msgid "The channel is currently open, and data can flow over it." msgstr "Le canal est actuellement ouvert, et les données peuvent y circuler." @@ -88238,9 +90033,8 @@ msgid "" msgstr "" #: modules/webrtc/doc_classes/WebRTCPeerConnection.xml -#, fuzzy msgid "Interface to a WebRTC peer connection." -msgstr "Interface vers une connexion homologue WebRTC." +msgstr "L'interface de connexion par pair via WebRTC." #: modules/webrtc/doc_classes/WebRTCPeerConnection.xml msgid "" @@ -89294,14 +91088,12 @@ msgid "" msgstr "" #: doc/classes/WindowDialog.xml -#, fuzzy msgid "The vertical offset of the title text." -msgstr "Décalage vertical du texte du titre." +msgstr "Le décalage vertical du texte du titre." #: doc/classes/WindowDialog.xml -#, fuzzy msgid "The font used to draw the title." -msgstr "La police utilisée pour le texte en gras." +msgstr "" #: doc/classes/WindowDialog.xml msgid "The icon for the close button." @@ -89347,10 +91139,9 @@ msgid "" msgstr "" #: doc/classes/World.xml -#, fuzzy msgid "" "The [RID] of this world's navigation map. Used by the [NavigationServer]." -msgstr "Retourne le [RID] de la énième forme d'une zone." +msgstr "" #: doc/classes/World.xml msgid "The World's visual scenario." @@ -89385,10 +91176,9 @@ msgid "" msgstr "" #: doc/classes/World2D.xml -#, fuzzy msgid "" "The [RID] of this world's navigation map. Used by the [Navigation2DServer]." -msgstr "Retourne le [RID] de la énième forme d'une zone." +msgstr "" #: doc/classes/World2D.xml msgid "" diff --git a/doc/translations/gl.po b/doc/translations/gl.po index 17fb042ad7..207a818761 100644 --- a/doc/translations/gl.po +++ b/doc/translations/gl.po @@ -848,7 +848,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7685,8 +7692,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11754,7 +11761,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20165,7 +20177,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23551,7 +23563,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25382,7 +25394,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32478,7 +32490,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32494,7 +32506,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32524,7 +32536,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36624,7 +36636,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36885,7 +36897,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36999,6 +37011,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39696,7 +39754,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39708,7 +39772,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57462,7 +57527,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60353,8 +60418,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63977,13 +64042,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63995,13 +64061,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70887,7 +70954,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70972,6 +71043,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/hi.po b/doc/translations/hi.po index 98778940cf..2df4b9bbe4 100644 --- a/doc/translations/hi.po +++ b/doc/translations/hi.po @@ -847,7 +847,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7684,8 +7691,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11753,7 +11760,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20164,7 +20176,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23550,7 +23562,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25381,7 +25393,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32477,7 +32489,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32493,7 +32505,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32523,7 +32535,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36623,7 +36635,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36884,7 +36896,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36998,6 +37010,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39695,7 +39753,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39707,7 +39771,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57461,7 +57526,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60352,8 +60417,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63976,13 +64041,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63994,13 +64060,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70886,7 +70953,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70971,6 +71042,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/hu.po b/doc/translations/hu.po index 325d7d0f52..221206451a 100644 --- a/doc/translations/hu.po +++ b/doc/translations/hu.po @@ -866,7 +866,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7703,8 +7710,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11772,7 +11779,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20183,7 +20195,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23569,7 +23581,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25400,7 +25412,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32496,7 +32508,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32512,7 +32524,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32542,7 +32554,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36642,7 +36654,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36903,7 +36915,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37017,6 +37029,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39714,7 +39772,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39726,7 +39790,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57480,7 +57545,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60371,8 +60436,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63995,13 +64060,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64013,13 +64079,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70905,7 +70972,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70990,6 +71061,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/id.po b/doc/translations/id.po index eb95a98f22..39310a6160 100644 --- a/doc/translations/id.po +++ b/doc/translations/id.po @@ -1199,10 +1199,22 @@ msgstr "" "atau peringatan dicetak." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Seperti [metode cetak], tetapi hanya mencetak saat digunakan dalam mode " -"debug." +"Mencetak trek tumpukan di lokasi kode, hanya berfungsi saat dijalankan " +"dengan debugger dihidupkan.\n" +"Output di konsol akan terlihat seperti ini:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 dalam fungsi '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml #, fuzzy @@ -8097,8 +8109,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12166,7 +12178,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20579,7 +20596,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23969,7 +23986,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25806,7 +25823,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32903,7 +32920,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32919,7 +32936,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32949,7 +32966,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37070,7 +37087,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37331,7 +37348,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37447,6 +37464,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40144,7 +40207,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40156,7 +40225,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57931,7 +58001,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60828,8 +60898,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64453,13 +64523,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64471,13 +64542,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71368,7 +71440,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71453,6 +71529,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/is.po b/doc/translations/is.po index c68a096dfa..e3080abf39 100644 --- a/doc/translations/is.po +++ b/doc/translations/is.po @@ -847,7 +847,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7684,8 +7691,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11753,7 +11760,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20164,7 +20176,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23550,7 +23562,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25381,7 +25393,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32477,7 +32489,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32493,7 +32505,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32523,7 +32535,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36623,7 +36635,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36884,7 +36896,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36998,6 +37010,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39695,7 +39753,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39707,7 +39771,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57461,7 +57526,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60352,8 +60417,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63976,13 +64041,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63994,13 +64060,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70886,7 +70953,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70971,6 +71042,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/it.po b/doc/translations/it.po index fd78bc8f1c..e07c906b29 100644 --- a/doc/translations/it.po +++ b/doc/translations/it.po @@ -25,12 +25,13 @@ # Andrea Leganza <neogene@gmail.com>, 2021. # Federico Caprini <caprinifede@gmail.com>, 2022. # Alessandro Casalino <alessandro.casalino93@gmail.com>, 2022. +# AndreWharn <andrewharnofficial@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-04-25 15:12+0000\n" -"Last-Translator: Micila Micillotto <micillotto@gmail.com>\n" +"PO-Revision-Date: 2022-07-31 16:43+0000\n" +"Last-Translator: Mirko <miknsop@gmail.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/it/>\n" "Language: it\n" @@ -38,7 +39,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.12.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -61,6 +62,7 @@ msgid "Theme Properties" msgstr "Proprietà del tema" #: doc/tools/make_rst.py +#, fuzzy msgid "Signals" msgstr "Segnali" @@ -101,18 +103,16 @@ msgid "Default" msgstr "Predefinito" #: doc/tools/make_rst.py -#, fuzzy msgid "Setter" -msgstr "Impostatore" +msgstr "Setter" #: doc/tools/make_rst.py msgid "value" msgstr "valore" #: doc/tools/make_rst.py -#, fuzzy msgid "Getter" -msgstr "Acchiappatore" +msgstr "Getter" #: doc/tools/make_rst.py msgid "" @@ -137,9 +137,8 @@ msgstr "" "qui." #: doc/tools/make_rst.py -#, fuzzy msgid "This method is used to construct a type." -msgstr "Questo metodo viene utilizzato per creare un tipo di variabile." +msgstr "Questo metodo viene utilizzato per creare un tipo." #: doc/tools/make_rst.py msgid "" @@ -1372,10 +1371,22 @@ msgstr "" "messaggi di debug ed errore che vengono mostrati con la stack trace." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Come [method print], ma stampa solo quando viene utilizzato in modalità " -"debug." +"Stampa un stack trace nella posizione del codice, funziona solo quando il " +"debugger è attivato.\n" +"L'output nella console apparirà come:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8702,8 +8713,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12783,7 +12794,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -21303,7 +21319,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24703,7 +24719,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -26543,7 +26559,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33683,7 +33699,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33699,7 +33715,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33732,7 +33748,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37884,7 +37900,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -38148,7 +38164,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -38267,6 +38283,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40972,7 +41034,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40984,7 +41052,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -56892,7 +56961,7 @@ msgstr "" #: doc/classes/Spatial.xml msgid "Introduction to 3D" -msgstr "" +msgstr "Introduzione al 3D" #: doc/classes/Spatial.xml doc/classes/Vector3.xml msgid "All 3D Demos" @@ -58807,7 +58876,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61723,8 +61792,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -65387,13 +65456,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -65405,13 +65475,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -72367,11 +72438,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" -"Se [code] vero [/code], i nodi figli sono ordinati, altrimenti l'ordinamento " -"è disabilitato." #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -72455,6 +72527,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ja.po b/doc/translations/ja.po index 324df4d9ae..fe76c741d0 100644 --- a/doc/translations/ja.po +++ b/doc/translations/ja.po @@ -1333,8 +1333,22 @@ msgstr "" "たときにスタックトレースを表示することができます。" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "[method print] と同様ですが、しかしデバッグモード時にのみ表示します。" +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" +"コード位置のスタックトラックを表示します。デバッガを有効にして実行した時にの" +"み動作します。\n" +"コンソール内での出力はこのようになります:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -9918,8 +9932,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -14717,7 +14731,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -23302,7 +23321,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -26725,7 +26744,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -28567,7 +28586,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -35779,7 +35798,7 @@ msgstr "円柱の高さ。" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -35795,7 +35814,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -35831,7 +35850,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -40028,7 +40047,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -40295,7 +40314,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -40416,6 +40435,53 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "Set the max packet size that this peer can handle." +msgstr "指定された名前のアニメーションノードを返します。" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -43124,7 +43190,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -43136,7 +43208,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -61336,7 +61409,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -64289,8 +64362,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -67983,13 +68056,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -68001,13 +68075,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -75036,9 +75111,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "[code]true[/code]の場合、頂点色をアルベド色として使用します。" +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -75122,6 +75200,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ko.po b/doc/translations/ko.po index 2f6879593c..ac9274cee6 100644 --- a/doc/translations/ko.po +++ b/doc/translations/ko.po @@ -1004,7 +1004,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7859,8 +7866,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11931,7 +11938,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20452,7 +20464,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23844,7 +23856,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25682,7 +25694,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32792,7 +32804,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32808,7 +32820,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32838,7 +32850,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36972,7 +36984,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37235,7 +37247,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37353,6 +37365,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40176,7 +40234,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40188,7 +40252,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57973,7 +58038,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60874,8 +60939,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64507,13 +64572,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64525,13 +64591,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71452,7 +71519,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71537,6 +71608,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/lt.po b/doc/translations/lt.po index 2468d389d3..79790f5e70 100644 --- a/doc/translations/lt.po +++ b/doc/translations/lt.po @@ -857,7 +857,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7694,8 +7701,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11763,7 +11770,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20174,7 +20186,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23560,7 +23572,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25391,7 +25403,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32487,7 +32499,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32503,7 +32515,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32533,7 +32545,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36633,7 +36645,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36894,7 +36906,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37008,6 +37020,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39705,7 +39763,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39717,7 +39781,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57471,7 +57536,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60362,8 +60427,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63986,13 +64051,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64004,13 +64070,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70896,7 +70963,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70981,6 +71052,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/lv.po b/doc/translations/lv.po index 9faf7fd017..1f63bf69bb 100644 --- a/doc/translations/lv.po +++ b/doc/translations/lv.po @@ -862,7 +862,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7699,8 +7706,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11768,7 +11775,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20179,7 +20191,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23568,7 +23580,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25399,7 +25411,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32495,7 +32507,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32511,7 +32523,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32541,7 +32553,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36641,7 +36653,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36902,7 +36914,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37016,6 +37028,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39713,7 +39771,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39725,7 +39789,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57479,7 +57544,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60370,8 +60435,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63994,13 +64059,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64012,13 +64078,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70904,7 +70971,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70989,6 +71060,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/mr.po b/doc/translations/mr.po index c989fcc549..32832a4d8f 100644 --- a/doc/translations/mr.po +++ b/doc/translations/mr.po @@ -845,7 +845,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7682,8 +7689,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11751,7 +11758,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20162,7 +20174,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23548,7 +23560,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25379,7 +25391,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32475,7 +32487,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32491,7 +32503,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32521,7 +32533,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36621,7 +36633,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36882,7 +36894,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36996,6 +37008,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39693,7 +39751,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39705,7 +39769,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57459,7 +57524,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60350,8 +60415,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63974,13 +64039,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63992,13 +64058,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70884,7 +70951,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70969,6 +71040,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/nb.po b/doc/translations/nb.po index 8017f4006b..42dca83c45 100644 --- a/doc/translations/nb.po +++ b/doc/translations/nb.po @@ -857,7 +857,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7694,8 +7701,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11763,7 +11770,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20174,7 +20186,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23560,7 +23572,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25391,7 +25403,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32487,7 +32499,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32503,7 +32515,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32533,7 +32545,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36633,7 +36645,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36894,7 +36906,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37008,6 +37020,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39705,7 +39763,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39717,7 +39781,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57471,7 +57536,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60362,8 +60427,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63986,13 +64051,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64004,13 +64070,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70896,7 +70963,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70981,6 +71052,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ne.po b/doc/translations/ne.po index 9a17a51fb6..0ba02ba939 100644 --- a/doc/translations/ne.po +++ b/doc/translations/ne.po @@ -845,7 +845,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7682,8 +7689,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11751,7 +11758,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20162,7 +20174,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23548,7 +23560,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25379,7 +25391,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32475,7 +32487,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32491,7 +32503,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32521,7 +32533,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36621,7 +36633,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36882,7 +36894,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36996,6 +37008,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39693,7 +39751,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39705,7 +39769,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57459,7 +57524,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60350,8 +60415,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63974,13 +64039,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63992,13 +64058,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70884,7 +70951,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70969,6 +71040,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/nl.po b/doc/translations/nl.po index d36175b6c2..3053cadb2b 100644 --- a/doc/translations/nl.po +++ b/doc/translations/nl.po @@ -906,7 +906,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7751,8 +7758,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11820,7 +11827,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20231,7 +20243,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23620,7 +23632,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25451,7 +25463,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32547,7 +32559,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32563,7 +32575,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32593,7 +32605,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36693,7 +36705,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36954,7 +36966,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37068,6 +37080,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39765,7 +39823,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39777,7 +39841,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57532,7 +57597,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60423,8 +60488,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64047,13 +64112,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64065,13 +64131,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70957,7 +71024,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71042,6 +71113,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/pl.po b/doc/translations/pl.po index 343dfb0050..729b6a654c 100644 --- a/doc/translations/pl.po +++ b/doc/translations/pl.po @@ -1279,8 +1279,22 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "Jak [method print], ale wypisuje tylko w trybie debugowania." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" +"Wypisuje zrzut stosu w miejscu kodu, działa tylko przy uruchamianiu z " +"włączonym debuggerem.\n" +"Wynik w konsoli wyglądać może tak:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8189,8 +8203,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12262,7 +12276,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20703,7 +20722,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24102,7 +24121,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25939,7 +25958,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33076,7 +33095,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33092,7 +33111,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33125,7 +33144,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37281,7 +37300,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37545,7 +37564,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37664,6 +37683,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40361,7 +40426,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40373,7 +40444,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58195,7 +58267,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61097,8 +61169,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64744,13 +64816,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64762,13 +64835,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71696,11 +71770,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" -"Jeśli [code]true[/code], potomne węzły są sortowane. W innym przypadku jest " -"wyłączone." #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -71784,6 +71859,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/pt.po b/doc/translations/pt.po index fdb01b1579..c99a8e1cd6 100644 --- a/doc/translations/pt.po +++ b/doc/translations/pt.po @@ -1340,9 +1340,22 @@ msgstr "" "rastreamento de pilha quando um erro ou aviso é impresso ." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Igual [method print], mas só imprime quando usado em modo de depuração." +"Imprime a pilha de chamadas no local do código, só funciona com o depurador " +"ativado.\n" +"Saída no console vai parecer assim:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8506,8 +8519,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12580,7 +12593,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -21038,7 +21056,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24434,7 +24452,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -26271,7 +26289,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33383,7 +33401,7 @@ msgstr "A altura do cilindro." msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33399,7 +33417,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33430,7 +33448,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37559,7 +37577,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37824,7 +37842,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37942,6 +37960,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40639,7 +40703,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40651,7 +40721,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58499,7 +58570,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61396,8 +61467,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -65035,13 +65106,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -65053,13 +65125,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71954,7 +72027,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -72039,6 +72116,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/pt_BR.po b/doc/translations/pt_BR.po index 50d4359c46..ea624fdf2c 100644 --- a/doc/translations/pt_BR.po +++ b/doc/translations/pt_BR.po @@ -41,12 +41,13 @@ # Fabio Moura de Oliveira <ccmaismais@yahoo.com>, 2022. # Daniel Abrante <danielabrante@protonmail.com>, 2022. # lucas rossy brasil coelho <lucasrossy270@gmail.com>, 2022. +# Felipe Kinoshita <kinofhek@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-06-16 18:58+0000\n" -"Last-Translator: lucas rossy brasil coelho <lucasrossy270@gmail.com>\n" +"PO-Revision-Date: 2022-08-04 06:40+0000\n" +"Last-Translator: Felipe Kinoshita <kinofhek@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" "godot-engine/godot-class-reference/pt_BR/>\n" "Language: pt_BR\n" @@ -54,7 +55,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.13-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -1368,9 +1369,22 @@ msgstr "" "rastreamento de pilha quando um erro ou aviso é impresso ." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Igual [method print], mas só imprime quando usado em modo de depuração." +"Imprime a pilha de chamadas no local do código, só funciona com o depurador " +"habilitado.\n" +"Saída no console vai parecer assim:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8742,8 +8756,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12820,7 +12834,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -21332,7 +21351,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24735,7 +24754,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -26574,7 +26593,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33720,7 +33739,7 @@ msgstr "A altura do cilindro." msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33736,7 +33755,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33769,7 +33788,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37925,7 +37944,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -38191,7 +38210,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -38310,6 +38329,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -41007,7 +41072,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -41019,7 +41090,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58868,7 +58940,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61780,8 +61852,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -65433,13 +65505,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -65451,13 +65524,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -72389,11 +72463,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" -"Se [code]true[/code], os nós filhos são organizados, do contrário, a " -"organização é desabilitada." #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -72477,6 +72552,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" @@ -76671,6 +76755,13 @@ msgid "" "the same space as the parent YSort, allowing to better organize a scene or " "divide it in multiple ones, yet keep the unique sorting." msgstr "" +"Classifique todos os nós filhos com base em suas posições Y. O nó filho deve " +"herdar de [CanvasItem] para ser classificado. Os nós que têm uma posição Y " +"mais alta serão desenhados mais tarde, então eles aparecerão no topo dos nós " +"que têm uma posição Y mais baixa. O aninhamento de nós YSort é possível. Os " +"nós YSort filhos serão classificados no mesmo espaço que o YSort pai, " +"permitindo organizar melhor uma cena ou dividi-la em várias outras, mas " +"manter a classificação única." #: doc/classes/YSort.xml msgid "" diff --git a/doc/translations/ro.po b/doc/translations/ro.po index 8c7112f102..332dbd0801 100644 --- a/doc/translations/ro.po +++ b/doc/translations/ro.po @@ -873,7 +873,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7714,8 +7721,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11783,7 +11790,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20194,7 +20206,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23583,7 +23595,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25414,7 +25426,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32510,7 +32522,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32526,7 +32538,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32556,7 +32568,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36656,7 +36668,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36917,7 +36929,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37032,6 +37044,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39729,7 +39787,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39741,7 +39805,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57495,7 +57560,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60386,8 +60451,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64010,13 +64075,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64028,13 +64094,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70920,7 +70987,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71005,6 +71076,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ru.po b/doc/translations/ru.po index 1596ca8553..b148868ce6 100644 --- a/doc/translations/ru.po +++ b/doc/translations/ru.po @@ -49,21 +49,22 @@ # FuzzMix <fmwolfiechad@gmail.com>, 2022. # МАН69К <weblate@mah69k.net>, 2022. # Vadim Mitroshkin <Vadim7540@yandex.ru>, 2022. +# SonicStalker Games <dmitriyusolsev1971@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-07-03 00:44+0000\n" -"Last-Translator: Bozhko Artyom Dmitrievich <jek_sun@mail.ru>\n" +"PO-Revision-Date: 2022-08-04 06:40+0000\n" +"Last-Translator: SonicStalker Games <dmitriyusolsev1971@gmail.com>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/ru/>\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -620,11 +621,11 @@ msgstr "" "[codeblock]\n" "- Меньше -1,0 (не включая): Облегчение вхождения-выхождения\n" "- 1.0: Линейный\n" -"- От -1,0 до 0,0 (не включая): Облегчение в\n" +"- От -1,0 до 0,0 (не включая): Облегчение выхождения-вхождения\n" "- 0.0: Постоянный\n" -"- От 0,0 до 1,0 (не включая): Облегчение\n" +"- От 0,0 до 1,0 (не включая): Облегчение выхождения(только выход)\n" "- 1.0: Линейный\n" -"- Больше 1,0 (не включая): Облегчение\n" +"- Больше 1,0 (не включая): Облегчение вхождения(только вход)\n" "[/codeblock]\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/" "ease_cheatsheet.png]ease() значения кривой шпаргалка[/url]\n" @@ -1402,8 +1403,22 @@ msgstr "" "трассировка стека при печати ошибки или предупреждения." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "Как [method print], но печатает только в режиме отладки." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" +"Как [method print], но включает в себя текущий кадр стека когда запушен с " +"включенным отладчиком.\n" +"Вывод в консоли будет выглядеть примерно так:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -1817,19 +1832,30 @@ msgstr "" "Возвращает результат плавной интерполяции значения [code]s[/code] между " "[code]0[/code] и [code]1[/code], в зависимости от того, где находится " "[code]s[/code] относительно [code]from[/code] и [code]to[/code].\n" +"\n" "Возвращаемое значение равно [code]0[/code], если [code]s <= from[/code] и " "[code]1[/code], если[code]s >= to[/code]. Если [code]s[/code] находится " "между [code]from[/code] и [code]to[/code], то возвращаемое значение следует " "S-образной кривой, которая соответствует значению [code]s[/code] между " "[code]0[/code] и [code]1[/code].\n" +"\n" "S-образная кривая является кубическим эрмитовым сплайном, заданным функцией " "[code]f(s) = 3*s^2 - 2*s^3[/code].\n" +"\n" "[codeblock]\n" "smoothstep(0, 2, -5.0) # Returns 0.0\n" "smoothstep(0, 2, 0.5) # Returns 0.15625\n" "smoothstep(0, 2, 1.0) # Returns 0.5\n" "smoothstep(0, 2, 2.0) # Returns 1.0\n" -"[/codeblock]" +"[/codeblock]\n" +"\n" +"Compared to [method ease] with a curve value of [code]-1.6521[/code], [" +"method smoothstep] returns the smoothest possible curve with no sudden " +"changes in the derivative. If you need to perform more advanced transitions, " +"use [Tween] or [AnimationPlayer].\n" +"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/" +"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, -1" +".6521) return values[/url]" #: modules/gdscript/doc_classes/@GDScript.xml #, fuzzy @@ -9352,8 +9378,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -13447,7 +13473,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -22008,7 +22039,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -25419,7 +25450,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -27259,7 +27290,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -34416,7 +34447,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -34432,7 +34463,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -34465,7 +34496,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -38625,7 +38656,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -38890,7 +38921,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -39022,6 +39053,53 @@ msgstr "" msgid "Control activation of this server." msgstr "Управление активацией данного сервера." +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "Set the max packet size that this peer can handle." +msgstr "Возвращает длину вектора." + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml #, fuzzy msgid "" @@ -41794,7 +41872,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -41806,7 +41890,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -59734,7 +59819,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -62675,8 +62760,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -66352,15 +66437,16 @@ msgstr "" #: doc/classes/TreeItem.xml #, fuzzy msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" "Возвращает последний элемент массива, или[code]null[/code] если массив " "пустой." #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -66373,15 +66459,16 @@ msgstr "" #: doc/classes/TreeItem.xml #, fuzzy msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" "Возвращает первый элемент в массиве, или [code]null[/code] если массив " "пустой." #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -73453,9 +73540,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Если [code]true[/code], текстура будет центрирована." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -73539,6 +73629,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/sk.po b/doc/translations/sk.po index 38e701eef9..ddcdeb10f1 100644 --- a/doc/translations/sk.po +++ b/doc/translations/sk.po @@ -848,7 +848,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7685,8 +7692,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11754,7 +11761,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20165,7 +20177,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23554,7 +23566,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25385,7 +25397,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32481,7 +32493,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32497,7 +32509,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32527,7 +32539,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36627,7 +36639,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36888,7 +36900,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37002,6 +37014,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39699,7 +39757,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39711,7 +39775,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57465,7 +57530,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60356,8 +60421,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63980,13 +64045,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63998,13 +64064,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70890,7 +70957,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70975,6 +71046,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/sr_Cyrl.po b/doc/translations/sr_Cyrl.po index 3984d209f4..6a336f195b 100644 --- a/doc/translations/sr_Cyrl.po +++ b/doc/translations/sr_Cyrl.po @@ -859,7 +859,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7696,8 +7703,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11765,7 +11772,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20176,7 +20188,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23565,7 +23577,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25396,7 +25408,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32492,7 +32504,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32508,7 +32520,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32538,7 +32550,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36638,7 +36650,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36899,7 +36911,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37013,6 +37025,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39710,7 +39768,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39722,7 +39786,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57476,7 +57541,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60367,8 +60432,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63991,13 +64056,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64009,13 +64075,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70901,7 +70968,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70986,6 +71057,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/sv.po b/doc/translations/sv.po index 9be24493d7..b582952401 100644 --- a/doc/translations/sv.po +++ b/doc/translations/sv.po @@ -6,12 +6,13 @@ # Christoffer Sundbom <christoffer_karlsson@live.se>, 2021. # Kent Jofur <kent.jofur@gmail.com>, 2021. # Alex25820 <alexs25820@gmail.com>, 2021. +# Björn Åkesson <bjorn.akesson@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2021-12-19 17:31+0000\n" -"Last-Translator: Alex25820 <alexs25820@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:56+0000\n" +"Last-Translator: Björn Åkesson <bjorn.akesson@gmail.com>\n" "Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/sv/>\n" "Language: sv\n" @@ -19,7 +20,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.10\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -92,7 +93,7 @@ msgstr "" #: doc/tools/make_rst.py msgid "Getter" -msgstr "" +msgstr "Getter" #: doc/tools/make_rst.py msgid "" @@ -848,7 +849,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7685,8 +7693,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11754,7 +11762,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20165,7 +20178,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23551,7 +23564,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25382,7 +25395,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32478,7 +32491,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32494,7 +32507,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32524,7 +32537,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36624,7 +36637,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36885,7 +36898,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36999,6 +37012,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -37553,7 +37612,7 @@ msgstr "" #: doc/classes/Node.xml msgid "Nodes and Scenes" -msgstr "" +msgstr "Noder och scener" #: doc/classes/Node.xml msgid "All Demos" @@ -39696,7 +39755,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39708,7 +39773,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57462,7 +57528,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60353,8 +60419,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63977,13 +64043,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63995,13 +64062,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70887,7 +70955,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70972,6 +71044,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/th.po b/doc/translations/th.po index dabf3c09f3..3b8c2afd36 100644 --- a/doc/translations/th.po +++ b/doc/translations/th.po @@ -933,7 +933,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7790,8 +7797,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11860,7 +11867,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20275,7 +20287,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23665,7 +23677,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25500,7 +25512,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32650,7 +32662,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32666,7 +32678,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32696,7 +32708,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36813,7 +36825,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37074,7 +37086,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37191,6 +37203,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39938,7 +39996,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39950,7 +40014,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57724,7 +57789,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60621,8 +60686,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64246,13 +64311,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64264,13 +64330,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71172,7 +71239,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71257,6 +71328,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/tl.po b/doc/translations/tl.po index b100d0e612..6fe51a2de6 100644 --- a/doc/translations/tl.po +++ b/doc/translations/tl.po @@ -924,7 +924,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7761,8 +7768,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11834,7 +11841,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20248,7 +20260,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23640,7 +23652,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25471,7 +25483,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32573,7 +32585,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32589,7 +32601,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32622,7 +32634,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36737,7 +36749,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36998,7 +37010,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37112,6 +37124,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39809,7 +39867,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39821,7 +39885,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57578,7 +57643,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60469,8 +60534,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64102,13 +64167,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64120,13 +64186,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71015,7 +71082,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71100,6 +71171,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/tr.po b/doc/translations/tr.po index dc9d2524b7..ffa15621df 100644 --- a/doc/translations/tr.po +++ b/doc/translations/tr.po @@ -20,12 +20,13 @@ # Ramazan Aslan <legendraslan@gmail.com>, 2022. # paledega <paledega@yandex.ru>, 2022. # Yekez <yasintonge@gmail.com>, 2022. +# Deleted User <noreply+46858@weblate.org>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-07-03 00:45+0000\n" -"Last-Translator: Yekez <yasintonge@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:56+0000\n" +"Last-Translator: Deleted User <noreply+46858@weblate.org>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/tr/>\n" "Language: tr\n" @@ -33,7 +34,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -96,7 +97,6 @@ msgid "Default" msgstr "Varsayılan" #: doc/tools/make_rst.py -#, fuzzy msgid "Setter" msgstr "Ayarlayıcı" @@ -105,7 +105,6 @@ msgid "value" msgstr "değer" #: doc/tools/make_rst.py -#, fuzzy msgid "Getter" msgstr "Alıcı" @@ -1315,10 +1314,22 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"[method print] yöntemi gibidir fakat yanlız hata ayıklama (debug) modunda " -"kullanılır." +"Kod içindeki istiflenme konumunu yazdırır ve yanlızca hata ayıklayıcı " +"(debugger) açıkken çalışır.\n" +"Konsoldaki çıktı aşağıdaki gibi bir şey olacaktır.\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8471,8 +8482,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12543,7 +12554,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20978,7 +20994,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24374,7 +24390,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -26215,7 +26231,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33330,7 +33346,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33346,7 +33362,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33378,7 +33394,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37520,7 +37536,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37784,7 +37800,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37903,6 +37919,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40600,7 +40662,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40612,7 +40680,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58417,7 +58486,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61318,8 +61387,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64955,13 +65024,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64973,13 +65043,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71895,10 +71966,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" -"Eğer [code]true[/code] ise düğümler sıraya sokulur, yoksa sıraya sokulmaz." #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -71982,6 +72055,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/uk.po b/doc/translations/uk.po index afedf189b4..b1272c6b3e 100644 --- a/doc/translations/uk.po +++ b/doc/translations/uk.po @@ -991,7 +991,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7843,8 +7850,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11916,7 +11923,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20344,7 +20356,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23733,7 +23745,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25570,7 +25582,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32680,7 +32692,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32696,7 +32708,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32726,7 +32738,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36863,7 +36875,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37126,7 +37138,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37244,6 +37256,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39941,7 +39999,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39953,7 +40017,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57742,7 +57807,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60644,8 +60709,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64279,13 +64344,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64297,13 +64363,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71215,7 +71282,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71300,6 +71371,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/vi.po b/doc/translations/vi.po index ab16aa1782..60ab8769ab 100644 --- a/doc/translations/vi.po +++ b/doc/translations/vi.po @@ -1202,8 +1202,15 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "Giống [method print], nhưng chỉ in khi sử dụng trong chế độ gỡ lỗi." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8138,8 +8145,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12211,7 +12218,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20643,7 +20655,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24035,7 +24047,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25872,7 +25884,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32980,7 +32992,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32996,7 +33008,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33027,7 +33039,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37165,7 +37177,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37429,7 +37441,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37548,6 +37560,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40245,7 +40303,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40257,7 +40321,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58065,7 +58130,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60966,8 +61031,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64603,13 +64668,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64621,13 +64687,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71550,9 +71617,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Nếu [code]true[/code], họa tiết sẽ được căn ở trung tâm." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -71636,6 +71706,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/zh_CN.po b/doc/translations/zh_CN.po index d2179a01f2..7647bf0081 100644 --- a/doc/translations/zh_CN.po +++ b/doc/translations/zh_CN.po @@ -62,7 +62,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-07-17 07:14+0000\n" +"PO-Revision-Date: 2022-07-31 16:43+0000\n" "Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot-class-reference/zh_Hans/>\n" @@ -645,7 +645,7 @@ msgstr "" "a = floor(2.99) # a = 2.0\n" "a = floor(-2.99) # a = -3.0\n" "[/codeblock]\n" -"请参阅 [method ceil]、[method round]、[method stepify] 和 [int]。\n" +"另请参阅 [method ceil]、[method round]、[method stepify] 和 [int]。\n" "[b]注意:[/b]该方法返回一个浮点数。如果你需要整数,而 [code]s[/code] 是非负" "数,你可以直接使用 [code]int(s)[/code]。" @@ -1322,8 +1322,21 @@ msgstr "" "在打印错误或警告时还会显示堆栈跟踪。" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "与 [method print] 类似,但仅在调试模式下使用时才打印。" +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" +"与 [method print] 类似,但在打开调试器运行时还会包含当前栈帧。\n" +"控制台中的输出应该是类似这样的:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -9570,14 +9583,13 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" -"控制器振动的程度。范围从 [code]0.0[/code] 到 [code]1.0[/code],精度 " -"[code].01[/code]。如果更改,会相应地更新 [member ARVRPositionalTracker." -"rumble]。\n" +"控制器振动的程度。范围从 [code]0.0[/code] 到 [code]1.0[/code]。如果更改," +"会相应地更新 [member ARVRPositionalTracker.rumble]。\n" "如果你想让控制器在限定时间内振动,这是一个有用的属性,可以将其动画化。" #: doc/classes/ARVRController.xml @@ -12380,6 +12392,10 @@ msgid "" "name can't be resolved at runtime, it will fall back to [code]\"Master\"[/" "code]." msgstr "" +"这个音频在哪个总线上播放。\n" +"[b]注意:[/b]设置这个属性时,请记住它并不会对给定的名称是否与现有总线匹配进行" +"校验。这是因为音频总线布局可以在设置这个属性后再加载。如果这个给定的名称在运" +"行时无法解析,就会回退到 [code]\"Master\"[/code]。" #: doc/classes/AudioStreamPlayer.xml msgid "" @@ -12580,6 +12596,10 @@ msgid "" "name can't be resolved at runtime, it will fall back to [code]\"Master\"[/" "code]." msgstr "" +"播放音频的总线。\n" +"[b]注意:[/b]设置这个属性时,请记住它并不会对给定的名称是否与现有总线匹配进行" +"校验。这是因为音频总线布局可以在设置这个属性后再加载。如果这个给定的名称在运" +"行时无法解析,就会回退到 [code]\"Master\"[/code]。" #: doc/classes/AudioStreamPlayer3D.xml msgid "" @@ -14560,9 +14580,17 @@ msgstr "描述此相机渲染哪些 3D 渲染层的剔除掩码。" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" -"如果为 [code]true[/code],则说明祖级的 [Viewport] 当前正在使用这个摄像头。" +"如果为 [code]true[/code],则祖级 [Viewport] 正在使用这个相机。\n" +"如果场景中有多个相机,总会有一个被设为当前相机。例如,假设场景中存在两个 " +"[Camera] 节点并且只有一个为当前相机,那么如果把某一个相机的 [member current] " +"设为 [code]false[/code] 就会导致另一个相机被设为当前相机。" #: doc/classes/Camera.xml msgid "" @@ -17959,7 +17987,7 @@ msgstr "道奇蓝色。" #: doc/classes/Color.xml msgid "Firebrick color." -msgstr "火砖的颜色。" +msgstr "耐火砖红色。" #: doc/classes/Color.xml msgid "Floral white color." @@ -17971,11 +17999,11 @@ msgstr "森林绿色。" #: doc/classes/Color.xml msgid "Fuchsia color." -msgstr "紫红色的颜色。" +msgstr "洋红色。" #: doc/classes/Color.xml msgid "Gainsboro color." -msgstr "庚斯伯勒颜色。" +msgstr "庚斯伯勒灰色。" #: doc/classes/Color.xml msgid "Ghost white color." @@ -17987,7 +18015,7 @@ msgstr "金色。" #: doc/classes/Color.xml msgid "Goldenrod color." -msgstr "金黄的颜色。" +msgstr "金菊色。" #: doc/classes/Color.xml msgid "Gray color." @@ -18007,7 +18035,7 @@ msgstr "蜜露色。" #: doc/classes/Color.xml msgid "Hot pink color." -msgstr "炙热的粉红色。" +msgstr "亮粉色。" #: doc/classes/Color.xml msgid "Indian red color." @@ -18031,7 +18059,7 @@ msgstr "薰衣草色。" #: doc/classes/Color.xml msgid "Lavender blush color." -msgstr "薰衣草腮红的颜色。" +msgstr "薰衣草紫红色。" #: doc/classes/Color.xml msgid "Lawn green color." @@ -18055,7 +18083,7 @@ msgstr "淡青色。" #: doc/classes/Color.xml msgid "Light goldenrod color." -msgstr "淡淡的金黄色。" +msgstr "亮金菊黄色。" #: doc/classes/Color.xml msgid "Light gray color." @@ -22909,7 +22937,7 @@ msgstr "" msgid "" "A script implemented in the C# programming language (Mono-enabled builds " "only)." -msgstr "用C#编程语言实现的脚本(仅启用Mono的版本)。" +msgstr "用 C# 编程语言实现的脚本(仅 Mono 版本中存在)。" #: modules/mono/doc_classes/CSharpScript.xml msgid "" @@ -22917,14 +22945,14 @@ msgid "" "class and is only available in Mono-enabled Godot builds.\n" "See also [GodotSharp]." msgstr "" -"此类表示C#脚本。它与[GDScript]类的C#等效,并且仅在启用了Mono的Godot版本中可" -"用。\n" -"另请参阅[GodotSharp]。" +"这个类表示 C# 脚本,是 [GDScript] 类在 C# 中的对等体,仅在启用了 Mono 的 " +"Godot 版本中可用。\n" +"另请参阅 [GodotSharp]。" #: modules/mono/doc_classes/CSharpScript.xml #: modules/gdnative/doc_classes/PluginScript.xml msgid "Returns a new instance of the script." -msgstr "返回脚本的新实例。" +msgstr "返回该脚本的新实例。" #: doc/classes/CubeMap.xml msgid "A CubeMap is a 6-sided 3D texture." @@ -23241,7 +23269,7 @@ msgstr "重新计算曲线的烘焙点缓存。" msgid "" "Removes points that are closer than [code]CMP_EPSILON[/code] (0.00001) units " "to their neighbor on the curve." -msgstr "移除比曲线上的相邻点近[code]CMP_EPSILON[/code](0.00001)个单位的点。" +msgstr "移除比曲线上的相邻点近 [code]CMP_EPSILON[/code](0.00001)个单位的点。" #: doc/classes/Curve.xml doc/classes/Curve2D.xml doc/classes/Curve3D.xml msgid "Removes all points from the curve." @@ -23436,9 +23464,9 @@ msgid "" "the index is out of bounds, the function sends an error to the console, and " "returns [code](0, 0)[/code]." msgstr "" -"返回指向顶点[code]idx[/code]的控制点位置。返回的位置是相对于顶点[code]idx[/" -"code]的。如果索引超出了范围,函数会向控制台发送一条错误,并返回 [code](0, 0)" -"[/code]。" +"返回指向顶点 [code]idx[/code] 的控制点位置。返回的位置是相对于顶点 " +"[code]idx[/code] 的。如果索引超出了范围,函数会向控制台发送一条错误,并返回 " +"[code](0, 0)[/code]。" #: doc/classes/Curve2D.xml msgid "" @@ -23447,9 +23475,9 @@ msgid "" "code]. If the index is out of bounds, the function sends an error to the " "console, and returns [code](0, 0)[/code]." msgstr "" -"返回从顶点[code]idx[/code]引出的控制点位置。返回的位置是相对于顶点 " -"[code]idx[/code]。如果索引越界,函数会向控制台发送错误,并返回 [code](0, 0)[/" -"code]。" +"返回从顶点 [code]idx[/code] 引出的控制点位置。返回的位置是相对于顶点 " +"[code]idx[/code]。如果索引越界,函数会向控制台发送错误,并返回 [code](0, " +"0)[/code]。" #: doc/classes/Curve2D.xml msgid "" @@ -25208,9 +25236,9 @@ msgid "" "appear in the inspector when selecting a node that extends the class " "specified by [code]class_name[/code]." msgstr "" -"如果[code]class_name[/code]指定的类中的[code]property[/code]被禁用,则返回 " -"[code]true[/code]。当属性被禁用时,当[code]class_name[/code]类被指定为类的(继" -"承)父节点时,它将不会出现在检查器中。" +"如果 [code]class_name[/code] 指定的类中的 [code]property[/code] 属性被禁用," +"则返回 [code]true[/code]。禁用某一属性后,当选中继承自 " +"[code]class_name[/code] 类的节点时,该属性将不会出现在检查器中。" #: doc/classes/EditorFeatureProfile.xml msgid "" @@ -25226,17 +25254,19 @@ msgid "" "format obtained by using the feature profile manager's [b]Export[/b] button " "or the [method save_to_file] method." msgstr "" -"从文件中加载一个编辑器功能配置文件。该文件必须遵循JSON格式,通过使用功能配置" -"文件管理器的[b]Export[/b]按钮或[method save_to_file]方法获得。" +"从文件中加载一个编辑器功能配置文件。该文件必须遵循 JSON " +"格式,通过使用功能配置文件管理器的[b]导出[/b]按钮或 [method save_to_file] " +"方法获得。" #: doc/classes/EditorFeatureProfile.xml msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" -"将编辑器的功能配置保存到JSON格式的文件中。然后可以使用特征配置文件管理器的[b]" -"导入[/b]按钮或[method load_from_file]按钮导入它。" +"将编辑器的功能配置保存到 JSON " +"格式的文件中。然后可以使用功能配置文件管理器的[b]导入[/b]按钮或 [method " +"load_from_file] 方法导入它。" #: doc/classes/EditorFeatureProfile.xml msgid "" @@ -25244,8 +25274,9 @@ msgid "" "by [code]class_name[/code]. When disabled, the class won't appear in the " "Create New Node dialog." msgstr "" -"如果 [code]disable[/code] 是 [code]true[/code],则禁用 [code]class_name[/" -"code] 指定的类。被禁用时,该类不会出现在“创建新 Node”对话框中。" +"如果 [code]disable[/code] 为 [code]true[/code],则禁用 " +"[code]class_name[/code] 指定的类。禁用后,该类不会出现在“创建新 " +"Node”对话框中。" #: doc/classes/EditorFeatureProfile.xml msgid "" @@ -25254,9 +25285,9 @@ msgid "" "appear in the Create New Node dialog but the inspector will be read-only " "when selecting a node that extends the class." msgstr "" -"如果 [code]disable[/code] 为 [code]true[/code],则禁用 [code]class_name[/" -"code] 指定的类的编辑。禁用时,类仍然会出现在“创建新 Node”对话框中,但在选择继" -"承的节点时,检查器将只读。" +"如果 [code]disable[/code] 为 [code]true[/code],则禁用 " +"[code]class_name[/code] 指定的类的编辑。禁用后,该类仍然会出现在“创建新 " +"Node”对话框中,但在选中继承的节点时,检查器将只读。" #: doc/classes/EditorFeatureProfile.xml msgid "" @@ -25265,9 +25296,10 @@ msgid "" "When a property is disabled, it won't appear in the inspector when selecting " "a node that extends the class specified by [code]class_name[/code]." msgstr "" -"如果 [code]disable[/code] 是 [code]true[/code],则禁用 [code]class_name[/" -"code] 指定的类中的 [code]property[/code] 的编辑。当属性被禁用时,当选择继承 " -"[code]class_name[/code] 指定的类的节点时,它将不会出现在检查器中。" +"如果 [code]disable[/code] 为 [code]true[/code],则禁用 " +"[code]class_name[/code] 指定的类中的 [code]property[/code] " +"属性的编辑。禁用某一属性后,选中继承自 [code]class_name[/code] " +"指定的类的节点时,这个属性将不会出现在检查器中。" #: doc/classes/EditorFeatureProfile.xml msgid "" @@ -25298,7 +25330,7 @@ msgstr "" msgid "" "The AssetLib tab. If this feature is disabled, the AssetLib tab won't " "display." -msgstr "AssetLib选项卡。如果禁用此功能,则不会显示AssetLib选项卡。" +msgstr "AssetLib 选项卡。如果禁用此功能,则不会显示 AssetLib 选项卡。" #: doc/classes/EditorFeatureProfile.xml msgid "" @@ -29653,11 +29685,11 @@ msgstr "用于色调映射的默认曝光。" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" -"要使用的色调映射模式。色调映射是“转换”HDR 值以适合在 LDR 显示器上呈现的过程。" -"(Godot 尚不支持在 HDR 显示器上进行渲染。)" +"要使用的色调映射模式。色调映射是将 HDR 值“转换”为适合在 SDR " +"显示器上呈现的值过程。(Godot 尚不支持在 HDR 显示器上进行渲染。)" #: doc/classes/Environment.xml msgid "" @@ -31932,13 +31964,14 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" -"给定表示图块的[Vector2]数组,构建一个地图集。返回的字典有两个键:" -"[code]points[/code]是[Vector2]的向量,用于指定每个图块的位置,[code]size[/" -"code]包含整个图集的整体大小,作为[Vector2]。" +"给定表示图块的 [Vector2] " +"数组,构建一个地图集。返回的字典有两个键:[code]points[/code] 是 [Vector2] " +"的数组,用于指定每个图块的位置,[code]size[/code] 包含整个图集的整体大小," +"是一个 [Vector2]。" #: doc/classes/Geometry.xml msgid "" @@ -33218,9 +33251,7 @@ msgstr "小图矩形的大小。地图自身基于网格区域的大小,并被 msgid "" "If [code]true[/code], enables disconnection of existing connections in the " "GraphEdit by dragging the right end." -msgstr "" -"如果为 [code]true[/code],通过拖动右端,可以断开图形编辑GraphEdit中现有的连" -"接。" +msgstr "如果为 [code]true[/code],通过拖动右端,可以断开 GraphEdit 中现有的连接。" #: doc/classes/GraphEdit.xml msgid "The scroll offset." @@ -33277,9 +33308,9 @@ msgid "" "code] slot of the [code]from[/code] GraphNode and the [code]to_slot[/code] " "slot of the [code]to[/code] GraphNode is attempted to be created." msgstr "" -"当试图创建[code]来自from[/code]图形节点GraphNode1的[code]from_slot[/code]槽和" -"[code]to[/code]图形节点GraphNode2的[code]to_slot[/code]槽之间的连接时,会向图" -"形编辑GraphEdit发出。" +"尝试创建从 [code]from[/code] GraphNode 的 [code]from_slot[/code] 槽到 " +"[code]to[/code] GraphNode 的 [code]to_slot[/code] 槽之间的连接时,会向该 " +"GraphEdit 发出。" #: doc/classes/GraphEdit.xml msgid "" @@ -33306,9 +33337,9 @@ msgid "" "slot of [code]from[/code] GraphNode and [code]to_slot[/code] slot of " "[code]to[/code] GraphNode is attempted to be removed." msgstr "" -"当试图移除 [code]from[/code] 图形节点GraphNode1的 [code]from_slot[/code]槽和" -"[code]to[/code] 图形节点GraphNode 的[code]to_slot[/code] 槽之间的连接时,会发" -"送到图形编辑GraphEdit。" +"尝试移除从 [code]from[/code] GraphNode 的 [code]from_slot[/code] 槽到 " +"[code]to[/code] GraphNode 的 [code]to_slot[/code] 槽之间的连接时,会向该 " +"GraphEdit 发出。" #: doc/classes/GraphEdit.xml msgid "" @@ -33532,9 +33563,8 @@ msgstr "" msgid "" "Sets the [Color] of the right (output) side of the slot [code]idx[/code] to " "[code]color_right[/code]." -msgstr "" -"将插槽[code]idx[/code]的右侧(输出)的颜色[Color]设置为[code]color_right[/" -"code]。" +msgstr "将插槽 [code]idx[/code] 的右侧(输出)的颜色 [Color] 设置为 " +"[code]color_right[/code]。" #: doc/classes/GraphNode.xml msgid "" @@ -33570,7 +33600,7 @@ msgstr "" #: doc/classes/GraphNode.xml msgid "If [code]true[/code], the GraphNode is a comment node." -msgstr "如果为 [code]true[/code],则 GraphNode 是注释节点。" +msgstr "如果为 [code]true[/code],则该 GraphNode 是注释节点。" #: doc/classes/GraphNode.xml msgid "" @@ -33598,7 +33628,7 @@ msgstr "" #: doc/classes/GraphNode.xml msgid "If [code]true[/code], the GraphNode is selected." -msgstr "如果为 [code]true[/code],图形节点GraphNode被选中。" +msgstr "如果为 [code]true[/code],则该 GraphNode 被选中。" #: doc/classes/GraphNode.xml msgid "" @@ -35784,7 +35814,6 @@ msgid "" msgstr "允许的最大重定向数。用于防止无限重定向循环。" #: doc/classes/HTTPRequest.xml -#, fuzzy msgid "" "If set to a value greater than [code]0.0[/code] before the request starts, " "the HTTP request will time out after [code]timeout[/code] seconds have " @@ -35795,11 +35824,11 @@ msgid "" "leave this to [code]0.0[/code] to prevent the download from failing if it " "takes too much time." msgstr "" -"如果设为大于 [code]0.0[/code] 的值,在经过 [code]timeout[/code] 秒仍未[i]完成" -"[/i]请求时,该 HTTP 请求就会超时。对于 REST API 等较小的 HTTP 请求,将 " -"[member timeout] 设为大于 [code]0.0[/code] 的值可以定时防止应用程序在失败时陷" -"入长时间的无响应状态。下载文件时请保持 [code]0.0[/code],防止在需要花费较长时" -"间下载时导致下载失败。" +"如果在请求开始前设为大于 [code]0.0[/code] 的值,在经过 [code]timeout[/code] " +"秒仍未[i]完成[/i]请求时,该 HTTP 请求就会超时。对于 REST API 等较小的 HTTP 请" +"求,将 [member timeout] 设为 [code]10.0[/code] 到 [code]30.0[/code] 之间的值" +"可以定时防止应用程序在失败时陷入长时间的无响应状态。下载文件时请保持 " +"[code]0.0[/code],防止在需要花费较长时间下载时导致下载失败。" #: doc/classes/HTTPRequest.xml msgid "If [code]true[/code], multithreading is used to improve performance." @@ -37641,7 +37670,6 @@ msgid "Controls the mouse mode. See [enum MouseMode] for more information." msgstr "控制鼠标模式。详情请参阅 [enum MouseMode]。" #: doc/classes/Input.xml -#, fuzzy msgid "" "If [code]true[/code], similar input events sent by the operating system are " "accumulated. When input accumulation is enabled, all input events generated " @@ -37663,8 +37691,8 @@ msgstr "" "输入累积在默认情况下是启用的。它可以被禁用,将以增加CPU使用率为代价,获得稍微" "更精确及更灵敏的输入。在需要自由绘制线条的应用中,一般应用在用户绘制线条时禁" "用输入累加,以获得紧跟实际输入的结果。\n" -"[b]注意:[/b]默认[i]禁用[/i]输入累积是出于向后兼容的缘故。然而我们推荐那些不" -"需要非常活跃输入的游戏将其启用,能够降低 CPU 占用。" +"[b]注意:[/b]输入累积是默认[i]启用[/i]的。推荐那些不需要非常活跃输入的游戏保" +"持启用,能够降低 CPU 占用。" #: doc/classes/Input.xml msgid "Emitted when a joypad device has been connected or disconnected." @@ -38390,7 +38418,6 @@ msgid "Input event type for mouse motion events." msgstr "鼠标移动事件的输入事件类型。" #: doc/classes/InputEventMouseMotion.xml -#, fuzzy msgid "" "Contains mouse and pen motion information. Supports relative, absolute " "positions and speed. See [method Node._input].\n" @@ -38407,9 +38434,11 @@ msgid "" "avoid visible gaps in lines if the user is moving the mouse quickly." msgstr "" "包含鼠标和笔的运动信息。支持相对、绝对位置和速度。见 [method Node._input]。\n" -"[b]注意:[/b]默认情况下,这个事件能够每帧发出多次,提供更精确的输入报告,但代" -"价是更高的 CPU 占用。你可以将 [member Input.use_accumulated_input] 设为 " -"[code]true[/code],将每帧中的多个事件合并为单个事件进行发送。\n" +"[b]注意:[/b]这个事件的行为受 [member Input.use_accumulated_input] 取值的影" +"响。设为 [code]true[/code] 时(默认),从操作系统获取到的鼠标/笔的移动事件会" +"被合并,每个渲染帧最多只会发出一个累积事件。设为 [code]false[/code] 时,收到" +"几个事件就会发出几个事件,即每个渲染帧可能发出多次,能够精确地汇报输入,但代" +"价是占用 CPU。\n" "[b]注意:[/b]如果你使用 InputEventMouseMotion 来画线,请考虑同时实现" "[url=https://zh.wikipedia.org/zh-cn/" "%E5%B8%83%E9%9B%B7%E6%A3%AE%E6%BC%A2%E5%A7%86%E7%9B%B4%E7%B7%9A%E6%BC%94%E7%AE%97%E6%B3%95]" @@ -38420,13 +38449,12 @@ msgid "Mouse and input coordinates" msgstr "鼠标和输入坐标" #: doc/classes/InputEventMouseMotion.xml -#, fuzzy msgid "" "Returns [code]true[/code] when using the eraser end of a stylus pen.\n" "[b]Note:[/b] This property is implemented on Linux, macOS and Windows." msgstr "" -"返回键盘布局的数量。\n" -"[b]注意:[/b]本方法在Linux、macOS和Windows上实现。" +"使用手写笔的橡皮端时,返回 [code]true[/code]。\n" +"[b]注意:[/b]这个属性在 Linux、macOS 和 Windows 上实现。" #: doc/classes/InputEventMouseMotion.xml msgid "" @@ -40992,7 +41020,7 @@ msgstr "对 [Font] 轮廓的染色。" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -41000,8 +41028,8 @@ msgid "" "sorted from back to front (subject to priority)." msgstr "" "设置文本轮廓的渲染优先级。优先级高的物体将被排序在优先级低的物体前面。\n" -"[b]注意:[/b]仅在 [member alpha_cut] 为 [constant ALPHA_CUT_DISABLED](默认" -"值)时适用。\n" +"[b]注意:[/b]仅在 [member alpha_cut] 为 [constant " +"ALPHA_CUT_DISABLED](默认值)时适用。\n" "[b]注意:[/b]仅适用于透明物体的排序。这不会影响透明物体相对于不透明物体的排序" "方式。这是因为不透明对象不被排序,而透明对象则从后往前排序(取决于优先级)。" @@ -41013,7 +41041,7 @@ msgstr "标签上一个像素宽度的大小,以 3D 缩放。" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -41021,8 +41049,8 @@ msgid "" "sorted from back to front (subject to priority)." msgstr "" "设置文本的渲染优先级。优先级高的物体将被排序在优先级低的物体前面。\n" -"[b]注意:[/b]仅在 [member alpha_cut] 为 [constant ALPHA_CUT_DISABLED](默认" -"值)时适用。\n" +"[b]注意:[/b]仅在 [member alpha_cut] 为 [constant " +"ALPHA_CUT_DISABLED](默认值)时适用。\n" "[b]注意:[/b]仅适用于透明物体的排序。这不会影响透明物体相对于不透明物体的排序" "方式。这是因为不透明对象不被排序,而透明对象则从后往前排序(取决于优先级)。" @@ -41049,9 +41077,9 @@ msgstr "如果打开,环境中的灯光会影响该标签。" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." -msgstr "如果打开,从后面也可以看到文本,如果不打开,从后面看它是不可见的。" +msgstr "如果打开,从后面也可以看到文本。如果不打开,从后面看该文本是不可见的。" #: doc/classes/Label3D.xml doc/classes/SpatialMaterial.xml #: doc/classes/SpriteBase3D.xml @@ -46060,18 +46088,18 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." msgstr "" -"[NavigationMesh] 的实例。[Navigation] 节点根据它的 [NavigationMesh] 资源来确" -"定哪些可以进行导航、哪些不能。\n" +"[NavigationMesh] 的实例。[Navigation] 节点根据它的 [NavigationMesh] " +"资源来确定哪些可以进行导航、哪些不能。\n" "默认情况下,这个节点会在默认的 [World] 导航地图中进行注册。如果这个节点是 " "[Navigation] 节点的子项,就会在该导航节点的导航地图中进行注册。\n" "如果两个地图共享类似的边界,就可以相互连接。你可以通过 [method " -"NavigationServer.map_set_edge_connection_margin] 设置两个顶点连接两条边界所需" -"的最小距离。\n" +"NavigationServer.map_set_edge_connection_margin] " +"设置两个顶点连接两条边界所需的最小距离。\n" "[b]注意:[/b]将两个地区的导航网格相互重叠并不足以将其相连。它们必须共享类似的" "边界。\n" "从另一个地区进入这个地图的消耗可以通过 [member enter_cost] 进行控制。\n" @@ -46397,18 +46425,18 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." msgstr "" -"导航地图上的地区。[Navigation2DServer] 根据它的 [NavigationPolygon] 资源来确" -"定哪些可以进行导航、哪些不能。\n" +"导航地图上的地区。[Navigation2DServer] 根据它的 [NavigationPolygon] " +"资源来确定哪些可以进行导航、哪些不能。\n" "默认情况下,这个节点会在默认的 [World2D] 导航地图中进行注册。如果这个节点是 " "[Navigation2D] 节点的子项,就会在该导航节点的导航地图中进行注册。\n" "如果两个地图共享类似的边界,就可以相互连接。你可以通过 [method " -"Navigation2DServer.map_set_edge_connection_margin] 设置两个顶点连接两条边界所" -"需的最小距离。\n" +"Navigation2DServer.map_set_edge_connection_margin] " +"设置两个顶点连接两条边界所需的最小距离。\n" "[b]注意:[/b]将两个地区的导航网格相互重叠并不足以将其相连。它们必须共享类似的" "边界。\n" "从另一个地区进入这个地图的寻路消耗可以通过 [member enter_cost] 进行控制。\n" @@ -46551,6 +46579,62 @@ msgstr "" msgid "Control activation of this server." msgstr "控制这个服务器是否激活。" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "对 [NetworkedMultiplayerPeer] 的一种实现,能够通过脚本控制。" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" +"对 [NetworkedMultiplayerPeer] 的一种实现,能够作为 [member MultiplayerAPI." +"network_peer] 使用并且通过脚本控制。\n" +"其目的是为高级多人 API 添加新的后端,不必使用 GDNative。" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" +"向本地 [MultiplayerAPI] 传递数据包。\n" +"当你的脚本通过网络收到其他对等体的数据包时(发送方发出 [signal " +"packet_generated] 信号),将其传递给这个方法会在本地进行传递。" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "使用给定的 [code]peer_id[/code] 初始化该对等体(必须在 1 和 2147483647 " +"之间)。" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "设置连接的状态。见 [enum NetworkedMultiplayerPeer.ConnectionStatus]。" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "设置这个对等体所能够处理的最大数据包大小。" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" +"当本地 [MultiplayerAPI] 生成数据包时触发。\n" +"你的脚本应当获取这个数据包并将其通过网络发送给请求的对等体(" +"对方收到该数据时应当调用 [method deliver_packet])。" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -50248,8 +50332,18 @@ msgid "See [enum ShadowDetail]." msgstr "见 [enum ShadowDetail]。" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." -msgstr "见 [enum ShadowMode]。" +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." +msgstr "" +"为这个 [OmniLight] 使用的阴影渲染模式。见 [enum ShadowMode]。\n" +"[b]注意:[/b]在 GLES2 中,只有支持深度立方体贴图功能的 GPU 才支持 [constant " +"SHADOW_CUBE]。Radeon HD 4000 系列等较老的 GPU " +"不支持立方体贴图阴影,因此会回退到使用双抛物面阴影。" #: doc/classes/OmniLight.xml msgid "" @@ -50261,10 +50355,11 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" -"阴影被渲染成一个立方体贴图。比 [constant SHADOW_DUAL_PARABOLOID] 慢,但质量更" -"高。" +"阴影被渲染至一个立方体贴图。比 [constant SHADOW_DUAL_PARABOLOID] " +"慢,但质量更高。仅在支持深度立方体贴图功能的 GPU 上支持。" #: doc/classes/OmniLight.xml msgid "Use more detail vertically when computing the shadow." @@ -57224,9 +57319,8 @@ msgstr "改变给定索引处的字节。" #: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml #: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml #: doc/classes/PoolVector3Array.xml -#, fuzzy msgid "Sorts the elements of the array in ascending order." -msgstr "从数组中删除位于索引的元素。" +msgstr "将该数组中的元素按升序排列。" #: doc/classes/PoolByteArray.xml msgid "" @@ -63789,14 +63883,14 @@ msgid "" "Generates a pseudo-random float between [code]0.0[/code] and [code]1.0[/" "code] (inclusive)." msgstr "" -"产生一个[code]0.0[/code]和[code]1.0[/code](包括端点)之间的伪随机浮点数。" +"生成一个[code]0.0[/code]和[code]1.0[/code](包括端点)之间的伪随机浮点数。" #: doc/classes/RandomNumberGenerator.xml msgid "" "Generates a pseudo-random float between [code]from[/code] and [code]to[/" "code] (inclusive)." msgstr "" -"产生一个[code]from[/code]和[code]to[/code](包括端点)之间的伪随机浮点数。" +"生成一个[code]from[/code]和[code]to[/code](包括端点)之间的伪随机浮点数。" #: doc/classes/RandomNumberGenerator.xml msgid "" @@ -63805,8 +63899,8 @@ msgid "" "specified [code]mean[/code] and a standard [code]deviation[/code]. This is " "also called Gaussian distribution." msgstr "" -"产生一个[url=https://en.wikipedia.org/wiki/Normal_distribution]正态分布[/url]" -"的伪随机数,使用Box-Muller变换,具有指定的[code]mean[/code]和标准" +"生成一个[url=https://en.wikipedia.org/wiki/Normal_distribution]正态分布[/url]" +"的伪随机数,使用 Box-Muller 变换,具有指定的 [code]mean[/code] 和标准 " "[code]deviation[/code]。这也被称为高斯分布。" #: doc/classes/RandomNumberGenerator.xml @@ -63814,16 +63908,16 @@ msgid "" "Generates a pseudo-random 32-bit unsigned integer between [code]0[/code] and " "[code]4294967295[/code] (inclusive)." msgstr "" -"产生一个[code]0[/code]和[code]4294967295[/code](含端点)之间的伪随机32位无符" -"号整数。" +"生成一个 [code]0[/code] 和 [code]4294967295[/code](含端点)之间的伪随机 32 " +"位无符号整数。" #: doc/classes/RandomNumberGenerator.xml msgid "" "Generates a pseudo-random 32-bit signed integer between [code]from[/code] " "and [code]to[/code] (inclusive)." msgstr "" -"产生一个[code]to[/code]和[code]from[/code](含端点)之间的伪随机32位有符号整" -"数。" +"生成一个 [code]to[/code] 和 [code]from[/code](含端点)之间的伪随机 32 位有符" +"号整数。" #: doc/classes/RandomNumberGenerator.xml msgid "Setups a time-based seed to generator." @@ -63926,20 +64020,20 @@ msgstr "使该 [Range] 停止与任何其他 Range 共享其成员变量。" #: doc/classes/Range.xml msgid "" "If [code]true[/code], [member value] may be greater than [member max_value]." -msgstr "如果为 [code]true[/code],[member value]可能大于[member max_value]。" +msgstr "如果为 [code]true[/code],[member value] 可能大于 [member max_value]。" #: doc/classes/Range.xml msgid "" "If [code]true[/code], [member value] may be less than [member min_value]." -msgstr "如果为 [code]true[/code],[member value]可能小于[member min_value]。" +msgstr "如果为 [code]true[/code],[member value] 可能小于 [member min_value]。" #: doc/classes/Range.xml msgid "" "If [code]true[/code], and [code]min_value[/code] is greater than 0, " "[code]value[/code] will be represented exponentially rather than linearly." msgstr "" -"如果为 [code]true[/code],并且[code]min_value[/code]大于0,[code]value[/code]" -"将以指数方式而不是线性方式表示。" +"如果为 [code]true[/code],并且 [code]min_value[/code] 大于 0,[code]value[/" +"code] 将以指数方式而不是线性方式表示。" #: doc/classes/Range.xml msgid "" @@ -63961,12 +64055,12 @@ msgid "" "multiplied by [code]page[/code] over the difference between [code]min_value[/" "code] and [code]max_value[/code]." msgstr "" -"页面大小。主要用于[ScrollBar]。ScrollBar的长度是它的尺寸乘以[code]page[/code]" -"超过[code]min_value[/code]和[code]max_value[/code]之间的差值。" +"页面大小。主要用于 [ScrollBar]。ScrollBar 的长度是它的尺寸乘以 [code]page[/" +"code] 超过 [code]min_value[/code] 和 [code]max_value[/code] 之间的差值。" #: doc/classes/Range.xml msgid "The value mapped between 0 and 1." -msgstr "该值在0和1之间进行映射。" +msgstr "该值在 0 和 1 之间进行映射。" #: doc/classes/Range.xml msgid "" @@ -63982,9 +64076,9 @@ msgid "" "[code]value[/code] will first be rounded to a multiple of [code]step[/code] " "then rounded to the nearest integer." msgstr "" -"如果大于0,[code]value[/code]将总是被四舍五入为[code]step[/code]的倍数。如果" -"[code]rounded[/code]也是[code]true[/code],[code]value[/code]将首先被四舍五入" -"为[code]step[/code]的倍数,然后舍入为最近的整数。" +"如果大于 0,[code]value[/code] 将总是被四舍五入为 [code]step[/code] 的倍数。" +"如果 [code]rounded[/code] 也是 [code]true[/code],[code]value[/code] 将首先被" +"四舍五入为 [code]step[/code] 的倍数,然后舍入为最近的整数。" #: doc/classes/Range.xml msgid "Range's current value." @@ -63995,8 +64089,8 @@ msgid "" "Emitted when [member min_value], [member max_value], [member page], or " "[member step] change." msgstr "" -"在 [member min_value], [member max_value], [member page], 或 [member step] 改" -"变时释放信号。" +"在 [member min_value]、[member max_value]、[member page]、[member step] 改变" +"时释放信号。" #: doc/classes/Range.xml msgid "" @@ -64039,12 +64133,12 @@ msgstr "" "以便找到沿光线路径最近的对象。\n" "RayCast 可以忽略某些对象,方法是通过 [code]add_exception[/code] 将它们添加到" "例外列表中,或者通过使用碰撞层和掩码设置,进行适当的过滤。\n" -"RayCast 可以配置为报告与 [Area]([member collide_with_areas]) 和/或 " -"[PhysicsBody]([member collide_with_bodies]) 的碰撞。\n" +"RayCast 可以配置为报告与 [Area]([member collide_with_areas])和/或 " +"[PhysicsBody]([member collide_with_bodies])的碰撞。\n" "只有启用的光线投射才能检测空间并报告碰撞。\n" -"RayCast 计算每个物理帧的交集(参阅 [Node]),并将结果缓存起来,以便稍后使用," -"直到下一帧。如果物理帧之间(或同一帧期间)需要多次检测,请在调整光线投射后使" -"用[method force_raycast_update]。" +"RayCast 计算每个物理帧的交集(见 [Node]),并将结果缓存起来,以便稍后使用,直" +"到下一帧。如果物理帧之间(或同一帧期间)需要多次检测,请在调整光线投射后使用 " +"[method force_raycast_update]。" #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -64072,7 +64166,7 @@ msgid "" msgstr "" "更新射线的碰撞信息。使用此方法立即更新碰撞信息,而不是等待下一次 " "[code]_physics_process[/code] 调用,例如,如果光线或其父级已更改状态。\n" -"[b]注意:[/b][code]enabled[/code]不需要此功能。" +"[b]注意:[/b][code]enabled[/code] 不需要此功能。" #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -64098,7 +64192,7 @@ msgid "" "[b]Note:[/b] Bit indices range from 0-19." msgstr "" "如果通过的位索引被打开,则返回 [code]true[/code]。\n" -"[b]注意:[/b]位指数范围为0-19。" +"[b]注意:[/b]位指数范围为 0-19。" #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -64136,8 +64230,8 @@ msgid "" "Sets the bit index passed to the [code]value[/code] passed.\n" "[b]Note:[/b] Bit indexes range from 0-19." msgstr "" -"将传递的位索引设置为传递的[code]值[/code]。\n" -"[b]注意:[/b]位索引的范围是0-19。" +"将传递的位索引设置为传递的 [code]value[/code]。\n" +"[b]注意:[/b]位索引的范围是 0-19。" #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -64172,9 +64266,9 @@ msgid "" "If set to [code]Color(0.0, 0.0, 0.0)[/code] (by default), the color set in " "[member ProjectSettings.debug/shapes/collision/shape_color] is used." msgstr "" -"如果在 [b]Debug[/b] 菜单中启用了可见碰撞形状 [b]Visible Collision Shapes[/" -"b],则可用于在编辑器中和运行时绘制形状的自定义颜色。如果 [RayCast] 与某物体发" -"生碰撞,此颜色将在运行时突出显示。\n" +"如果在[b]调试[/b]菜单中启用了[b]显示碰撞区域[/b],则可用于在编辑器中和运行时" +"绘制形状的自定义颜色。如果 [RayCast] 与某物体发生碰撞,此颜色将在运行时突出显" +"示。\n" "如果设置为 [code]Color(0.0, 0.0, 0.0)[/code](默认),则使用 [member " "ProjectSettings.debug/shapes/collision/shape_color] 中设置的颜色。" @@ -64186,8 +64280,8 @@ msgid "" "shape to be visible at run-time." msgstr "" "如果设置为 [code]1[/code],则将一条线用作调试形状。否则,将绘制一个截断的金字" -"塔来表示 [RayCast]。需要在 [b]调试[/b] 菜单中启用可见碰撞形状 [b]Visible " -"Collision Shapes[/b],以便调试形状在运行时可见。" +"塔来表示 [RayCast]。需要在[b]调试[/b]菜单中启用[b]显示碰撞区域[/b],以便调试" +"形状在运行时可见。" #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "If [code]true[/code], collisions will be reported." @@ -64259,9 +64353,9 @@ msgid "" "itself from whatever is touching its far endpoint. It's often useful for " "characters." msgstr "" -"用于3D碰撞的射线形状,它可以被设置成一个[PhysicsBody]或[Area]。一条射线并不是" -"真正的碰撞体;然而,它试图将自己与其远端点接触的东西分开。这通常对角色很有" -"用。" +"用于 3D 碰撞的射线形状,它可以被设置成一个 [PhysicsBody] 或 [Area]。一条射线" +"并不是真正的碰撞体;然而,它试图将自己与其远端点接触的东西分开。这通常对角色" +"很有用。" #: doc/classes/RayShape.xml doc/classes/RayShape2D.xml msgid "The ray's length." @@ -64301,11 +64395,11 @@ msgstr "" #: doc/classes/Rect2.xml msgid "Constructs a [Rect2] by position and size." -msgstr "按位置和大小构造一个[Rect2]。" +msgstr "按位置和大小构造一个 [Rect2]。" #: doc/classes/Rect2.xml msgid "Constructs a [Rect2] by x, y, width, and height." -msgstr "通过x、y、宽度和高度构造一个[Rect2]。" +msgstr "通过 x、y、宽度和高度构造一个 [Rect2]。" #: doc/classes/Rect2.xml msgid "" @@ -68818,7 +68912,6 @@ msgid "" msgstr "返回该 [SceneTreeTween] 目前是否正在执行,即未暂停且未完成。" #: doc/classes/SceneTreeTween.xml -#, fuzzy msgid "" "Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a " "[SceneTreeTween] contained by the scene tree (i.e. the array from [method " @@ -68832,7 +68925,7 @@ msgstr "" "[SceneTreeTween](即 [method SceneTree.get_processed_tweens] 返回的数组中包含" "这个 [SceneTreeTween])。[SceneTreeTween] 失效的情况有:补间完成、被销毁、使" "用 [code]SceneTreeTween.new()[/code] 创建。无效的 [SceneTreeTween] 不能追加 " -"[Tweener]。" +"[Tweener]。但你仍然能够使用 [method interpolate_value]。" #: doc/classes/SceneTreeTween.xml msgid "Aborts all tweening operations and invalidates the [SceneTreeTween]." @@ -68879,7 +68972,6 @@ msgstr "" "的默认缓动类型。" #: doc/classes/SceneTreeTween.xml -#, fuzzy msgid "" "Sets the number of times the tweening sequence will be repeated, i.e. " "[code]set_loops(2)[/code] will run the animation twice.\n" @@ -70738,13 +70830,13 @@ msgstr "启用此节点的呈现。将 [member visible] 更改为 [code]true[/co msgid "" "Transforms [code]local_point[/code] from this node's local space to world " "space." -msgstr "将 [code]local_point[/code] 从该节点的本地空间转换为世界空间。" +msgstr "将 [code]local_point[/code] 从这个节点的局部空间转换为世界空间。" #: doc/classes/Spatial.xml msgid "" "Transforms [code]global_point[/code] from world space to this node's local " "space." -msgstr "将 [code]global_point[/code] 从世界空间转换到这个节点的本地空间。" +msgstr "将 [code]global_point[/code] 从世界空间转换到这个节点的局部空间。" #: doc/classes/Spatial.xml msgid "" @@ -70754,7 +70846,7 @@ msgid "" "offset of [code](2, 0, 0)[/code] would actually add 20 ([code]2 * 10[/code]) " "to the X coordinate." msgstr "" -"通过给定的偏移量 [Vector3] 改变节点的位置。\n" +"通过给定的偏移量 [Vector3] 改变该节点的位置。\n" "注意,平移 [code]offset[/code] 受节点缩放的影响,所以如果按例如 [code]" "(10,1,1)[/code] 进行缩放,平移 [code](2,0,0)[/code] 实际上会在 X 坐标上增加 " "20 ([code]2 * 10[/code])。" @@ -70762,22 +70854,21 @@ msgstr "" #: doc/classes/Spatial.xml msgid "" "Changes the node's position by the given offset [Vector3] in local space." -msgstr "通过给定的偏移量 [Vector3] 改变节点在局部空间中的位置。" +msgstr "通过给定的局部空间偏移量 [Vector3] 改变该节点的位置。" #: doc/classes/Spatial.xml msgid "Updates the [SpatialGizmo] of this node." -msgstr "更新该节点的 [SpatialGizmo]。" +msgstr "更新这个节点的 [SpatialGizmo]。" #: doc/classes/Spatial.xml msgid "" "The [SpatialGizmo] for this node. Used for example in [EditorSpatialGizmo] " "as custom visualization and editing handles in Editor." msgstr "" -"此节点的 [SpatialGizmo]。例如在 [EditorSpatialGizmo] 中用作编辑器中的自定义可" -"视化和编辑手柄。" +"这个节点的 [SpatialGizmo]。例如在 [EditorSpatialGizmo] 中用作编辑器中的自定义" +"可视化和编辑手柄。" #: doc/classes/Spatial.xml -#, fuzzy msgid "" "Rotation part of the global transformation in radians, specified in terms of " "YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n" @@ -70789,7 +70880,7 @@ msgid "" "point numbers. Therefore, applying affine operations on the rotation " "\"vector\" is not meaningful." msgstr "" -"局部变换的旋转部分以弧度表示,以 YXZ-Euler 角的形式表示(X 角、Y 角、Z " +"全局变换的旋转部分,单位为弧度,以 YXZ 欧拉角的形式表示(X 角、Y 角、Z " "角)。\n" "[b]注意:[/b]在数学意义上,旋转是一个矩阵而不是一个向量。这三个欧拉角是旋转矩" "阵欧拉角参数化的三个独立参数,存储在 [Vector3] 数据结构中并不是因为旋转是一个" @@ -70798,13 +70889,13 @@ msgstr "" #: doc/classes/Spatial.xml msgid "World space (global) [Transform] of this node." -msgstr "此节点的世界空间(全局)[Transform]。" +msgstr "这个节点的世界空间(全局)变换 [Transform]。" #: doc/classes/Spatial.xml msgid "" "Global position of this node. This is equivalent to [code]global_transform." "origin[/code]." -msgstr "" +msgstr "这个节点的全局位置。与 [code]global_transform.origin[/code] 等价。" #: doc/classes/Spatial.xml msgid "" @@ -70818,7 +70909,7 @@ msgid "" "point numbers. Therefore, applying affine operations on the rotation " "\"vector\" is not meaningful." msgstr "" -"局部变换的旋转部分以弧度表示,以 YXZ-Euler 角的形式表示(X 角、Y 角、Z " +"局部变换的旋转部分,单位为弧度,以 YXZ 欧拉角的形式表示(X 角、Y 角、Z " "角)。\n" "[b]注意:[/b]在数学意义上,旋转是一个矩阵而不是一个向量。这三个欧拉角是旋转矩" "阵欧拉角参数化的三个独立参数,存储在 [Vector3] 数据结构中并不是因为旋转是一个" @@ -70839,17 +70930,17 @@ msgid "" "transformation matrices in Godot, the scale values will either be all " "positive or all negative." msgstr "" -"本地变换中的缩放。\n" +"局部变换的缩放部分。\n" "[b]注意:[/b]3D 中,变换矩阵是无法分解出正负混合的缩放的。由于 Godot 中使用变" "换矩阵来表示缩放,得到的缩放值要么全正、要么全负。" #: doc/classes/Spatial.xml msgid "Local space [Transform] of this node, with respect to the parent node." -msgstr "该节点相对于父节点的局部空间 [Transform]。" +msgstr "这个节点相对于父节点的局部空间 [Transform]。" #: doc/classes/Spatial.xml msgid "Local translation of this node." -msgstr "此节点的局部变换。" +msgstr "这个节点的局部变换。" #: doc/classes/Spatial.xml msgid "" @@ -72820,16 +72911,16 @@ msgstr "精灵上一个像素宽度的大小,以 3D 缩放。" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " "This is because opaque objects are not sorted, while transparent objects are " "sorted from back to front (subject to priority)." msgstr "" -"设置精灵的渲染优先级。优先级高的物体将被排序在优先级低的物体前面。\n" -"[b]注意:[/b]仅在 [member alpha_cut] 为 [constant ALPHA_CUT_DISABLED](默认" -"值)时适用。\n" +"设置该精灵的渲染优先级。优先级高的物体将被排序在优先级低的物体前面。\n" +"[b]注意:[/b]仅在 [member alpha_cut] 为 [constant " +"ALPHA_CUT_DISABLED](默认值)时适用。\n" "[b]注意:[/b]仅适用于透明物体的排序。这不会影响透明物体相对于不透明物体的排序" "方式。这是因为不透明对象不被排序,而透明对象则从后往前排序(取决于优先级)。" @@ -76415,12 +76506,12 @@ msgstr "设置特定行的文本。" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" -"如果 [code]bookmark[/code] 为 true,则为行 [code]line[/code] 设置书签。如果 " -"[code]bookmark[/code] 为 false,则删除该书签。\n" +"如果 [code]bookmark[/code] 为 [code]true[/code],则为行 [code]line[/code] " +"设置书签。如果 [code]bookmark[/code] 为 [code]false[/code],则删除该书签。\n" "书签显示在 [member breakpoint_gutter] 中。" #: doc/classes/TextEdit.xml @@ -80281,7 +80372,7 @@ msgid "" "is_selected]." msgstr "" "返回当前获得焦点的列,如果没有焦点列,则返回 -1。\n" -"在[constant SELECT_SINGLE] 模式下,焦点列是被选中的列。在 [constant " +"在 [constant SELECT_SINGLE] 模式下,焦点列是被选中的列。在 [constant " "SELECT_ROW] 模式下,如果有任意项被选中,焦点列总是 0。在 [constant " "SELECT_MULTI] 模式下,焦点列是焦点光标下的列,但不一定有列被选中。\n" "要判断一个项的某一列是否被选中,请使用 [method TreeItem.is_selected]。" @@ -80306,12 +80397,12 @@ msgid "" "will use their \"min_width\" in a similar fashion to [member Control." "size_flags_stretch_ratio]." msgstr "" -"设置一个列的最小宽度。拥有“Expand”标志的列将以类似于 [member Control." +"设置某一列的最小宽度。拥有“Expand”标志的列将以类似于 [member Control." "size_flags_stretch_ratio] 的方式使用其“min_width”最小宽度。" #: doc/classes/Tree.xml msgid "Sets the title of a column." -msgstr "设置一个列的标题。" +msgstr "设置某一列的标题。" #: doc/classes/Tree.xml msgid "" @@ -80485,7 +80576,7 @@ msgid "" "other flags." msgstr "" "禁用所有放置部分,但仍然允许通过 [method get_drop_section_at_position] 检" -"测“物品上”的放置部分。\n" +"测“项目上”的放置部分。\n" "[b]注意:[/b]这是默认的标志,当与其他标志结合时,它没有效果。" #: doc/classes/Tree.xml @@ -80549,7 +80640,7 @@ msgid "" "Draws the guidelines if not zero, this acts as a boolean. The guideline is a " "horizontal line drawn at the bottom of each item." msgstr "" -"如果不为零就绘制参考线,这作为一个布尔值。参考线是在每个项的底部画的一条水平" +"如果不为零就绘制参考线,行为类似于布尔值。参考线是在每个项的底部画的一条水平" "线。" #: doc/classes/Tree.xml @@ -80557,8 +80648,8 @@ msgid "" "Draws the relationship lines if not zero, this acts as a boolean. " "Relationship lines are drawn at the start of child items to show hierarchy." msgstr "" -"如果不为零,则绘制关系线,这作为一个布尔值。关系线在子项的开始处绘制,以显示" -"层次结构。" +"如果不为零就绘制关系线,行为类似于布尔值。关系线在子项的开始处绘制,以显示层" +"次结构。" #: doc/classes/Tree.xml msgid "" @@ -80821,19 +80912,20 @@ msgstr "返回使用 [method set_metadata] 为指定列设置的元数据。" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." -msgstr "返回树中的下一个 TreeItem,如果没有,则返回一个空对象。" +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." +msgstr "返回树中的下一个兄弟 TreeItem,如果没有,则返回一个空对象。" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." msgstr "" -"返回树中下一个可见的 TreeItem,如果没有,则返回空对象。\n" -"如果 [code]wrap[/code] 被启用,当在最后一个可见元素上调用时,该方法将环绕到树" +"返回树中下一个可见的兄弟 TreeItem,如果没有,则返回空对象。\n" +"如果启用了 [code]wrap[/code],当在最后一个可见元素上调用时,该方法将环绕到树" "中的第一个可见元素,否则它将返回 [code]null[/code]。" #: doc/classes/TreeItem.xml @@ -80842,19 +80934,20 @@ msgstr "返回父级 TreeItem,如果没有,则返回一个空对象。" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." -msgstr "返回树中的前一个 TreeItem,如果没有,则返回一个空对象。" +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." +msgstr "返回树中的前一个兄弟 TreeItem,如果没有,则返回一个空对象。" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." msgstr "" -"返回树中前一个可见的 TreeItem,如果没有,则返回 null 对象。\n" -"如果 [code]wrap[/code] 被启用,当在第一个可见元素上调用时,该方法将环绕到树中" +"返回树中前一个可见的兄弟 TreeItem,如果没有,则返回 null 对象。\n" +"如果启用了 [code]wrap[/code],当在第一个可见元素上调用时,该方法将环绕到树中" "最后一个可见元素,否则它将返回 [code]null[/code]。" #: doc/classes/TreeItem.xml @@ -89175,8 +89268,16 @@ msgid "Sets the viewport's global transformation matrix." msgstr "设置视窗的全局变换矩阵。" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "如果为 [code]true[/code],视窗将呈现为 hdr。" +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" +"如果为 " +"[code]true[/code],该视区会渲染至高动态范围(HDR)而不是标准动态范围(SDR)。" +"另请参阅 [method viewport_set_use_32_bpc_depth]。\n" +"[b]注意:[/b]仅在 GLES3 后端可用。" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -89275,6 +89376,19 @@ msgstr "设置视窗的 2D/3D 模式。选项见 [enum ViewportUsage] 常量。" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" +"如果为 [code]true[/code],分配该视区的帧缓冲时将使用完整浮点数精度(32 " +"位)而不是半浮点数精度(16 位)。只有在同一个 [Viewport] 上通过 [method " +"viewport_set_use_32_bpc_depth] 将 HDR 设为 [code]true[/code] 时有效。\n" +"[b]注意:[/b]仅在 GLES3 后端中可用。" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/zh_TW.po b/doc/translations/zh_TW.po index cd8d5c0eb5..59cd8b199b 100644 --- a/doc/translations/zh_TW.po +++ b/doc/translations/zh_TW.po @@ -948,7 +948,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7798,8 +7805,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11871,7 +11878,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20299,7 +20311,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23691,7 +23703,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25528,7 +25540,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32638,7 +32650,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32654,7 +32666,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32684,7 +32696,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36820,7 +36832,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37083,7 +37095,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37201,6 +37213,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39898,7 +39956,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39910,7 +39974,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57697,7 +57762,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60599,8 +60664,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64234,13 +64299,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64252,13 +64318,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71172,7 +71239,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71257,6 +71328,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/drivers/gles3/effects/copy_effects.cpp b/drivers/gles3/effects/copy_effects.cpp index c8e6c2b476..de0181f887 100644 --- a/drivers/gles3/effects/copy_effects.cpp +++ b/drivers/gles3/effects/copy_effects.cpp @@ -111,6 +111,7 @@ CopyEffects::~CopyEffects() { glDeleteVertexArrays(1, &screen_triangle_array); glDeleteBuffers(1, &quad); glDeleteVertexArrays(1, &quad_array); + copy.shader.version_free(copy.shader_version); } void CopyEffects::copy_to_rect(const Rect2i &p_rect) { diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index a5dec393bb..83154acd51 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -135,7 +135,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ Size2i ssize = texture_storage->render_target_get_size(p_to_render_target); Transform3D screen_transform; - screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); + screen_transform.translate_local(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f)); _update_transform_to_mat4(screen_transform, state_buffer.screen_transform); _update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform); @@ -183,7 +183,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_LOCATION, state.canvas_state_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW); - GLuint global_buffer = material_storage->global_variables_get_uniform_buffer(); + GLuint global_buffer = material_storage->global_shader_uniforms_get_uniform_buffer(); glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_LOCATION, global_buffer); glBindBuffer(GL_UNIFORM_BUFFER, 0); @@ -815,10 +815,8 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item _bind_canvas_texture(texture, current_filter, current_repeat, r_index); if (instance_count == 1) { GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_ATTRIBUTES); - } else if (instance_count > 1) { - GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_INSTANCED); } else { - ERR_PRINT("Must have at least one mesh instance to draw mesh"); + GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_INSTANCED); } uint32_t surf_count = mesh_storage->mesh_get_surface_count(mesh); @@ -882,7 +880,7 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item } else { glDrawArrays(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(surface)); } - } else if (instance_count > 1) { + } else { if (use_index_buffer) { glDrawElementsInstanced(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(surface), mesh_storage->mesh_surface_get_index_type(surface), 0, instance_count); } else { @@ -1570,7 +1568,7 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() { glBindBuffer(GL_UNIFORM_BUFFER, 0); String global_defines; - global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now + global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now global_defines += "#define MAX_LIGHTS " + itos(state.max_instances_per_batch) + "\n"; global_defines += "#define MAX_DRAW_DATA_INSTANCES " + itos(state.max_instances_per_batch) + "\n"; @@ -1610,6 +1608,8 @@ void fragment() { RasterizerCanvasGLES3::~RasterizerCanvasGLES3() { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); + memdelete_arr(state.instance_data_array); + GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_free(state.canvas_shader_default_version); material_storage->material_free(default_canvas_group_material); material_storage->shader_free(default_canvas_group_shader); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 969a9b2c42..7207a6efbb 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/templates/sort_array.h" #include "servers/rendering/rendering_server_default.h" +#include "servers/rendering/rendering_server_globals.h" #include "storage/config.h" #include "storage/light_storage.h" #include "storage/mesh_storage.h" @@ -39,15 +40,9 @@ #ifdef GLES3_ENABLED -uint64_t RasterizerSceneGLES3::auto_exposure_counter = 2; - RasterizerSceneGLES3 *RasterizerSceneGLES3::singleton = nullptr; -RasterizerSceneGLES3 *RasterizerSceneGLES3::get_singleton() { - return singleton; -} - -RendererSceneRender::GeometryInstance *RasterizerSceneGLES3::geometry_instance_create(RID p_base) { +RenderGeometryInstance *RasterizerSceneGLES3::geometry_instance_create(RID p_base) { RS::InstanceType type = RSG::utilities->get_base_type(p_base); ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); @@ -57,176 +52,36 @@ RendererSceneRender::GeometryInstance *RasterizerSceneGLES3::geometry_instance_c ginstance->data->base = p_base; ginstance->data->base_type = type; - _geometry_instance_mark_dirty(ginstance); + ginstance->_mark_dirty(); return ginstance; } -void RasterizerSceneGLES3::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->skeleton = p_skeleton; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RasterizerSceneGLES3::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_override = p_override; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RasterizerSceneGLES3::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_overlay = p_overlay; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RasterizerSceneGLES3::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->surface_materials = p_materials; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RasterizerSceneGLES3::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ERR_FAIL_COND(!ginstance); - ginstance->mesh_instance = p_mesh_instance; - - _geometry_instance_mark_dirty(ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->transform = p_transform; - ginstance->mirror = p_transform.basis.determinant() < 0; - ginstance->data->aabb = p_aabb; - ginstance->transformed_aabb = p_transformed_aabb; - - Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); - // handle non uniform scale here - - float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); - float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); - ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; - - ginstance->lod_model_scale = max_scale; -} - -void RasterizerSceneGLES3::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->layer_mask = p_layer_mask; -} - -void RasterizerSceneGLES3::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lod_bias = p_lod_bias; -} - -void RasterizerSceneGLES3::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->force_alpha = CLAMP(1.0 - p_transparency, 0, 1); -} - -void RasterizerSceneGLES3::geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->fade_near = p_enable_near; - ginstance->fade_near_begin = p_near_begin; - ginstance->fade_near_end = p_near_end; - ginstance->fade_far = p_enable_far; - ginstance->fade_far_begin = p_far_begin; - ginstance->fade_far_end = p_far_end; -} - -void RasterizerSceneGLES3::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->parent_fade_alpha = p_alpha; -} - -void RasterizerSceneGLES3::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_baked_light = p_enable; - - _geometry_instance_mark_dirty(ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_dynamic_gi = p_enable; - _geometry_instance_mark_dirty(ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->shader_parameters_offset = p_offset; - _geometry_instance_mark_dirty(ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->cast_double_sided_shadows = p_enable; - _geometry_instance_mark_dirty(ginstance); -} - uint32_t RasterizerSceneGLES3::geometry_instance_get_pair_mask() { return (1 << RS::INSTANCE_LIGHT); } -void RasterizerSceneGLES3::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - +void RasterizerSceneGLES3::GeometryInstanceGLES3::pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) { GLES3::Config *config = GLES3::Config::get_singleton(); - ginstance->omni_light_count = 0; - ginstance->spot_light_count = 0; - ginstance->omni_lights.clear(); - ginstance->spot_lights.clear(); + omni_light_count = 0; + spot_light_count = 0; + omni_lights.clear(); + spot_lights.clear(); for (uint32_t i = 0; i < p_light_instance_count; i++) { - RS::LightType type = light_instance_get_type(p_light_instances[i]); + RS::LightType type = RasterizerSceneGLES3::get_singleton()->light_instance_get_type(p_light_instances[i]); switch (type) { case RS::LIGHT_OMNI: { - if (ginstance->omni_light_count < (uint32_t)config->max_lights_per_object) { - ginstance->omni_lights.push_back(p_light_instances[i]); - ginstance->omni_light_count++; + if (omni_light_count < (uint32_t)config->max_lights_per_object) { + omni_lights.push_back(p_light_instances[i]); + omni_light_count++; } } break; case RS::LIGHT_SPOT: { - if (ginstance->spot_light_count < (uint32_t)config->max_lights_per_object) { - ginstance->spot_lights.push_back(p_light_instances[i]); - ginstance->spot_light_count++; + if (spot_light_count < (uint32_t)config->max_lights_per_object) { + spot_lights.push_back(p_light_instances[i]); + spot_light_count++; } } break; default: @@ -235,21 +90,7 @@ void RasterizerSceneGLES3::geometry_instance_pair_light_instances(GeometryInstan } } -void RasterizerSceneGLES3::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { -} - -void RasterizerSceneGLES3::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) { -} - -void RasterizerSceneGLES3::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { -} - -void RasterizerSceneGLES3::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_free(GeometryInstance *p_geometry_instance) { +void RasterizerSceneGLES3::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) { GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); GeometryInstanceSurface *surf = ginstance->surface_caches; @@ -262,24 +103,29 @@ void RasterizerSceneGLES3::geometry_instance_free(GeometryInstance *p_geometry_i geometry_instance_alloc.free(ginstance); } -void RasterizerSceneGLES3::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - if (ginstance->dirty_list_element.in_list()) { +void RasterizerSceneGLES3::GeometryInstanceGLES3::_mark_dirty() { + if (dirty_list_element.in_list()) { return; } //clear surface caches - GeometryInstanceSurface *surf = ginstance->surface_caches; + GeometryInstanceSurface *surf = surface_caches; while (surf) { GeometryInstanceSurface *next = surf->next; - geometry_instance_surface_alloc.free(surf); + RasterizerSceneGLES3::get_singleton()->geometry_instance_surface_alloc.free(surf); surf = next; } - ginstance->surface_caches = nullptr; + surface_caches = nullptr; - geometry_instance_dirty_list.add(&ginstance->dirty_list_element); + RasterizerSceneGLES3::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element); +} + +void RasterizerSceneGLES3::GeometryInstanceGLES3::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { +} + +void RasterizerSceneGLES3::GeometryInstanceGLES3::set_lightmap_capture(const Color *p_sh9) { } void RasterizerSceneGLES3::_update_dirty_geometry_instances() { @@ -295,7 +141,7 @@ void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::Dep case Dependency::DEPENDENCY_CHANGED_PARTICLES: case Dependency::DEPENDENCY_CHANGED_MULTIMESH: case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { - static_cast<RasterizerSceneGLES3 *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } break; case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata); @@ -310,7 +156,7 @@ void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::Dep } void RasterizerSceneGLES3::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { - static_cast<RasterizerSceneGLES3 *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { @@ -467,7 +313,7 @@ void RasterizerSceneGLES3::_geometry_instance_add_surface(GeometryInstanceGLES3 } } -void RasterizerSceneGLES3::_geometry_instance_update(GeometryInstance *p_geometry_instance) { +void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) { GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton(); GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); @@ -650,8 +496,7 @@ void RasterizerSceneGLES3::_update_dirty_skys() { while (sky) { if (sky->radiance == 0) { - sky->mipmap_count = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8) + 1; - + sky->mipmap_count = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8) - 1; // Left uninitialized, will attach a texture at render time glGenFramebuffers(1, &sky->radiance_framebuffer); @@ -678,7 +523,7 @@ void RasterizerSceneGLES3::_update_dirty_skys() { glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count - 1); glGenTextures(1, &sky->raw_radiance); glBindTexture(GL_TEXTURE_CUBE_MAP, sky->raw_radiance); @@ -699,7 +544,8 @@ void RasterizerSceneGLES3::_update_dirty_skys() { glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count - 1); + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); } @@ -715,13 +561,13 @@ void RasterizerSceneGLES3::_update_dirty_skys() { dirty_sky_list = nullptr; } -void RasterizerSceneGLES3::_setup_sky(Environment *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) { +void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) { GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); GLES3::SkyMaterialData *material = nullptr; - Sky *sky = sky_owner.get_or_null(p_env->sky); + Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env)); RID sky_material; @@ -856,22 +702,23 @@ void RasterizerSceneGLES3::_setup_sky(Environment *p_env, RID p_render_buffers, } if (!sky->radiance) { + _invalidate_sky(sky); _update_dirty_skys(); } } } -void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const Projection &p_projection, const Transform3D &p_transform) { +void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); - Sky *sky = sky_owner.get_or_null(p_env->sky); + Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env)); ERR_FAIL_COND(!sky); GLES3::SkyMaterialData *material_data = nullptr; RID sky_material; - RS::EnvironmentBG background = p_env->background; + RS::EnvironmentBG background = environment_get_background(p_env); if (sky) { ERR_FAIL_COND(!sky); @@ -903,16 +750,16 @@ void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const Projection &p_pro // Camera Projection camera; - if (p_env->sky_custom_fov) { + if (environment_get_sky_custom_fov(p_env)) { float near_plane = p_projection.get_z_near(); float far_plane = p_projection.get_z_far(); float aspect = p_projection.get_aspect(); - camera.set_perspective(p_env->sky_custom_fov, aspect, near_plane, far_plane); + camera.set_perspective(environment_get_sky_custom_fov(p_env), aspect, near_plane, far_plane); } else { camera = p_projection; } - Basis sky_transform = p_env->sky_orientation; + Basis sky_transform = environment_get_sky_orientation(p_env); sky_transform.invert(); sky_transform = p_transform.basis * sky_transform; @@ -926,17 +773,17 @@ void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const Projection &p_pro glDrawArrays(GL_TRIANGLES, 0, 3); } -void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Projection &p_projection, const Transform3D &p_transform) { +void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); - Sky *sky = sky_owner.get_or_null(p_env->sky); + Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env)); ERR_FAIL_COND(!sky); GLES3::SkyMaterialData *material_data = nullptr; RID sky_material; - RS::EnvironmentBG background = p_env->background; + RS::EnvironmentBG background = environment_get_background(p_env); if (sky) { ERR_FAIL_COND(!sky); @@ -990,7 +837,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Projec int max_processing_layer = sky->mipmap_count; // Update radiance cubemap - if (sky->reflection_dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) { + if (sky->reflection_dirty && (sky->processing_layer > max_processing_layer || update_single_frame)) { static const Vector3 view_normals[6] = { Vector3(+1, 0, 0), Vector3(-1, 0, 0), @@ -1051,6 +898,45 @@ void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Projec } } +// Helper functions for IBL filtering + +Vector3 importance_sample_GGX(Vector2 xi, float roughness4) { + // Compute distribution direction + float phi = 2.0 * Math_PI * xi.x; + float cos_theta = sqrt((1.0 - xi.y) / (1.0 + (roughness4 - 1.0) * xi.y)); + float sin_theta = sqrt(1.0 - cos_theta * cos_theta); + + // Convert to spherical direction + Vector3 half_vector; + half_vector.x = sin_theta * cos(phi); + half_vector.y = sin_theta * sin(phi); + half_vector.z = cos_theta; + + return half_vector; +} + +float distribution_GGX(float NdotH, float roughness4) { + float NdotH2 = NdotH * NdotH; + float denom = (NdotH2 * (roughness4 - 1.0) + 1.0); + denom = Math_PI * denom * denom; + + return roughness4 / denom; +} + +float radical_inverse_vdC(uint32_t bits) { + bits = (bits << 16) | (bits >> 16); + bits = ((bits & 0x55555555) << 1) | ((bits & 0xAAAAAAAA) >> 1); + bits = ((bits & 0x33333333) << 2) | ((bits & 0xCCCCCCCC) >> 2); + bits = ((bits & 0x0F0F0F0F) << 4) | ((bits & 0xF0F0F0F0) >> 4); + bits = ((bits & 0x00FF00FF) << 8) | ((bits & 0xFF00FF00) >> 8); + + return float(bits) * 2.3283064365386963e-10; +} + +Vector2 hammersley(uint32_t i, uint32_t N) { + return Vector2(float(i) / float(N), radical_inverse_vdC(i)); +} + void RasterizerSceneGLES3::_filter_sky_radiance(Sky *p_sky, int p_base_layer) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); @@ -1062,27 +948,68 @@ void RasterizerSceneGLES3::_filter_sky_radiance(Sky *p_sky, int p_base_layer) { if (p_base_layer == 0) { glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + // Copy over base layer without filtering. mode = CubemapFilterShaderGLES3::MODE_COPY; - - //Copy over base layer } - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, sky_globals.radical_inverse_vdc_cache_tex); int size = p_sky->radiance_size >> p_base_layer; glViewport(0, 0, size, size); glBindVertexArray(sky_globals.screen_triangle_array); material_storage->shaders.cubemap_filter_shader.version_bind_shader(scene_globals.cubemap_filter_shader_version, mode); - material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::SAMPLE_COUNT, sky_globals.ggx_samples, scene_globals.cubemap_filter_shader_version, mode); - material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, float(p_base_layer) / (p_sky->mipmap_count - 1.0), scene_globals.cubemap_filter_shader_version, mode); - material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::FACE_SIZE, float(size), scene_globals.cubemap_filter_shader_version, mode); + + if (p_base_layer > 0) { + const uint32_t sample_counts[4] = { 1, sky_globals.ggx_samples / 4, sky_globals.ggx_samples / 2, sky_globals.ggx_samples }; + uint32_t sample_count = sample_counts[MIN(3, p_base_layer)]; + + float roughness = float(p_base_layer) / (p_sky->mipmap_count); + float roughness4 = roughness * roughness; + roughness4 *= roughness4; + + float solid_angle_texel = 4.0 * Math_PI / float(6 * size * size); + + LocalVector<float> sample_directions; + sample_directions.resize(4 * sample_count); + + uint32_t index = 0; + float weight = 0.0; + for (uint32_t i = 0; i < sample_count; i++) { + Vector2 xi = hammersley(i, sample_count); + Vector3 dir = importance_sample_GGX(xi, roughness4); + Vector3 light_vec = (2.0 * dir.z * dir - Vector3(0.0, 0.0, 1.0)); + + if (light_vec.z < 0.0) { + continue; + } + + sample_directions[index * 4] = light_vec.x; + sample_directions[index * 4 + 1] = light_vec.y; + sample_directions[index * 4 + 2] = light_vec.z; + + float D = distribution_GGX(dir.z, roughness4); + float pdf = D * dir.z / (4.0 * dir.z) + 0.0001; + + float solid_angle_sample = 1.0 / (float(sample_count) * pdf + 0.0001); + + float mip_level = MAX(0.5 * log2(solid_angle_sample / solid_angle_texel) + float(MAX(1, p_base_layer - 3)), 1.0); + + sample_directions[index * 4 + 3] = mip_level; + weight += light_vec.z; + index++; + } + + glUniform4fv(material_storage->shaders.cubemap_filter_shader.version_get_uniform(CubemapFilterShaderGLES3::SAMPLE_DIRECTIONS_MIP, scene_globals.cubemap_filter_shader_version, mode), sample_count, sample_directions.ptr()); + material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::WEIGHT, weight, scene_globals.cubemap_filter_shader_version, mode); + material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::SAMPLE_COUNT, index, scene_globals.cubemap_filter_shader_version, mode); + } for (int i = 0; i < 6; i++) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, p_sky->radiance, p_base_layer); #ifdef DEBUG_ENABLED GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE); + if (status != GL_FRAMEBUFFER_COMPLETE) { + WARN_PRINT("Could not bind sky radiance face: " + itos(i) + ", status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status)); + } #endif material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::FACE_ID, i, scene_globals.cubemap_filter_shader_version, mode); @@ -1099,84 +1026,6 @@ Ref<Image> RasterizerSceneGLES3::sky_bake_panorama(RID p_sky, float p_energy, bo /* ENVIRONMENT API */ -RID RasterizerSceneGLES3::environment_allocate() { - return environment_owner.allocate_rid(); -} - -void RasterizerSceneGLES3::environment_initialize(RID p_rid) { - environment_owner.initialize_rid(p_rid); -} - -void RasterizerSceneGLES3::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->background = p_bg; -} - -void RasterizerSceneGLES3::environment_set_sky(RID p_env, RID p_sky) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky = p_sky; -} - -void RasterizerSceneGLES3::environment_set_sky_custom_fov(RID p_env, float p_scale) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky_custom_fov = p_scale; -} - -void RasterizerSceneGLES3::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky_orientation = p_orientation; -} - -void RasterizerSceneGLES3::environment_set_bg_color(RID p_env, const Color &p_color) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->bg_color = p_color; -} - -void RasterizerSceneGLES3::environment_set_bg_energy(RID p_env, float p_energy) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->bg_energy = p_energy; -} - -void RasterizerSceneGLES3::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->canvas_max_layer = p_max_layer; -} - -void RasterizerSceneGLES3::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->ambient_light = p_color; - env->ambient_source = p_ambient; - env->ambient_light_energy = p_energy; - env->ambient_sky_contribution = p_sky_contribution; - env->reflection_source = p_reflection_source; -} - -void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7"); - env->glow_enabled = p_enable; - env->glow_levels = p_levels; - env->glow_intensity = p_intensity; - env->glow_strength = p_strength; - env->glow_mix = p_mix; - env->glow_bloom = p_bloom_threshold; - env->glow_blend_mode = p_blend_mode; - env->glow_hdr_bleed_threshold = p_hdr_bleed_threshold; - env->glow_hdr_bleed_scale = p_hdr_bleed_scale; - env->glow_hdr_luminance_cap = p_hdr_luminance_cap; - env->glow_map_strength = p_glow_map_strength; - env->glow_map = p_glow_map; -} - void RasterizerSceneGLES3::environment_glow_set_use_bicubic_upscale(bool p_enable) { glow_bicubic_upscale = p_enable; } @@ -1185,35 +1034,15 @@ void RasterizerSceneGLES3::environment_glow_set_use_high_quality(bool p_enable) glow_high_quality = p_enable; } -void RasterizerSceneGLES3::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->ssr_enabled = p_enable; - env->ssr_max_steps = p_max_steps; - env->ssr_fade_in = p_fade_int; - env->ssr_fade_out = p_fade_out; - env->ssr_depth_tolerance = p_depth_tolerance; -} - void RasterizerSceneGLES3::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) { } -void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); -} - void RasterizerSceneGLES3::environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) { } -void RasterizerSceneGLES3::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) { -} void RasterizerSceneGLES3::environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) { } -void RasterizerSceneGLES3::environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { -} - void RasterizerSceneGLES3::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) { } @@ -1223,49 +1052,6 @@ void RasterizerSceneGLES3::environment_set_sdfgi_frames_to_converge(RS::Environm void RasterizerSceneGLES3::environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) { } -void RasterizerSceneGLES3::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->exposure = p_exposure; - env->tone_mapper = p_tone_mapper; - if (!env->auto_exposure && p_auto_exposure) { - env->auto_exposure_version = ++auto_exposure_counter; - } - env->auto_exposure = p_auto_exposure; - env->white = p_white; - env->min_luminance = p_min_luminance; - env->max_luminance = p_max_luminance; - env->auto_exp_speed = p_auto_exp_speed; - env->auto_exp_scale = p_auto_exp_scale; -} - -void RasterizerSceneGLES3::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->adjustments_enabled = p_enable; - env->adjustments_brightness = p_brightness; - env->adjustments_contrast = p_contrast; - env->adjustments_saturation = p_saturation; - env->use_1d_color_correction = p_use_1d_color_correction; - env->color_correction = p_color_correction; -} - -void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->fog_enabled = p_enable; - env->fog_light_color = p_light_color; - env->fog_light_energy = p_light_energy; - env->fog_sun_scatter = p_sun_scatter; - env->fog_density = p_density; - env->fog_height = p_height; - env->fog_height_density = p_height_density; - env->fog_aerial_perspective = p_aerial_perspective; -} - -void RasterizerSceneGLES3::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { -} - void RasterizerSceneGLES3::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) { } @@ -1273,27 +1059,9 @@ void RasterizerSceneGLES3::environment_set_volumetric_fog_filter_active(bool p_e } Ref<Image> RasterizerSceneGLES3::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Ref<Image>()); return Ref<Image>(); } -bool RasterizerSceneGLES3::is_environment(RID p_env) const { - return environment_owner.owns(p_env); -} - -RS::EnvironmentBG RasterizerSceneGLES3::environment_get_background(RID p_env) const { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX); - return env->background; -} - -int RasterizerSceneGLES3::environment_get_canvas_max_layer(RID p_env) const { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->canvas_max_layer; -} - RID RasterizerSceneGLES3::camera_effects_allocate() { return RID(); } @@ -1431,7 +1199,7 @@ bool RasterizerSceneGLES3::voxel_gi_needs_update(RID p_probe) const { return false; } -void RasterizerSceneGLES3::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) { +void RasterizerSceneGLES3::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) { } void RasterizerSceneGLES3::voxel_gi_set_quality(RS::VoxelGIQuality) { @@ -1633,18 +1401,17 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da scene_state.ubo.time = time; if (is_environment(p_render_data->environment)) { - Environment *env = environment_owner.get_or_null(p_render_data->environment); - RS::EnvironmentBG env_bg = env->background; - RS::EnvironmentAmbientSource ambient_src = env->ambient_source; + RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment); + RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment); - float bg_energy = env->bg_energy; + float bg_energy = environment_get_bg_energy(p_render_data->environment); scene_state.ubo.ambient_light_color_energy[3] = bg_energy; - scene_state.ubo.ambient_color_sky_mix = env->ambient_sky_contribution; + scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment); //ambient if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { - Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : env->bg_color; + Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy; @@ -1653,14 +1420,14 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da scene_state.ubo.use_ambient_light = true; scene_state.ubo.use_ambient_cubemap = false; } else { - float energy = env->ambient_light_energy; - Color color = env->ambient_light; + float energy = environment_get_ambient_light_energy(p_render_data->environment); + Color color = environment_get_ambient_light(p_render_data->environment); color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; scene_state.ubo.ambient_light_color_energy[2] = color.b * energy; - Basis sky_transform = env->sky_orientation; + Basis sky_transform = environment_get_sky_orientation(p_render_data->environment); sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis; GLES3::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; @@ -1668,27 +1435,27 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da } //specular - RS::EnvironmentReflectionSource ref_src = env->reflection_source; + RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment); if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) { scene_state.ubo.use_reflection_cubemap = true; } else { scene_state.ubo.use_reflection_cubemap = false; } - scene_state.ubo.fog_enabled = env->fog_enabled; - scene_state.ubo.fog_density = env->fog_density; - scene_state.ubo.fog_height = env->fog_height; - scene_state.ubo.fog_height_density = env->fog_height_density; - scene_state.ubo.fog_aerial_perspective = env->fog_aerial_perspective; + scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment); + scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment); + scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment); + scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); + scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment); - Color fog_color = env->fog_light_color.srgb_to_linear(); - float fog_energy = env->fog_light_energy; + Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear(); + float fog_energy = environment_get_fog_light_energy(p_render_data->environment); scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; - scene_state.ubo.fog_sun_scatter = env->fog_sun_scatter; + scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment); } else { } @@ -1883,7 +1650,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b light_data.specular_amount = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0; - light_data.shadow_enabled = false; + light_data.shadow_opacity = 0.0; } // TODO, to avoid stalls, should rotate between 3 buffers based on frame index. @@ -1905,7 +1672,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b glBindBuffer(GL_UNIFORM_BUFFER, 0); } -void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { +void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::Config *config = GLES3::Config::get_singleton(); RENDER_TIMESTAMP("Setup 3D Scene"); @@ -1970,7 +1737,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * // Fill Light lists here ////////// - GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_variables_get_uniform_buffer(); + GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_uniforms_get_uniform_buffer(); glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer); Color clear_color; @@ -1980,8 +1747,6 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * clear_color = texture_storage->get_default_clear_color(); } - Environment *env = environment_owner.get_or_null(p_environment); - bool fb_cleared = false; Size2i screen_size; @@ -1991,10 +1756,10 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * bool use_wireframe = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME; SceneState::TonemapUBO tonemap_ubo; - if (env) { - tonemap_ubo.exposure = env->exposure; - tonemap_ubo.white = env->white; - tonemap_ubo.tonemapper = int32_t(env->tone_mapper); + if (render_data.environment.is_valid()) { + tonemap_ubo.exposure = environment_get_exposure(render_data.environment); + tonemap_ubo.white = environment_get_white(render_data.environment); + tonemap_ubo.tonemapper = int32_t(environment_get_tone_mapper(render_data.environment)); } if (scene_state.tonemap_buffer == 0) { @@ -2017,25 +1782,25 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black - } else if (env) { - RS::EnvironmentBG bg_mode = env->background; - float bg_energy = env->bg_energy; + } else if (render_data.environment.is_valid()) { + RS::EnvironmentBG bg_mode = environment_get_background(render_data.environment); + float bg_energy = environment_get_bg_energy(render_data.environment); switch (bg_mode) { case RS::ENV_BG_CLEAR_COLOR: { clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if (env->fog_enabled) { + if (environment_get_fog_enabled(render_data.environment)) { draw_sky_fog_only = true; GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color)); } } break; case RS::ENV_BG_COLOR: { - clear_color = env->bg_color; + clear_color = environment_get_bg_color(render_data.environment); clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if (env->fog_enabled) { + if (environment_get_fog_enabled(render_data.environment)) { draw_sky_fog_only = true; GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color)); } @@ -2055,7 +1820,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * } } // setup sky if used for ambient, reflections, or background - if (draw_sky || draw_sky_fog_only || env->reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || env->ambient_source == RS::ENV_AMBIENT_SOURCE_SKY) { + if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); Projection projection = render_data.cam_projection; if (render_data.reflection_probe.is_valid()) { @@ -2064,11 +1829,11 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * projection = correction * render_data.cam_projection; } - _setup_sky(env, p_render_buffers, *render_data.lights, projection, render_data.cam_transform, screen_size); + _setup_sky(render_data.environment, p_render_buffers, *render_data.lights, projection, render_data.cam_transform, screen_size); - if (env->sky.is_valid()) { - if (env->reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || env->ambient_source == RS::ENV_AMBIENT_SOURCE_SKY || (env->reflection_source == RS::ENV_REFLECTION_SOURCE_BG && env->background == RS::ENV_BG_SKY)) { - _update_sky_radiance(env, projection, render_data.cam_transform); + if (environment_get_sky(render_data.environment).is_valid()) { + if (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY || (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_BG && environment_get_background(render_data.environment) == RS::ENV_BG_SKY)) { + _update_sky_radiance(render_data.environment, projection, render_data.cam_transform); } } else { // do not try to draw sky if invalid @@ -2148,7 +1913,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS; } - if (!env || (env && !env->fog_enabled)) { + if (render_data.environment.is_null() || (render_data.environment.is_valid() && !environment_get_fog_enabled(render_data.environment))) { spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG; } } @@ -2172,7 +1937,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * scene_state.current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_DISABLED; scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK; - _draw_sky(env, render_data.cam_projection, render_data.cam_transform); + _draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform); } RENDER_TIMESTAMP("Render 3D Transparent Pass"); @@ -2221,11 +1986,10 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, } if (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) { - Environment *env = environment_owner.get_or_null(p_render_data->environment); glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 2); GLuint texture_to_bind = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_CUBEMAP_BLACK))->tex_id; - if (env) { - Sky *sky = sky_owner.get_or_null(env->sky); + if (p_render_data->environment.is_valid()) { + Sky *sky = sky_owner.get_or_null(environment_get_sky(p_render_data->environment)); if (sky && sky->radiance != 0) { texture_to_bind = sky->radiance; // base_spec_constant |= USE_RADIANCE_MAP; @@ -2490,10 +2254,10 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, } } -void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { } -void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) { +void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) { } void RasterizerSceneGLES3::set_time(double p_time, double p_step) { @@ -2510,7 +2274,7 @@ RID RasterizerSceneGLES3::render_buffers_create() { return render_buffers_owner.make_rid(rb); } -void RasterizerSceneGLES3::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { +void RasterizerSceneGLES3::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); @@ -2543,7 +2307,7 @@ void RasterizerSceneGLES3::render_buffers_configure(RID p_render_buffers, RID p_ glGenTextures(1, &rb->depth_texture); glBindTexture(GL_TEXTURE_2D, rb->depth_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -2624,8 +2388,8 @@ TypedArray<Image> RasterizerSceneGLES3::bake_render_uv2(RID p_base, const Vector } bool RasterizerSceneGLES3::free(RID p_rid) { - if (environment_owner.owns(p_rid)) { - environment_owner.free(p_rid); + if (is_environment(p_rid)) { + environment_free(p_rid); } else if (sky_owner.owns(p_rid)) { Sky *sky = sky_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!sky, false); @@ -2661,6 +2425,8 @@ void RasterizerSceneGLES3::light_projectors_set_filter(RS::LightProjectorFilter } RasterizerSceneGLES3::RasterizerSceneGLES3() { + singleton = this; + GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); GLES3::Config *config = GLES3::Config::get_singleton(); @@ -2705,7 +2471,7 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { { String global_defines; - global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now + global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now global_defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(config->max_renderable_lights) + "\n"; global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n"; global_defines += "\n#define MAX_FORWARD_LIGHTS " + itos(config->max_lights_per_object) + "\n"; @@ -2744,13 +2510,17 @@ void fragment() { sky_globals.ggx_samples = GLOBAL_GET("rendering/reflections/sky_reflections/ggx_samples"); String global_defines; - global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now + global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(sky_globals.max_directional_lights) + "\n"; material_storage->shaders.sky_shader.initialize(global_defines); sky_globals.shader_default_version = material_storage->shaders.sky_shader.version_create(); material_storage->shaders.sky_shader.version_bind_shader(sky_globals.shader_default_version, SkyShaderGLES3::MODE_BACKGROUND); + } - material_storage->shaders.cubemap_filter_shader.initialize(); + { + String global_defines; + global_defines += "\n#define MAX_SAMPLE_COUNT " + itos(sky_globals.ggx_samples) + "\n"; + material_storage->shaders.cubemap_filter_shader.initialize(global_defines); scene_globals.cubemap_filter_shader_version = material_storage->shaders.cubemap_filter_shader.version_create(); material_storage->shaders.cubemap_filter_shader.version_bind_shader(scene_globals.cubemap_filter_shader_version, CubemapFilterShaderGLES3::MODE_DEFAULT); } @@ -2820,36 +2590,6 @@ void sky() { glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind } - // Radical inverse vdc cache texture used for cubemap filtering. - { - glGenTextures(1, &sky_globals.radical_inverse_vdc_cache_tex); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, sky_globals.radical_inverse_vdc_cache_tex); - - uint8_t radical_inverse[512]; - - for (uint32_t i = 0; i < 512; i++) { - uint32_t bits = i; - - bits = (bits << 16) | (bits >> 16); - bits = ((bits & 0x55555555) << 1) | ((bits & 0xAAAAAAAA) >> 1); - bits = ((bits & 0x33333333) << 2) | ((bits & 0xCCCCCCCC) >> 2); - bits = ((bits & 0x0F0F0F0F) << 4) | ((bits & 0xF0F0F0F0) >> 4); - bits = ((bits & 0x00FF00FF) << 8) | ((bits & 0xFF00FF00) >> 8); - - float value = float(bits) * 2.3283064365386963e-10; - radical_inverse[i] = uint8_t(CLAMP(value * 255.0, 0, 255)); - } - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 512, 1, 0, GL_RED, GL_UNSIGNED_BYTE, radical_inverse); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //need this for proper sampling - - glBindTexture(GL_TEXTURE_2D, 0); - } #ifdef GLES_OVER_GL glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS); #endif @@ -2886,6 +2626,8 @@ RasterizerSceneGLES3::~RasterizerSceneGLES3() { glDeleteBuffers(1, &sky_globals.directional_light_buffer); memdelete_arr(sky_globals.directional_lights); memdelete_arr(sky_globals.last_frame_directional_lights); + + singleton = nullptr; } #endif // GLES3_ENABLED diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 3ac8770228..a54d87a3a3 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -107,7 +107,7 @@ struct RenderDataGLES3 { float z_near = 0.0; float z_far = 0.0; - const PagedArray<RendererSceneRender::GeometryInstance *> *instances = nullptr; + const PagedArray<RenderGeometryInstance *> *instances = nullptr; const PagedArray<RID> *lights = nullptr; const PagedArray<RID> *reflection_probes = nullptr; RID environment = RID(); @@ -165,7 +165,7 @@ private: float inv_spot_attenuation; float cos_spot_angle; float specular_amount; - uint32_t shadow_enabled; + float shadow_opacity; }; static_assert(sizeof(LightData) % 16 == 0, "LightData size must be a multiple of 16 bytes"); @@ -210,7 +210,7 @@ private: mutable RID_Owner<LightInstance> light_instance_owner; - struct GeometryInstanceGLES3; + class GeometryInstanceGLES3; // Cached data for drawing surfaces struct GeometryInstanceSurface { @@ -265,33 +265,16 @@ private: GeometryInstanceGLES3 *owner = nullptr; }; - struct GeometryInstanceGLES3 : public GeometryInstance { + class GeometryInstanceGLES3 : public RenderGeometryInstanceBase { + public: //used during rendering - bool mirror = false; - bool non_uniform_scale = false; - float lod_bias = 0.0; - float lod_model_scale = 1.0; - AABB transformed_aabb; //needed for LOD - float depth = 0; - uint32_t flags_cache = 0; bool store_transform_cache = true; - int32_t shader_parameters_offset = -1; - uint32_t layer_mask = 1; int32_t instance_count = 0; - RID mesh_instance; bool can_sdfgi = false; bool using_projectors = false; bool using_softshadows = false; - bool fade_near = false; - float fade_near_begin = 0; - float fade_near_end = 0; - bool fade_far = false; - float fade_far_begin = 0; - float fade_far_end = 0; - float force_alpha = 1.0; - float parent_fade_alpha = 1.0; uint32_t omni_light_count = 0; LocalVector<RID> omni_lights; @@ -301,35 +284,22 @@ private: LocalVector<uint32_t> spot_light_gl_cache; //used during setup - uint32_t base_flags = 0; - Transform3D transform; GeometryInstanceSurface *surface_caches = nullptr; SelfList<GeometryInstanceGLES3> dirty_list_element; - struct Data { - //data used less often goes into regular heap - RID base; - RS::InstanceType base_type; - - RID skeleton; - Vector<RID> surface_materials; - RID material_override; - RID material_overlay; - AABB aabb; - - bool use_dynamic_gi = false; - bool use_baked_light = false; - bool cast_double_sided_shadows = false; - bool mirror = false; - bool dirty_dependencies = false; + GeometryInstanceGLES3() : + dirty_list_element(this) {} - DependencyTracker dependency_tracker; - }; + virtual void _mark_dirty() override; + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; + virtual void set_lightmap_capture(const Color *p_sh9) override; - Data *data = nullptr; + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override; + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} - GeometryInstanceGLES3() : - dirty_list_element(this) {} + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override {} }; enum { @@ -357,8 +327,7 @@ private: void _geometry_instance_add_surface_with_material(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh); void _geometry_instance_add_surface_with_material_chain(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, RID p_mat_src, RID p_mesh); void _geometry_instance_add_surface(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, RID p_material, RID p_mesh); - void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance); - void _geometry_instance_update(GeometryInstance *p_geometry_instance); + void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance); void _update_dirty_geometry_instances(); struct SceneState { @@ -570,85 +539,6 @@ protected: /* Environment */ - struct Environment { - // BG - RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR; - RID sky; - float sky_custom_fov = 0.0; - Basis sky_orientation; - Color bg_color; - float bg_energy = 1.0; - int canvas_max_layer = 0; - RS::EnvironmentAmbientSource ambient_source = RS::ENV_AMBIENT_SOURCE_BG; - Color ambient_light; - float ambient_light_energy = 1.0; - float ambient_sky_contribution = 1.0; - RS::EnvironmentReflectionSource reflection_source = RS::ENV_REFLECTION_SOURCE_BG; - Color ao_color; - - /// Tonemap - - RS::EnvironmentToneMapper tone_mapper; - float exposure = 1.0; - float white = 1.0; - bool auto_exposure = false; - float min_luminance = 0.2; - float max_luminance = 8.0; - float auto_exp_speed = 0.2; - float auto_exp_scale = 0.5; - uint64_t auto_exposure_version = 0; - - // Fog - bool fog_enabled = false; - Color fog_light_color = Color(0.5, 0.6, 0.7); - float fog_light_energy = 1.0; - float fog_sun_scatter = 0.0; - float fog_density = 0.001; - float fog_height = 0.0; - float fog_height_density = 0.0; //can be negative to invert effect - float fog_aerial_perspective = 0.0; - - /// Glow - bool glow_enabled = false; - Vector<float> glow_levels; - float glow_intensity = 0.8; - float glow_strength = 1.0; - float glow_bloom = 0.0; - float glow_mix = 0.01; - RS::EnvironmentGlowBlendMode glow_blend_mode = RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT; - float glow_hdr_bleed_threshold = 1.0; - float glow_hdr_luminance_cap = 12.0; - float glow_hdr_bleed_scale = 2.0; - float glow_map_strength = 1.0; - RID glow_map = RID(); - - /// SSAO - bool ssao_enabled = false; - float ssao_radius = 1.0; - float ssao_intensity = 2.0; - float ssao_power = 1.5; - float ssao_detail = 0.5; - float ssao_horizon = 0.06; - float ssao_sharpness = 0.98; - float ssao_direct_light_affect = 0.0; - float ssao_ao_channel_affect = 0.0; - - /// SSR - bool ssr_enabled = false; - int ssr_max_steps = 64; - float ssr_fade_in = 0.15; - float ssr_fade_out = 2.0; - float ssr_depth_tolerance = 0.2; - - /// Adjustments - bool adjustments_enabled = false; - float adjustments_brightness = 1.0f; - float adjustments_contrast = 1.0f; - float adjustments_saturation = 1.0f; - bool use_1d_color_correction = false; - RID color_correction = RID(); - }; - RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM; bool ssao_half_size = false; float ssao_adaptive_target = 0.5; @@ -660,10 +550,6 @@ protected: bool glow_high_quality = false; RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGHNESS_QUALITY_LOW; - static uint64_t auto_exposure_counter; - - mutable RID_Owner<Environment, true> environment_owner; - /* Sky */ struct SkyGlobals { @@ -729,44 +615,23 @@ protected: Sky *dirty_sky_list = nullptr; mutable RID_Owner<Sky, true> sky_owner; - void _setup_sky(Environment *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size); + void _setup_sky(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size); void _invalidate_sky(Sky *p_sky); void _update_dirty_skys(); - void _update_sky_radiance(Environment *p_env, const Projection &p_projection, const Transform3D &p_transform); + void _update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform); void _filter_sky_radiance(Sky *p_sky, int p_base_layer); - void _draw_sky(Environment *p_env, const Projection &p_projection, const Transform3D &p_transform); + void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform); void _free_sky_data(Sky *p_sky); public: + static RasterizerSceneGLES3 *get_singleton() { return singleton; } + RasterizerCanvasGLES3 *canvas; - GeometryInstance *geometry_instance_create(RID p_base) override; - void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override; - void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override; - void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) override; - void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override; - void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override; - void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override; - void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override; - void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override; - void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override; - void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override; - void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override; - void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override; - void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override; - void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; - void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override; - void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override; - void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override; + RenderGeometryInstance *geometry_instance_create(RID p_base) override; + void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override; uint32_t geometry_instance_get_pair_mask() override; - void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override; - void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; - void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override; - void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override; - - void geometry_instance_free(GeometryInstance *p_geometry_instance) override; /* SHADOW ATLAS API */ @@ -803,49 +668,24 @@ public: /* ENVIRONMENT API */ - RID environment_allocate() override; - void environment_initialize(RID p_rid) override; - void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override; - void environment_set_sky(RID p_env, RID p_sky) override; - void environment_set_sky_custom_fov(RID p_env, float p_scale) override; - void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override; - void environment_set_bg_color(RID p_env, const Color &p_color) override; - void environment_set_bg_energy(RID p_env, float p_energy) override; - void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override; - void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override; - - void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override; void environment_glow_set_use_bicubic_upscale(bool p_enable) override; void environment_glow_set_use_high_quality(bool p_enable) override; - void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) override; void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override; - void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) override; + void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override; - void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override; - void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override; - void environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override; + void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override; void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override; void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override; void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override; - void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override; - - void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override; - - void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override; - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) override; void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override; void environment_set_volumetric_fog_filter_active(bool p_enable) override; Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override; - bool is_environment(RID p_env) const override; - RS::EnvironmentBG environment_get_background(RID p_env) const override; - int environment_get_canvas_max_layer(RID p_env) const override; - RID camera_effects_allocate() override; void camera_effects_initialize(RID p_rid) override; void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override; @@ -899,13 +739,13 @@ public: RID voxel_gi_instance_create(RID p_voxel_gi) override; void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override; bool voxel_gi_needs_update(RID p_probe) const override; - void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override; + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) override; void voxel_gi_set_quality(RS::VoxelGIQuality) override; - void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; - void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override; + void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; + void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override; void set_scene_pass(uint64_t p_pass) override { scene_pass = p_pass; @@ -922,7 +762,7 @@ public: } RID render_buffers_create() override; - void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; + void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; void gi_set_use_half_resolution(bool p_enable) override; void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override; @@ -940,7 +780,6 @@ public: void decals_set_filter(RS::DecalFilter p_filter) override; void light_projectors_set_filter(RS::LightProjectorFilter p_filter) override; - static RasterizerSceneGLES3 *get_singleton(); RasterizerSceneGLES3(); ~RasterizerSceneGLES3(); }; diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl index e08a15e59d..852dccf415 100644 --- a/drivers/gles3/shaders/canvas_uniforms_inc.glsl +++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl @@ -58,8 +58,8 @@ struct DrawData { uvec4 lights; }; -layout(std140) uniform GlobalVariableData { //ubo:1 - vec4 global_variables[MAX_GLOBAL_VARIABLES]; +layout(std140) uniform GlobalShaderUniformData { //ubo:1 + vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; }; layout(std140) uniform CanvasData { //ubo:0 diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl index ebf0c08ec4..88464876f1 100644 --- a/drivers/gles3/shaders/cubemap_filter.glsl +++ b/drivers/gles3/shaders/cubemap_filter.glsl @@ -29,19 +29,15 @@ uniform samplerCube source_cube; //texunit:0 /* clang-format on */ uniform int face_id; -uniform float roughness; -uniform float face_size; -uniform int sample_count; -//Todo, profile on low end hardware to see if fixed loop is faster -#ifdef USE_FIXED_SAMPLES -#define FIXED_SAMPLE_COUNT 32 +#ifndef MODE_DIRECT_WRITE +uniform int sample_count; +uniform vec4 sample_directions_mip[MAX_SAMPLE_COUNT]; +uniform float weight; #endif in highp vec2 uv_interp; -uniform sampler2D radical_inverse_vdc_cache; // texunit:1 - layout(location = 0) out vec4 frag_color; #define M_PI 3.14159265359 @@ -93,48 +89,6 @@ vec3 texelCoordToVec(vec2 uv, int faceID) { return normalize(result); } -vec3 ImportanceSampleGGX(vec2 xi, float roughness4) { - // Compute distribution direction - float Phi = 2.0 * M_PI * xi.x; - float CosTheta = sqrt((1.0 - xi.y) / (1.0 + (roughness4 - 1.0) * xi.y)); - float SinTheta = sqrt(1.0 - CosTheta * CosTheta); - - // Convert to spherical direction - vec3 H; - H.x = SinTheta * cos(Phi); - H.y = SinTheta * sin(Phi); - H.z = CosTheta; - - return H; -} - -float DistributionGGX(float NdotH, float roughness4) { - float NdotH2 = NdotH * NdotH; - float denom = (NdotH2 * (roughness4 - 1.0) + 1.0); - denom = M_PI * denom * denom; - - return roughness4 / denom; -} - -// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float GGX(float NdotV, float a) { - float k = a / 2.0; - return NdotV / (NdotV * (1.0 - k) + k); -} - -// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float G_Smith(float a, float nDotV, float nDotL) { - return GGX(nDotL, a * a) * GGX(nDotV, a * a); -} - -float radical_inverse_VdC(int i) { - return texture(radical_inverse_vdc_cache, vec2(float(i) / 512.0, 0.0)).x; -} - -vec2 Hammersley(int i, int N) { - return vec2(float(i) / float(N), radical_inverse_VdC(i)); -} - void main() { vec3 color = vec3(0.0); vec2 uv = uv_interp; @@ -145,9 +99,6 @@ void main() { #else vec4 sum = vec4(0.0); - float solid_angle_texel = 4.0 * M_PI / (6.0 * face_size * face_size); - float roughness2 = roughness * roughness; - float roughness4 = roughness2 * roughness2; vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); mat3 T; T[0] = normalize(cross(UpVector, N)); @@ -155,32 +106,15 @@ void main() { T[2] = N; for (int sample_num = 0; sample_num < sample_count; sample_num++) { - vec2 xi = Hammersley(sample_num, sample_count); - - vec3 H = T * ImportanceSampleGGX(xi, roughness4); - float NdotH = dot(N, H); - vec3 L = (2.0 * NdotH * H - N); - - float NdotL = clamp(dot(N, L), 0.0, 1.0); - - if (NdotL > 0.0) { - float D = DistributionGGX(NdotH, roughness4); - float pdf = D * NdotH / (4.0 * NdotH) + 0.0001; - - float solid_angle_sample = 1.0 / (float(sample_count) * pdf + 0.0001); - - float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(solid_angle_sample / solid_angle_texel); - - vec3 val = textureLod(source_cube, L, mipLevel).rgb; - // Mix using linear - val = srgb_to_linear(val); - - sum.rgb += val * NdotL; - sum.a += NdotL; - } + vec4 sample_direction_mip = sample_directions_mip[sample_num]; + vec3 L = T * sample_direction_mip.xyz; + vec3 val = textureLod(source_cube, L, sample_direction_mip.w).rgb; + // Mix using linear + val = srgb_to_linear(val); + sum.rgb += val * sample_direction_mip.z; } - sum /= sum.a; + sum /= weight; sum.rgb = linear_to_srgb(sum.rgb); frag_color = vec4(sum.rgb, 1.0); diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 4f2be8bf60..84daf839e9 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -104,8 +104,8 @@ layout(location = 14) in highp vec4 instance_xform2; layout(location = 15) in highp uvec4 instance_color_custom_data; // Color packed into xy, Custom data into zw. #endif -layout(std140) uniform GlobalVariableData { //ubo:1 - vec4 global_variables[MAX_GLOBAL_VARIABLES]; +layout(std140) uniform GlobalShaderUniformData { //ubo:1 + vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; }; layout(std140) uniform SceneData { // ubo:2 @@ -399,8 +399,8 @@ uniform samplerCube radiance_map; // texunit:-2 #endif -layout(std140) uniform GlobalVariableData { //ubo:1 - vec4 global_variables[MAX_GLOBAL_VARIABLES]; +layout(std140) uniform GlobalShaderUniformData { //ubo:1 + vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; }; /* Material Uniforms */ @@ -495,7 +495,7 @@ struct LightData { //this structure needs to be as packed as possible mediump float cone_attenuation; mediump float cone_angle; mediump float specular_amount; - bool shadow_enabled; + mediump float shadow_opacity; }; #ifndef DISABLE_LIGHT_OMNI layout(std140) uniform OmniLightData { // ubo:5 @@ -686,7 +686,10 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte #endif // LIGHT_ANISOTROPY_USED // F float cLdotH5 = SchlickFresnel(cLdotH); - vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0); + // Calculate Fresnel using cheap approximate specular occlusion term from Filament: + // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion + float f90 = clamp(50.0 * f0.g, 0.0, 1.0); + vec3 F = f0 + (f90 - f0) * cLdotH5; vec3 specular_brdf_NL = cNdotL * D * F * G; @@ -751,7 +754,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f if (omni_lights[idx].size > 0.0) { float t = omni_lights[idx].size / max(0.001, light_length); - size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); + size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); } light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, omni_attenuation, f0, roughness, metallic, omni_lights[idx].specular_amount, albedo, alpha, @@ -800,7 +803,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f if (spot_lights[idx].size > 0.0) { float t = spot_lights[idx].size / max(0.001, light_length); - size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); + size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); } light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, spot_attenuation, f0, roughness, metallic, spot_lights[idx].specular_amount, albedo, alpha, @@ -1049,6 +1052,7 @@ void main() { #else vec3 ref_vec = reflect(-view, normal); #endif + ref_vec = mix(ref_vec, normal, roughness * roughness); float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; specular_light = textureLod(radiance_map, ref_vec, roughness * RADIANCE_MAX_LOD).rgb; @@ -1107,7 +1111,7 @@ void main() { float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; - specular_light *= env.x * f0 + env.y; + specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, 0.0, 1.0); #endif } diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl index 50ab38bc31..eb1befe38e 100644 --- a/drivers/gles3/shaders/sky.glsl +++ b/drivers/gles3/shaders/sky.glsl @@ -42,8 +42,8 @@ uniform sampler2D half_res; //texunit:-2 uniform sampler2D quarter_res; //texunit:-3 #endif -layout(std140) uniform GlobalVariableData { //ubo:1 - vec4 global_variables[MAX_GLOBAL_VARIABLES]; +layout(std140) uniform GlobalShaderUniformData { //ubo:1 + vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; }; struct DirectionalLightData { diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index f2809734a9..30b5919526 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -64,7 +64,14 @@ Config::Config() { #else float_texture_supported = extensions.has("GL_ARB_texture_float") || extensions.has("GL_OES_texture_float"); etc2_supported = true; +#if defined(ANDROID_ENABLED) || defined(IPHONE_ENABLED) + // Some Android devices report support for S3TC but we don't expect that and don't export the textures. + // This could be fixed but so few devices support it that it doesn't seem useful (and makes bigger APKs). + // For good measure we do the same hack for iOS, just in case. + s3tc_supported = false; +#else s3tc_supported = extensions.has("GL_EXT_texture_compression_dxt1") || extensions.has("GL_EXT_texture_compression_s3tc") || extensions.has("WEBGL_compressed_texture_s3tc"); +#endif rgtc_supported = extensions.has("GL_EXT_texture_compression_rgtc") || extensions.has("GL_ARB_texture_compression_rgtc") || extensions.has("EXT_texture_compression_rgtc"); #endif diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp index 22578c9e91..2e4bfdc15b 100644 --- a/drivers/gles3/storage/light_storage.cpp +++ b/drivers/gles3/storage/light_storage.cpp @@ -70,6 +70,7 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6; light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8; light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0; + light.param[RS::LIGHT_PARAM_SHADOW_OPACITY] = 1.0; light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02; light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0; light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 91c4320acc..26441fc726 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -180,10 +180,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 2 * p_array_size; const int *r = iv.ptr(); @@ -210,10 +206,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 3 * p_array_size; const int *r = iv.ptr(); @@ -242,10 +234,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 4 * p_array_size; const int *r = iv.ptr(); @@ -298,10 +286,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 2 * p_array_size; const int *r = iv.ptr(); @@ -328,10 +312,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 3 * p_array_size; const int *r = iv.ptr(); @@ -360,10 +340,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 4 * p_array_size; const int *r = iv.ptr(); @@ -997,7 +973,7 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { //this is a global variable, get the index to it - GlobalVariables::Variable *gv = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *gv = material_storage->global_shader_uniforms.variables.getptr(E.key); uint32_t index = 0; if (gv) { index = gv->buffer_index; @@ -1053,9 +1029,9 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag if (uses_global_buffer != (global_buffer_E != nullptr)) { if (uses_global_buffer) { - global_buffer_E = material_storage->global_variables.materials_using_buffer.push_back(self); + global_buffer_E = material_storage->global_shader_uniforms.materials_using_buffer.push_back(self); } else { - material_storage->global_variables.materials_using_buffer.erase(global_buffer_E); + material_storage->global_shader_uniforms.materials_using_buffer.erase(global_buffer_E); global_buffer_E = nullptr; } } @@ -1066,20 +1042,20 @@ MaterialData::~MaterialData() { if (global_buffer_E) { //unregister global buffers - material_storage->global_variables.materials_using_buffer.erase(global_buffer_E); + material_storage->global_shader_uniforms.materials_using_buffer.erase(global_buffer_E); } if (global_texture_E) { //unregister global textures for (const KeyValue<StringName, uint64_t> &E : used_global_textures) { - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(E.key); if (v) { v->texture_materials.erase(self); } } //unregister material from those using global textures - material_storage->global_variables.materials_using_texture.erase(global_texture_E); + material_storage->global_shader_uniforms.materials_using_texture.erase(global_texture_E); } if (uniform_buffer) { @@ -1110,7 +1086,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet if (p_texture_uniforms[i].global) { uses_global_textures = true; - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(uniform_name); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(uniform_name); if (v) { if (v->buffer_index >= 0) { WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); @@ -1180,6 +1156,9 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_BLACK: { gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_BLACK); } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT: { + gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_TRANSPARENT); + } break; case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: { gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_ANISO); } break; @@ -1282,7 +1261,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet if (E.value != global_textures_pass) { to_delete.push_back(E.key); - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(E.key); if (v) { v->texture_materials.erase(self); } @@ -1296,9 +1275,9 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet //handle registering/unregistering global textures if (uses_global_textures != (global_texture_E != nullptr)) { if (uses_global_textures) { - global_texture_E = material_storage->global_variables.materials_using_texture.push_back(self); + global_texture_E = material_storage->global_shader_uniforms.materials_using_texture.push_back(self); } else { - material_storage->global_variables.materials_using_texture.erase(global_texture_E); + material_storage->global_shader_uniforms.materials_using_texture.erase(global_texture_E); global_texture_E = nullptr; } } @@ -1365,22 +1344,22 @@ MaterialStorage::MaterialStorage() { material_data_request_func[RS::SHADER_SKY] = _create_sky_material_func; material_data_request_func[RS::SHADER_FOG] = nullptr; - static_assert(sizeof(GlobalVariables::Value) == 16); + static_assert(sizeof(GlobalShaderUniforms::Value) == 16); - global_variables.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); - if (global_variables.buffer_size > uint32_t(Config::get_singleton()->max_uniform_buffer_size)) { - global_variables.buffer_size = uint32_t(Config::get_singleton()->max_uniform_buffer_size); + global_shader_uniforms.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); + if (global_shader_uniforms.buffer_size > uint32_t(Config::get_singleton()->max_uniform_buffer_size)) { + global_shader_uniforms.buffer_size = uint32_t(Config::get_singleton()->max_uniform_buffer_size); WARN_PRINT("Project setting: rendering/limits/global_shader_variables/buffer_size exceeds maximum uniform buffer size of: " + itos(Config::get_singleton()->max_uniform_buffer_size)); } - global_variables.buffer_values = memnew_arr(GlobalVariables::Value, global_variables.buffer_size); - memset(global_variables.buffer_values, 0, sizeof(GlobalVariables::Value) * global_variables.buffer_size); - global_variables.buffer_usage = memnew_arr(GlobalVariables::ValueUsage, global_variables.buffer_size); - global_variables.buffer_dirty_regions = memnew_arr(bool, global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); - memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); - glGenBuffers(1, &global_variables.buffer); - glBindBuffer(GL_UNIFORM_BUFFER, global_variables.buffer); - glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalVariables::Value) * global_variables.buffer_size, nullptr, GL_DYNAMIC_DRAW); + global_shader_uniforms.buffer_values = memnew_arr(GlobalShaderUniforms::Value, global_shader_uniforms.buffer_size); + memset(global_shader_uniforms.buffer_values, 0, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size); + global_shader_uniforms.buffer_usage = memnew_arr(GlobalShaderUniforms::ValueUsage, global_shader_uniforms.buffer_size); + global_shader_uniforms.buffer_dirty_regions = memnew_arr(bool, global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE); + memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE); + glGenBuffers(1, &global_shader_uniforms.buffer); + glBindBuffer(GL_UNIFORM_BUFFER, global_shader_uniforms.buffer); + glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size, nullptr, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); { @@ -1518,7 +1497,7 @@ MaterialStorage::MaterialStorage() { actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; actions.renames["DEPTH"] = "gl_FragDepth"; actions.renames["OUTPUT_IS_SRGB"] = "true"; - actions.renames["FOG"] = "custom_fog"; + actions.renames["FOG"] = "fog"; actions.renames["RADIANCE"] = "custom_radiance"; actions.renames["IRRADIANCE"] = "custom_irradiance"; actions.renames["BONE_INDICES"] = "bone_attrib"; @@ -1529,6 +1508,11 @@ MaterialStorage::MaterialStorage() { actions.renames["CUSTOM3"] = "custom3_attrib"; actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; + actions.renames["NODE_POSITION_WORLD"] = "model_matrix[3].xyz"; + actions.renames["CAMERA_POSITION_WORLD"] = "scene_data.inv_view_matrix[3].xyz"; + actions.renames["CAMERA_DIRECTION_WORLD"] = "scene_data.view_matrix[3].xyz"; + actions.renames["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz"; + actions.renames["VIEW_INDEX"] = "ViewIndex"; actions.renames["VIEW_MONO_LEFT"] = "0"; actions.renames["VIEW_RIGHT"] = "1"; @@ -1674,7 +1658,7 @@ ShaderCompiler::DefaultIdentifierActions actions; actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; particles_shader.compiler.initialize(actions); */ @@ -1736,25 +1720,25 @@ ShaderCompiler::DefaultIdentifierActions actions; MaterialStorage::~MaterialStorage() { //shaders.copy.version_free(shaders.copy_version); - memdelete_arr(global_variables.buffer_values); - memdelete_arr(global_variables.buffer_usage); - memdelete_arr(global_variables.buffer_dirty_regions); - glDeleteBuffers(1, &global_variables.buffer); + memdelete_arr(global_shader_uniforms.buffer_values); + memdelete_arr(global_shader_uniforms.buffer_usage); + memdelete_arr(global_shader_uniforms.buffer_dirty_regions); + glDeleteBuffers(1, &global_shader_uniforms.buffer); singleton = nullptr; } -/* GLOBAL VARIABLE API */ +/* GLOBAL SHADER UNIFORM API */ -int32_t MaterialStorage::_global_variable_allocate(uint32_t p_elements) { +int32_t MaterialStorage::_global_shader_uniform_allocate(uint32_t p_elements) { int32_t idx = 0; - while (idx + p_elements <= global_variables.buffer_size) { - if (global_variables.buffer_usage[idx].elements == 0) { + while (idx + p_elements <= global_shader_uniforms.buffer_size) { + if (global_shader_uniforms.buffer_usage[idx].elements == 0) { bool valid = true; for (uint32_t i = 1; i < p_elements; i++) { - if (global_variables.buffer_usage[idx + i].elements > 0) { + if (global_shader_uniforms.buffer_usage[idx + i].elements > 0) { valid = false; - idx += i + global_variables.buffer_usage[idx + i].elements; + idx += i + global_shader_uniforms.buffer_usage[idx + i].elements; break; } } @@ -1765,17 +1749,17 @@ int32_t MaterialStorage::_global_variable_allocate(uint32_t p_elements) { return idx; } else { - idx += global_variables.buffer_usage[idx].elements; + idx += global_shader_uniforms.buffer_usage[idx].elements; } } return -1; } -void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) { +void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; bool b = p_value; bv.x = b ? 1.0 : 0.0; bv.y = 0.0; @@ -1784,7 +1768,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_BVEC2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1792,7 +1776,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0.0; } break; case RS::GLOBAL_VAR_TYPE_BVEC3: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1800,7 +1784,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0.0; } break; case RS::GLOBAL_VAR_TYPE_BVEC4: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1808,7 +1792,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = (bvec & 8) ? 1.0 : 0.0; } break; case RS::GLOBAL_VAR_TYPE_INT: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; int32_t v = p_value; bv.x = v; bv.y = 0; @@ -1816,7 +1800,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC2: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector2i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1824,7 +1808,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC3: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector3i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1832,7 +1816,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC4: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector<int32_t> v = p_value; bv.x = v.size() >= 1 ? v[0] : 0; bv.y = v.size() >= 2 ? v[1] : 0; @@ -1840,7 +1824,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size() >= 4 ? v[3] : 0; } break; case RS::GLOBAL_VAR_TYPE_RECT2I: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Rect2i v = p_value; bv.x = v.position.x; bv.y = v.position.y; @@ -1848,7 +1832,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size.y; } break; case RS::GLOBAL_VAR_TYPE_UINT: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; uint32_t v = p_value; bv.x = v; bv.y = 0; @@ -1856,7 +1840,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC2: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector2i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1864,7 +1848,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC3: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector3i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1872,7 +1856,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC4: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector<int32_t> v = p_value; bv.x = v.size() >= 1 ? v[0] : 0; bv.y = v.size() >= 2 ? v[1] : 0; @@ -1880,7 +1864,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size() >= 4 ? v[3] : 0; } break; case RS::GLOBAL_VAR_TYPE_FLOAT: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; float v = p_value; bv.x = v; bv.y = 0; @@ -1888,7 +1872,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Vector2 v = p_value; bv.x = v.x; bv.y = v.y; @@ -1896,7 +1880,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC3: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Vector3 v = p_value; bv.x = v.x; bv.y = v.y; @@ -1904,7 +1888,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC4: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Plane v = p_value; bv.x = v.normal.x; bv.y = v.normal.y; @@ -1912,14 +1896,14 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.d; } break; case RS::GLOBAL_VAR_TYPE_COLOR: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Color v = p_value; bv.x = v.r; bv.y = v.g; bv.z = v.b; bv.w = v.a; - GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1]; + GlobalShaderUniforms::Value &bv_linear = global_shader_uniforms.buffer_values[p_index + 1]; //v = v.srgb_to_linear(); bv_linear.x = v.r; bv_linear.y = v.g; @@ -1928,7 +1912,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_RECT2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Rect2 v = p_value; bv.x = v.position.x; bv.y = v.position.y; @@ -1936,7 +1920,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size.y; } break; case RS::GLOBAL_VAR_TYPE_MAT2: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Vector<float> m2 = p_value; if (m2.size() < 4) { m2.resize(4); @@ -1953,7 +1937,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_MAT3: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Basis v = p_value; bv[0].x = v.rows[0][0]; bv[0].y = v.rows[1][0]; @@ -1972,7 +1956,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_MAT4: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Vector<float> m2 = p_value; if (m2.size() < 16) { @@ -2001,7 +1985,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Transform2D v = p_value; bv[0].x = v.columns[0][0]; bv[0].y = v.columns[0][1]; @@ -2020,7 +2004,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Transform3D v = p_value; bv[0].x = v.basis.rows[0][0]; bv[0].y = v.basis.rows[1][0]; @@ -2049,15 +2033,15 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } } -void MaterialStorage::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { +void MaterialStorage::_global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { int32_t prev_chunk = -1; for (int32_t i = 0; i < p_elements; i++) { - int32_t chunk = (p_index + i) / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; + int32_t chunk = (p_index + i) / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; if (chunk != prev_chunk) { - if (!global_variables.buffer_dirty_regions[chunk]) { - global_variables.buffer_dirty_regions[chunk] = true; - global_variables.buffer_dirty_region_count++; + if (!global_shader_uniforms.buffer_dirty_regions[chunk]) { + global_shader_uniforms.buffer_dirty_regions[chunk] = true; + global_shader_uniforms.buffer_dirty_region_count++; } } @@ -2065,16 +2049,16 @@ void MaterialStorage::_global_variable_mark_buffer_dirty(int32_t p_index, int32_ } } -void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { - ERR_FAIL_COND(global_variables.variables.has(p_name)); - GlobalVariables::Variable gv; +void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) { + ERR_FAIL_COND(global_shader_uniforms.variables.has(p_name)); + GlobalShaderUniforms::Variable gv; gv.type = p_type; gv.value = p_value; gv.buffer_index = -1; if (p_type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { //is texture - global_variables.must_update_texture_materials = true; //normally there are none + global_shader_uniforms.must_update_texture_materials = true; //normally there are none } else { gv.buffer_elements = 1; if (p_type == RS::GLOBAL_VAR_TYPE_COLOR || p_type == RS::GLOBAL_VAR_TYPE_MAT2) { @@ -2091,56 +2075,56 @@ void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVa } //is vector, allocate in buffer and update index - gv.buffer_index = _global_variable_allocate(gv.buffer_elements); + gv.buffer_index = _global_shader_uniform_allocate(gv.buffer_elements); ERR_FAIL_COND_MSG(gv.buffer_index < 0, vformat("Failed allocating global variable '%s' out of buffer memory. Consider increasing it in the Project Settings.", String(p_name))); - global_variables.buffer_usage[gv.buffer_index].elements = gv.buffer_elements; - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + global_shader_uniforms.buffer_usage[gv.buffer_index].elements = gv.buffer_elements; + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); - global_variables.must_update_buffer_materials = true; //normally there are none + global_shader_uniforms.must_update_buffer_materials = true; //normally there are none } - global_variables.variables[p_name] = gv; + global_shader_uniforms.variables[p_name] = gv; } -void MaterialStorage::global_variable_remove(const StringName &p_name) { - if (!global_variables.variables.has(p_name)) { +void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) { + if (!global_shader_uniforms.variables.has(p_name)) { return; } - GlobalVariables::Variable &gv = global_variables.variables[p_name]; + GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; if (gv.buffer_index >= 0) { - global_variables.buffer_usage[gv.buffer_index].elements = 0; - global_variables.must_update_buffer_materials = true; + global_shader_uniforms.buffer_usage[gv.buffer_index].elements = 0; + global_shader_uniforms.must_update_buffer_materials = true; } else { - global_variables.must_update_texture_materials = true; + global_shader_uniforms.must_update_texture_materials = true; } - global_variables.variables.erase(p_name); + global_shader_uniforms.variables.erase(p_name); } -Vector<StringName> MaterialStorage::global_variable_get_list() const { +Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } Vector<StringName> names; - for (const KeyValue<StringName, GlobalVariables::Variable> &E : global_variables.variables) { + for (const KeyValue<StringName, GlobalShaderUniforms::Variable> &E : global_shader_uniforms.variables) { names.push_back(E.key); } names.sort_custom<StringName::AlphCompare>(); return names; } -void MaterialStorage::global_variable_set(const StringName &p_name, const Variant &p_value) { - ERR_FAIL_COND(!global_variables.variables.has(p_name)); - GlobalVariables::Variable &gv = global_variables.variables[p_name]; +void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const Variant &p_value) { + ERR_FAIL_COND(!global_shader_uniforms.variables.has(p_name)); + GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.value = p_value; if (gv.override.get_type() == Variant::NIL) { if (gv.buffer_index >= 0) { //buffer - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); } else { //texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -2153,26 +2137,26 @@ void MaterialStorage::global_variable_set(const StringName &p_name, const Varian } } -void MaterialStorage::global_variable_set_override(const StringName &p_name, const Variant &p_value) { - if (!global_variables.variables.has(p_name)) { +void MaterialStorage::global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) { + if (!global_shader_uniforms.variables.has(p_name)) { return; //variable may not exist } ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT); - GlobalVariables::Variable &gv = global_variables.variables[p_name]; + GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.override = p_value; if (gv.buffer_index >= 0) { //buffer if (gv.override.get_type() == Variant::NIL) { - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); } else { - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.override); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.override); } - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); } else { //texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -2184,35 +2168,35 @@ void MaterialStorage::global_variable_set_override(const StringName &p_name, con } } -Variant MaterialStorage::global_variable_get(const StringName &p_name) const { +Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); } - if (!global_variables.variables.has(p_name)) { + if (!global_shader_uniforms.variables.has(p_name)) { return Variant(); } - return global_variables.variables[p_name].value; + return global_shader_uniforms.variables[p_name].value; } -RS::GlobalVariableType MaterialStorage::global_variable_get_type_internal(const StringName &p_name) const { - if (!global_variables.variables.has(p_name)) { +RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_internal(const StringName &p_name) const { + if (!global_shader_uniforms.variables.has(p_name)) { return RS::GLOBAL_VAR_TYPE_MAX; } - return global_variables.variables[p_name].type; + return global_shader_uniforms.variables[p_name].type; } -RS::GlobalVariableType MaterialStorage::global_variable_get_type(const StringName &p_name) const { +RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance."); } - return global_variable_get_type_internal(p_name); + return global_shader_uniform_get_type_internal(p_name); } -void MaterialStorage::global_variables_load_settings(bool p_load_textures) { +void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) { List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); @@ -2257,11 +2241,11 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) { "samplerCube", }; - RS::GlobalVariableType gvtype = RS::GLOBAL_VAR_TYPE_MAX; + RS::GlobalShaderUniformType gvtype = RS::GLOBAL_VAR_TYPE_MAX; for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { if (global_var_type_names[i] == type) { - gvtype = RS::GlobalVariableType(i); + gvtype = RS::GlobalShaderUniformType(i); break; } } @@ -2283,47 +2267,47 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) { value = resource; } - if (global_variables.variables.has(name)) { + if (global_shader_uniforms.variables.has(name)) { //has it, update it - global_variable_set(name, value); + global_shader_uniform_set(name, value); } else { - global_variable_add(name, gvtype, value); + global_shader_uniform_add(name, gvtype, value); } } } } -void MaterialStorage::global_variables_clear() { - global_variables.variables.clear(); +void MaterialStorage::global_shader_uniforms_clear() { + global_shader_uniforms.variables.clear(); } -GLuint MaterialStorage::global_variables_get_uniform_buffer() const { - return global_variables.buffer; +GLuint MaterialStorage::global_shader_uniforms_get_uniform_buffer() const { + return global_shader_uniforms.buffer; } -int32_t MaterialStorage::global_variables_instance_allocate(RID p_instance) { - ERR_FAIL_COND_V(global_variables.instance_buffer_pos.has(p_instance), -1); - int32_t pos = _global_variable_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); - global_variables.instance_buffer_pos[p_instance] = pos; //save anyway +int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance) { + ERR_FAIL_COND_V(global_shader_uniforms.instance_buffer_pos.has(p_instance), -1); + int32_t pos = _global_shader_uniform_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); + global_shader_uniforms.instance_buffer_pos[p_instance] = pos; //save anyway ERR_FAIL_COND_V_MSG(pos < 0, -1, "Too many instances using shader instance variables. Increase buffer size in Project Settings."); - global_variables.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES; + global_shader_uniforms.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES; return pos; } -void MaterialStorage::global_variables_instance_free(RID p_instance) { - ERR_FAIL_COND(!global_variables.instance_buffer_pos.has(p_instance)); - int32_t pos = global_variables.instance_buffer_pos[p_instance]; +void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) { + ERR_FAIL_COND(!global_shader_uniforms.instance_buffer_pos.has(p_instance)); + int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos >= 0) { - global_variables.buffer_usage[pos].elements = 0; + global_shader_uniforms.buffer_usage[pos].elements = 0; } - global_variables.instance_buffer_pos.erase(p_instance); + global_shader_uniforms.instance_buffer_pos.erase(p_instance); } -void MaterialStorage::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { - if (!global_variables.instance_buffer_pos.has(p_instance)) { +void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) { + if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } - int32_t pos = global_variables.instance_buffer_pos[p_instance]; + int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos < 0) { return; //again, not allocated, ignore @@ -2344,11 +2328,14 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind ShaderLanguage::TYPE_VEC3, // vec3 ShaderLanguage::TYPE_IVEC3, //vec3i ShaderLanguage::TYPE_MAX, //xform2d not supported here + ShaderLanguage::TYPE_VEC4, //vec4 + ShaderLanguage::TYPE_IVEC4, //vec4i ShaderLanguage::TYPE_VEC4, //plane ShaderLanguage::TYPE_VEC4, //quat ShaderLanguage::TYPE_MAX, //aabb not supported here ShaderLanguage::TYPE_MAX, //basis not supported here ShaderLanguage::TYPE_MAX, //xform not supported here + ShaderLanguage::TYPE_MAX, //projection not supported here ShaderLanguage::TYPE_VEC4 //color }; @@ -2358,59 +2345,59 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind pos += p_index; - _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos]); - _global_variable_mark_buffer_dirty(pos, 1); + _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_shader_uniforms.buffer_values[pos]); + _global_shader_uniform_mark_buffer_dirty(pos, 1); } -void MaterialStorage::_update_global_variables() { +void MaterialStorage::_update_global_shader_uniforms() { MaterialStorage *material_storage = MaterialStorage::get_singleton(); - if (global_variables.buffer_dirty_region_count > 0) { - uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; - if (total_regions / global_variables.buffer_dirty_region_count <= 4) { + if (global_shader_uniforms.buffer_dirty_region_count > 0) { + uint32_t total_regions = global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; + if (total_regions / global_shader_uniforms.buffer_dirty_region_count <= 4) { // 25% of regions dirty, just update all buffer - glBindBuffer(GL_UNIFORM_BUFFER, global_variables.buffer); - glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalVariables::Value) * global_variables.buffer_size, global_variables.buffer_values, GL_DYNAMIC_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, global_shader_uniforms.buffer); + glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size, global_shader_uniforms.buffer_values, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); - memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * total_regions); + memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * total_regions); } else { - uint32_t region_byte_size = sizeof(GlobalVariables::Value) * GlobalVariables::BUFFER_DIRTY_REGION_SIZE; - glBindBuffer(GL_UNIFORM_BUFFER, global_variables.buffer); + uint32_t region_byte_size = sizeof(GlobalShaderUniforms::Value) * GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; + glBindBuffer(GL_UNIFORM_BUFFER, global_shader_uniforms.buffer); for (uint32_t i = 0; i < total_regions; i++) { - if (global_variables.buffer_dirty_regions[i]) { - glBufferSubData(GL_UNIFORM_BUFFER, i * region_byte_size, region_byte_size, &global_variables.buffer_values[i * GlobalVariables::BUFFER_DIRTY_REGION_SIZE]); - global_variables.buffer_dirty_regions[i] = false; + if (global_shader_uniforms.buffer_dirty_regions[i]) { + glBufferSubData(GL_UNIFORM_BUFFER, i * region_byte_size, region_byte_size, &global_shader_uniforms.buffer_values[i * GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE]); + global_shader_uniforms.buffer_dirty_regions[i] = false; } } glBindBuffer(GL_UNIFORM_BUFFER, 0); } - global_variables.buffer_dirty_region_count = 0; + global_shader_uniforms.buffer_dirty_region_count = 0; } - if (global_variables.must_update_buffer_materials) { + if (global_shader_uniforms.must_update_buffer_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (const RID &E : global_variables.materials_using_buffer) { + for (const RID &E : global_shader_uniforms.materials_using_buffer) { Material *material = material_storage->get_material(E); ERR_CONTINUE(!material); //wtf material_storage->_material_queue_update(material, true, false); } - global_variables.must_update_buffer_materials = false; + global_shader_uniforms.must_update_buffer_materials = false; } - if (global_variables.must_update_texture_materials) { + if (global_shader_uniforms.must_update_texture_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (const RID &E : global_variables.materials_using_texture) { + for (const RID &E : global_shader_uniforms.materials_using_texture) { Material *material = material_storage->get_material(E); ERR_CONTINUE(!material); //wtf material_storage->_material_queue_update(material, false, true); } - global_variables.must_update_texture_materials = false; + global_shader_uniforms.must_update_texture_materials = false; } } @@ -2535,11 +2522,11 @@ String MaterialStorage::shader_get_code(RID p_shader) const { return shader->code; } -void MaterialStorage::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { +void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const { GLES3::Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); if (shader->data) { - return shader->data->get_param_list(p_param_list); + return shader->data->get_shader_uniform_list(p_param_list); } } @@ -2771,14 +2758,14 @@ bool MaterialStorage::material_casts_shadows(RID p_material) { return true; //by default everything casts shadows } -void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { +void MaterialStorage::material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) { GLES3::Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); if (material->shader && material->shader->data) { material->shader->data->get_instance_param_list(r_parameters); if (material->next_pass.is_valid()) { - material_get_instance_shader_parameters(material->next_pass, r_parameters); + material_get_instance_shader_uniforms(material->next_pass, r_parameters); } } } @@ -2886,7 +2873,7 @@ void CanvasShaderData::set_default_texture_param(const StringName &p_name, RID p } } -void CanvasShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void CanvasShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { @@ -3123,7 +3110,7 @@ void SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_te } } -void SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void SkyShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { RBMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { @@ -3448,7 +3435,7 @@ void SceneShaderData::set_default_texture_param(const StringName &p_name, RID p_ } } -void SceneShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void SceneShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { RBMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h index 91e1eee306..2ca47351a4 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -54,7 +54,7 @@ namespace GLES3 { struct ShaderData { virtual void set_code(const String &p_Code) = 0; virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) = 0; - virtual void get_param_list(List<PropertyInfo> *p_param_list) const = 0; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const = 0; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0; virtual bool is_param_texture(const StringName &p_param) const = 0; @@ -164,7 +164,7 @@ struct CanvasShaderData : public ShaderData { virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; @@ -215,7 +215,7 @@ struct SkyShaderData : public ShaderData { virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; @@ -335,7 +335,7 @@ struct SceneShaderData : public ShaderData { virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; @@ -365,15 +365,15 @@ struct SceneMaterialData : public MaterialData { MaterialData *_create_scene_material_func(ShaderData *p_shader); -/* Global variable structs */ -struct GlobalVariables { +/* Global shader uniform structs */ +struct GlobalShaderUniforms { enum { BUFFER_DIRTY_REGION_SIZE = 1024 }; struct Variable { HashSet<RID> texture_materials; // materials using this - RS::GlobalVariableType type; + RS::GlobalShaderUniformType type; Variant value; Variant override; int32_t buffer_index; //for vectors @@ -429,13 +429,13 @@ private: friend struct MaterialData; static MaterialStorage *singleton; - /* GLOBAL VARIABLE API */ + /* GLOBAL SHADER UNIFORM API */ - GlobalVariables global_variables; + GlobalShaderUniforms global_shader_uniforms; - int32_t _global_variable_allocate(uint32_t p_elements); - void _global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value); - void _global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements); + int32_t _global_shader_uniform_allocate(uint32_t p_elements); + void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value); + void _global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements); /* SHADER API */ @@ -508,28 +508,28 @@ public: ShaderCompiler compiler_sky; } shaders; - /* GLOBAL VARIABLE API */ + /* GLOBAL SHADER UNIFORM API */ - void _update_global_variables(); + void _update_global_shader_uniforms(); - virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override; - virtual void global_variable_remove(const StringName &p_name) override; - virtual Vector<StringName> global_variable_get_list() const override; + virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override; + virtual void global_shader_uniform_remove(const StringName &p_name) override; + virtual Vector<StringName> global_shader_uniform_get_list() const override; - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) override; - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) override; - virtual Variant global_variable_get(const StringName &p_name) const override; - virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override; - RS::GlobalVariableType global_variable_get_type_internal(const StringName &p_name) const; + virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override; + virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override; + virtual Variant global_shader_uniform_get(const StringName &p_name) const override; + virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override; + RS::GlobalShaderUniformType global_shader_uniform_get_type_internal(const StringName &p_name) const; - virtual void global_variables_load_settings(bool p_load_textures = true) override; - virtual void global_variables_clear() override; + virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override; + virtual void global_shader_uniforms_clear() override; - virtual int32_t global_variables_instance_allocate(RID p_instance) override; - virtual void global_variables_instance_free(RID p_instance) override; - virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override; + virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override; + virtual void global_shader_uniforms_instance_free(RID p_instance) override; + virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override; - GLuint global_variables_get_uniform_buffer() const; + GLuint global_shader_uniforms_get_uniform_buffer() const; /* SHADER API */ @@ -545,7 +545,7 @@ public: virtual void shader_set_code(RID p_shader, const String &p_code) override; virtual void shader_set_path_hint(RID p_shader, const String &p_path) override; virtual String shader_get_code(RID p_shader) const override; - virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; + virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override; virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override; @@ -576,7 +576,7 @@ public: virtual bool material_is_animated(RID p_material) override; virtual bool material_casts_shadows(RID p_material) override; - virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override; + virtual void material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) override; virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override; diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index 88b81805fa..667ba4f5e6 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -1347,7 +1347,7 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b _multimesh_mark_all_dirty(multimesh, false, true); //update AABB } else if (multimesh->mesh.is_valid()) { //if we have a mesh set, we need to re-generate the AABB from the new data - const float *data = multimesh->data_cache.ptr(); + const float *data = p_buffer.ptr(); _multimesh_re_create_aabb(multimesh, data, multimesh->instances); multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index c05f516548..543638e8ff 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -115,6 +115,17 @@ TextureStorage::TextureStorage() { texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK], images, RS::TEXTURE_LAYERED_CUBEMAP); } + { // transparent black + Ref<Image> image; + image.instantiate(); + image->create(4, 4, true, Image::FORMAT_RGBA8); + image->fill(Color(0, 0, 0, 0)); + image->generate_mipmaps(); + + default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT] = texture_allocate(); + texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT], image); + } + { Ref<Image> image; image.instantiate(); diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 77ec1da6f5..71f713bc9f 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -103,6 +103,7 @@ namespace GLES3 { enum DefaultGLTexture { DEFAULT_GL_TEXTURE_WHITE, DEFAULT_GL_TEXTURE_BLACK, + DEFAULT_GL_TEXTURE_TRANSPARENT, DEFAULT_GL_TEXTURE_NORMAL, DEFAULT_GL_TEXTURE_ANISO, DEFAULT_GL_TEXTURE_DEPTH, diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp index a00210a2ab..654104722b 100644 --- a/drivers/gles3/storage/utilities.cpp +++ b/drivers/gles3/storage/utilities.cpp @@ -293,7 +293,7 @@ void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_de /* MISC */ void Utilities::update_dirty_resources() { - MaterialStorage::get_singleton()->_update_global_variables(); + MaterialStorage::get_singleton()->_update_global_shader_uniforms(); MaterialStorage::get_singleton()->_update_queued_materials(); //MeshStorage::get_singleton()->_update_dirty_skeletons(); MeshStorage::get_singleton()->_update_dirty_multimeshes(); diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp index 704ddca726..275f3240d7 100644 --- a/drivers/png/resource_saver_png.cpp +++ b/drivers/png/resource_saver_png.cpp @@ -35,7 +35,7 @@ #include "drivers/png/png_driver_common.h" #include "scene/resources/texture.h" -Error ResourceSaverPNG::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceSaverPNG::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { Ref<ImageTexture> texture = p_resource; ERR_FAIL_COND_V_MSG(!texture.is_valid(), ERR_INVALID_PARAMETER, "Can't save invalid texture as PNG."); diff --git a/drivers/png/resource_saver_png.h b/drivers/png/resource_saver_png.h index 1a681faaec..260a643a1b 100644 --- a/drivers/png/resource_saver_png.h +++ b/drivers/png/resource_saver_png.h @@ -39,7 +39,7 @@ public: static Error save_image(const String &p_path, const Ref<Image> &p_img); static Vector<uint8_t> save_image_to_buffer(const Ref<Image> &p_img); - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual bool recognize(const Ref<Resource> &p_resource) const; virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h index 18f435f942..f5dca7c282 100644 --- a/drivers/unix/dir_access_unix.h +++ b/drivers/unix/dir_access_unix.h @@ -52,39 +52,39 @@ protected: virtual bool is_hidden(const String &p_name); public: - virtual Error list_dir_begin(); ///< This starts dir listing - virtual String get_next(); - virtual bool current_is_dir() const; - virtual bool current_is_hidden() const; + virtual Error list_dir_begin() override; ///< This starts dir listing + virtual String get_next() override; + virtual bool current_is_dir() const override; + virtual bool current_is_hidden() const override; - virtual void list_dir_end(); ///< + virtual void list_dir_end() override; ///< - virtual int get_drive_count(); - virtual String get_drive(int p_drive); - virtual int get_current_drive(); - virtual bool drives_are_shortcuts(); + virtual int get_drive_count() override; + virtual String get_drive(int p_drive) override; + virtual int get_current_drive() override; + virtual bool drives_are_shortcuts() override; - virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success - virtual String get_current_dir(bool p_include_drive = true) const; ///< return current dir location - virtual Error make_dir(String p_dir); + virtual Error change_dir(String p_dir) override; ///< can be relative or absolute, return false on success + virtual String get_current_dir(bool p_include_drive = true) const override; ///< return current dir location + virtual Error make_dir(String p_dir) override; - virtual bool file_exists(String p_file); - virtual bool dir_exists(String p_dir); - virtual bool is_readable(String p_dir); - virtual bool is_writable(String p_dir); + virtual bool file_exists(String p_file) override; + virtual bool dir_exists(String p_dir) override; + virtual bool is_readable(String p_dir) override; + virtual bool is_writable(String p_dir) override; virtual uint64_t get_modified_time(String p_file); - virtual Error rename(String p_path, String p_new_path); - virtual Error remove(String p_path); + virtual Error rename(String p_path, String p_new_path) override; + virtual Error remove(String p_path) override; - virtual bool is_link(String p_file); - virtual String read_link(String p_file); - virtual Error create_link(String p_source, String p_target); + virtual bool is_link(String p_file) override; + virtual String read_link(String p_file) override; + virtual Error create_link(String p_source, String p_target) override; - virtual uint64_t get_space_left(); + virtual uint64_t get_space_left() override; - virtual String get_filesystem_type() const; + virtual String get_filesystem_type() const override; DirAccessUnix(); ~DirAccessUnix(); diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index d61fc08f57..297c34e454 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -54,33 +54,33 @@ class FileAccessUnix : public FileAccess { public: static CloseNotificationFunc close_notification_func; - virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file - virtual bool is_open() const; ///< true when file is open + virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file + virtual bool is_open() const override; ///< true when file is open - virtual String get_path() const; /// returns the path for the current open file - virtual String get_path_absolute() const; /// returns the absolute path for the current open file + virtual String get_path() const override; /// returns the path for the current open file + virtual String get_path_absolute() const override; /// returns the absolute path for the current open file - virtual void seek(uint64_t p_position); ///< seek to a given position - virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_length() const; ///< get size of the file + virtual void seek(uint64_t p_position) override; ///< seek to a given position + virtual void seek_end(int64_t p_position = 0) override; ///< seek from the end of file + virtual uint64_t get_position() const override; ///< get position in the file + virtual uint64_t get_length() const override; ///< get size of the file - virtual bool eof_reached() const; ///< reading passed EOF + virtual bool eof_reached() const override; ///< reading passed EOF - virtual uint8_t get_8() const; ///< get a byte - virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; + virtual uint8_t get_8() const override; ///< get a byte + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override; - virtual Error get_error() const; ///< get last error + virtual Error get_error() const override; ///< get last error - virtual void flush(); - virtual void store_8(uint8_t p_dest); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes + virtual void flush() override; + virtual void store_8(uint8_t p_dest) override; ///< store a byte + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes - virtual bool file_exists(const String &p_path); ///< return true if a file exists + virtual bool file_exists(const String &p_path) override; ///< return true if a file exists - virtual uint64_t _get_modified_time(const String &p_file); - virtual uint32_t _get_unix_permissions(const String &p_file); - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions); + virtual uint64_t _get_modified_time(const String &p_file) override; + virtual uint32_t _get_unix_permissions(const String &p_file) override; + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override; FileAccessUnix() {} virtual ~FileAccessUnix(); diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index 2deeb79957..0dc2efedc1 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -95,12 +95,12 @@ void IPUnix::_resolve_hostname(List<IPAddress> &r_addresses, const String &p_hos int s = getaddrinfo(p_hostname.utf8().get_data(), nullptr, &hints, &result); if (s != 0) { - ERR_PRINT("getaddrinfo failed! Cannot resolve hostname."); + print_verbose("getaddrinfo failed! Cannot resolve hostname."); return; } if (result == nullptr || result->ai_addr == nullptr) { - ERR_PRINT("Invalid response from getaddrinfo"); + print_verbose("Invalid response from getaddrinfo"); if (result) { freeaddrinfo(result); } diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 9abd4780eb..89daa2af64 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1834,6 +1834,11 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T if (p_format.usage_bits & TEXTURE_USAGE_STORAGE_ATOMIC_BIT && !(flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)) { ERR_FAIL_V_MSG(RID(), "Format " + format_text + " does not support usage as atomic storage image."); } + + // Validation via VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR fails if VRS attachment is not supported. + if (p_format.usage_bits & TEXTURE_USAGE_VRS_ATTACHMENT_BIT && p_format.format != DATA_FORMAT_R8_UINT) { + ERR_FAIL_V_MSG(RID(), "Format " + format_text + " does not support usage as VRS attachment."); + } } //some view validation @@ -1999,6 +2004,9 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T } RID id = texture_owner.make_rid(texture); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif if (p_data.size()) { for (uint32_t i = 0; i < image_create_info.arrayLayers; i++) { @@ -2128,6 +2136,9 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID texture.owner = p_with_texture; RID id = texture_owner.make_rid(texture); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif _add_dependency(id, p_with_texture); return id; @@ -2247,6 +2258,9 @@ RID RenderingDeviceVulkan::texture_create_from_extension(TextureType p_type, Dat } RID id = texture_owner.make_rid(texture); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif return id; } @@ -2372,6 +2386,9 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p texture.owner = p_with_texture; RID id = texture_owner.make_rid(texture); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif _add_dependency(id, p_with_texture); return id; @@ -3354,6 +3371,11 @@ bool RenderingDeviceVulkan::texture_is_format_supported_for_usage(DataFormat p_f return false; } + // Validation via VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR fails if VRS attachment is not supported. + if (p_usage & TEXTURE_USAGE_VRS_ATTACHMENT_BIT && p_format != DATA_FORMAT_R8_UINT) { + return false; + } + return true; } @@ -3807,7 +3829,12 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF subpass.pNext = subpass_nextptr; subpass.flags = 0; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.viewMask = view_mask; + if (p_view_count == 1) { + // VUID-VkSubpassDescription2-multiview-06558: If the multiview feature is not enabled, viewMask must be 0. + subpass.viewMask = 0; + } else { + subpass.viewMask = view_mask; + } subpass.inputAttachmentCount = input_references.size(); if (input_references.size()) { subpass.pInputAttachments = input_references.ptr(); @@ -3895,8 +3922,14 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF render_pass_create_info.pDependencies = nullptr; } - render_pass_create_info.correlatedViewMaskCount = 1; - render_pass_create_info.pCorrelatedViewMasks = &correlation_mask; + if (p_view_count == 1) { + // VUID-VkRenderPassCreateInfo2-viewMask-03057: If the VkSubpassDescription2::viewMask member of all elements of pSubpasses is 0, correlatedViewMaskCount must be 0. + render_pass_create_info.correlatedViewMaskCount = 0; + render_pass_create_info.pCorrelatedViewMasks = nullptr; + } else { + render_pass_create_info.correlatedViewMaskCount = 1; + render_pass_create_info.pCorrelatedViewMasks = &correlation_mask; + } Vector<uint32_t> view_masks; VkRenderPassMultiviewCreateInfo render_pass_multiview_create_info; @@ -3950,7 +3983,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c passes.push_back(pass); return framebuffer_format_create_multipass(p_format, passes, p_view_count); } -RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, Vector<FramebufferPass> &p_passes, uint32_t p_view_count) { +RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, uint32_t p_view_count) { _THREAD_SAFE_METHOD_ FramebufferFormatKey key; @@ -3997,6 +4030,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c subpass.pNext = nullptr; subpass.flags = 0; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.viewMask = 0; subpass.inputAttachmentCount = 0; //unsupported for now subpass.pInputAttachments = nullptr; subpass.colorAttachmentCount = 0; @@ -4060,7 +4094,11 @@ RID RenderingDeviceVulkan::framebuffer_create_empty(const Size2i &p_size, Textur framebuffer.size = p_size; framebuffer.view_count = 1; - return framebuffer_owner.make_rid(framebuffer); + RID id = framebuffer_owner.make_rid(framebuffer); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif + return id; } RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check, uint32_t p_view_count) { @@ -4088,7 +4126,7 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac return framebuffer_create_multipass(p_texture_attachments, passes, p_format_check, p_view_count); } -RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check, uint32_t p_view_count) { +RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, const Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check, uint32_t p_view_count) { _THREAD_SAFE_METHOD_ Vector<AttachmentFormat> attachments; @@ -4140,6 +4178,9 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex framebuffer.view_count = p_view_count; RID id = framebuffer_owner.make_rid(framebuffer); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif for (int i = 0; i < p_texture_attachments.size(); i++) { if (p_texture_attachments[i].is_valid()) { @@ -4159,6 +4200,22 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_get_form return framebuffer->format_id; } +bool RenderingDeviceVulkan::framebuffer_is_valid(RID p_framebuffer) const { + _THREAD_SAFE_METHOD_ + + return framebuffer_owner.owns(p_framebuffer); +} + +void RenderingDeviceVulkan::framebuffer_set_invalidation_callback(RID p_framebuffer, InvalidationCallback p_callback, void *p_userdata) { + _THREAD_SAFE_METHOD_ + + Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_framebuffer); + ERR_FAIL_COND(!framebuffer); + + framebuffer->invalidated_callback = p_callback; + framebuffer->invalidated_callback_userdata = p_userdata; +} + /*****************/ /**** SAMPLER ****/ /*****************/ @@ -4201,7 +4258,11 @@ RID RenderingDeviceVulkan::sampler_create(const SamplerState &p_state) { VkResult res = vkCreateSampler(device, &sampler_create_info, nullptr, &sampler); ERR_FAIL_COND_V_MSG(res, RID(), "vkCreateSampler failed with error " + itos(res) + "."); - return sampler_owner.make_rid(sampler); + RID id = sampler_owner.make_rid(sampler); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif + return id; } /**********************/ @@ -4230,7 +4291,11 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec _buffer_memory_barrier(buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, false); } - return vertex_buffer_owner.make_rid(buffer); + RID id = vertex_buffer_owner.make_rid(buffer); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif + return id; } // Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated @@ -4391,7 +4456,11 @@ RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBuff _buffer_update(&index_buffer, 0, r, data_size); _buffer_memory_barrier(index_buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT, false); } - return index_buffer_owner.make_rid(index_buffer); + RID id = index_buffer_owner.make_rid(index_buffer); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif + return id; } RID RenderingDeviceVulkan::index_array_create(RID p_index_buffer, uint32_t p_index_offset, uint32_t p_index_count) { @@ -5488,7 +5557,11 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ ERR_FAIL_V_MSG(RID(), error_text); } - return shader_owner.make_rid(shader); + RID id = shader_owner.make_rid(shader); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif + return id; } uint32_t RenderingDeviceVulkan::shader_get_vertex_input_attribute_mask(RID p_shader) { @@ -5521,7 +5594,11 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Ve _buffer_update(&buffer, 0, r, data_size); _buffer_memory_barrier(buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_UNIFORM_READ_BIT, false); } - return uniform_buffer_owner.make_rid(buffer); + RID id = uniform_buffer_owner.make_rid(buffer); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif + return id; } RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data, uint32_t p_usage) { @@ -5592,7 +5669,11 @@ RID RenderingDeviceVulkan::texture_buffer_create(uint32_t p_size_elements, DataF } //allocate the view - return texture_buffer_owner.make_rid(texture_buffer); + RID id = texture_buffer_owner.make_rid(texture_buffer); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif + return id; } RenderingDeviceVulkan::DescriptorPool *RenderingDeviceVulkan::_descriptor_pool_allocate(const DescriptorPoolKey &p_key) { @@ -6171,6 +6252,9 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, uniform_set.shader_id = p_shader; RID id = uniform_set_owner.make_rid(uniform_set); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif //add dependencies _add_dependency(id, p_shader); for (uint32_t i = 0; i < uniform_count; i++) { @@ -6196,7 +6280,7 @@ bool RenderingDeviceVulkan::uniform_set_is_valid(RID p_uniform_set) { return uniform_set_owner.owns(p_uniform_set); } -void RenderingDeviceVulkan::uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata) { +void RenderingDeviceVulkan::uniform_set_set_invalidation_callback(RID p_uniform_set, InvalidationCallback p_callback, void *p_userdata) { UniformSet *us = uniform_set_owner.get_or_null(p_uniform_set); ERR_FAIL_COND(!us); us->invalidated_callback = p_callback; @@ -6793,6 +6877,9 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma #endif //create ID to associate with this pipeline RID id = render_pipeline_owner.make_rid(pipeline); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif //now add all the dependencies _add_dependency(id, p_shader); return id; @@ -6882,6 +6969,9 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader, const Vector<Pi //create ID to associate with this pipeline RID id = compute_pipeline_owner.make_rid(pipeline); +#ifdef DEV_ENABLED + set_resource_name(id, "RID:" + itos(id.get_id())); +#endif //now add all the dependencies _add_dependency(id, p_shader); return id; @@ -8663,6 +8753,11 @@ void RenderingDeviceVulkan::_free_internal(RID p_id) { } else if (framebuffer_owner.owns(p_id)) { Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_id); frames[frame].framebuffers_to_dispose_of.push_back(*framebuffer); + + if (framebuffer->invalidated_callback != nullptr) { + framebuffer->invalidated_callback(framebuffer->invalidated_callback_userdata); + } + framebuffer_owner.free(p_id); } else if (sampler_owner.owns(p_id)) { VkSampler *sampler = sampler_owner.get_or_null(p_id); diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 7c8021251f..d98ac1114b 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -392,6 +392,8 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t storage_mask = 0; Vector<RID> texture_ids; + InvalidationCallback invalidated_callback = nullptr; + void *invalidated_callback_userdata = nullptr; struct Version { VkFramebuffer framebuffer = VK_NULL_HANDLE; @@ -747,7 +749,7 @@ class RenderingDeviceVulkan : public RenderingDevice { LocalVector<AttachableTexture> attachable_textures; //used for validation Vector<Texture *> mutable_sampled_textures; //used for layout change Vector<Texture *> mutable_storage_textures; //used for layout change - UniformSetInvalidatedCallback invalidated_callback = nullptr; + InvalidationCallback invalidated_callback = nullptr; void *invalidated_callback_userdata = nullptr; }; @@ -1059,13 +1061,15 @@ public: /*********************/ virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format, uint32_t p_view_count = 1); - virtual FramebufferFormatID framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, Vector<FramebufferPass> &p_passes, uint32_t p_view_count = 1); + virtual FramebufferFormatID framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, uint32_t p_view_count = 1); virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1); virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format, uint32_t p_pass = 0); virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1); - virtual RID framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1); + virtual RID framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, const Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1); virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID); + virtual bool framebuffer_is_valid(RID p_framebuffer) const; + virtual void framebuffer_set_invalidation_callback(RID p_framebuffer, InvalidationCallback p_callback, void *p_userdata); virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer); @@ -1110,7 +1114,7 @@ public: virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set); virtual bool uniform_set_is_valid(RID p_uniform_set); - virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata); + virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, InvalidationCallback p_callback, void *p_userdata); virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL); //works for any buffer virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL); diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 524693eb03..a9a8ce68ac 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -1666,7 +1666,22 @@ Error VulkanContext::_update_swap_chain(Window *window) { if (present_mode_available) { window->presentMode = requested_present_mode; } else { - WARN_PRINT("Requested VSync mode is not available!"); + String present_mode_string; + switch (window->vsync_mode) { + case DisplayServer::VSYNC_MAILBOX: + present_mode_string = "Mailbox"; + break; + case DisplayServer::VSYNC_ADAPTIVE: + present_mode_string = "Adaptive"; + break; + case DisplayServer::VSYNC_ENABLED: + present_mode_string = "Enabled"; + break; + case DisplayServer::VSYNC_DISABLED: + present_mode_string = "Disabled"; + break; + } + WARN_PRINT(vformat("The requested V-Sync mode %s is not available. Falling back to V-Sync mode Enabled.", present_mode_string)); window->vsync_mode = DisplayServer::VSYNC_ENABLED; // Set to default. } @@ -1827,7 +1842,7 @@ Error VulkanContext::_update_swap_chain(Window *window) { /*pNext*/ nullptr, /*flags*/ 0, /*pipelineBindPoint*/ VK_PIPELINE_BIND_POINT_GRAPHICS, - /*viewMask*/ 1, + /*viewMask*/ 0, /*inputAttachmentCount*/ 0, /*pInputAttachments*/ nullptr, /*colorAttachmentCount*/ 1, @@ -1838,7 +1853,6 @@ Error VulkanContext::_update_swap_chain(Window *window) { /*pPreserveAttachments*/ nullptr, }; - uint32_t view_masks = 1; const VkRenderPassCreateInfo2KHR rp_info = { /*sType*/ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR, /*pNext*/ nullptr, @@ -1849,8 +1863,8 @@ Error VulkanContext::_update_swap_chain(Window *window) { /*pSubpasses*/ &subpass, /*dependencyCount*/ 0, /*pDependencies*/ nullptr, - /*correlatedViewMaskCount*/ 1, - /*pCorrelatedViewMasks*/ &view_masks, + /*correlatedViewMaskCount*/ 0, + /*pCorrelatedViewMasks*/ nullptr, }; err = vkCreateRenderPass2KHR(device, &rp_info, nullptr, &window->render_pass); @@ -2402,7 +2416,7 @@ void VulkanContext::command_begin_label(VkCommandBuffer p_command_buffer, String return; } - CharString cs = p_label_name.utf8().get_data(); + CharString cs = p_label_name.utf8(); VkDebugUtilsLabelEXT label; label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; label.pNext = nullptr; @@ -2418,7 +2432,7 @@ void VulkanContext::command_insert_label(VkCommandBuffer p_command_buffer, Strin if (!enabled_debug_utils) { return; } - CharString cs = p_label_name.utf8().get_data(); + CharString cs = p_label_name.utf8(); VkDebugUtilsLabelEXT label; label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; label.pNext = nullptr; @@ -2472,12 +2486,12 @@ String VulkanContext::get_device_pipeline_cache_uuid() const { } DisplayServer::VSyncMode VulkanContext::get_vsync_mode(DisplayServer::WindowID p_window) const { - ERR_FAIL_COND_V_MSG(!windows.has(p_window), DisplayServer::VSYNC_ENABLED, "Could not get VSync mode for window with WindowID " + itos(p_window) + " because it does not exist."); + ERR_FAIL_COND_V_MSG(!windows.has(p_window), DisplayServer::VSYNC_ENABLED, "Could not get V-Sync mode for window with WindowID " + itos(p_window) + " because it does not exist."); return windows[p_window].vsync_mode; } void VulkanContext::set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode) { - ERR_FAIL_COND_MSG(!windows.has(p_window), "Could not set VSync mode for window with WindowID " + itos(p_window) + " because it does not exist."); + ERR_FAIL_COND_MSG(!windows.has(p_window), "Could not set V-Sync mode for window with WindowID " + itos(p_window) + " because it does not exist."); windows[p_window].vsync_mode = p_mode; _update_swap_chain(&windows[p_window]); } diff --git a/drivers/windows/dir_access_windows.h b/drivers/windows/dir_access_windows.h index fbb07ddef8..c2835b3347 100644 --- a/drivers/windows/dir_access_windows.h +++ b/drivers/windows/dir_access_windows.h @@ -54,33 +54,33 @@ class DirAccessWindows : public DirAccess { bool _cishidden = false; public: - virtual Error list_dir_begin(); ///< This starts dir listing - virtual String get_next(); - virtual bool current_is_dir() const; - virtual bool current_is_hidden() const; - virtual void list_dir_end(); ///< + virtual Error list_dir_begin() override; ///< This starts dir listing + virtual String get_next() override; + virtual bool current_is_dir() const override; + virtual bool current_is_hidden() const override; + virtual void list_dir_end() override; ///< - virtual int get_drive_count(); - virtual String get_drive(int p_drive); + virtual int get_drive_count() override; + virtual String get_drive(int p_drive) override; - virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success - virtual String get_current_dir(bool p_include_drive = true) const; ///< return current dir location + virtual Error change_dir(String p_dir) override; ///< can be relative or absolute, return false on success + virtual String get_current_dir(bool p_include_drive = true) const override; ///< return current dir location - virtual bool file_exists(String p_file); - virtual bool dir_exists(String p_dir); + virtual bool file_exists(String p_file) override; + virtual bool dir_exists(String p_dir) override; - virtual Error make_dir(String p_dir); + virtual Error make_dir(String p_dir) override; - virtual Error rename(String p_path, String p_new_path); - virtual Error remove(String p_path); + virtual Error rename(String p_path, String p_new_path) override; + virtual Error remove(String p_path) override; - virtual bool is_link(String p_file) { return false; }; - virtual String read_link(String p_file) { return p_file; }; - virtual Error create_link(String p_source, String p_target) { return FAILED; }; + virtual bool is_link(String p_file) override { return false; }; + virtual String read_link(String p_file) override { return p_file; }; + virtual Error create_link(String p_source, String p_target) override { return FAILED; }; - uint64_t get_space_left(); + uint64_t get_space_left() override; - virtual String get_filesystem_type() const; + virtual String get_filesystem_type() const override; DirAccessWindows(); ~DirAccessWindows(); diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h index 5d67b6ca4f..8629bb936b 100644 --- a/drivers/windows/file_access_windows.h +++ b/drivers/windows/file_access_windows.h @@ -51,33 +51,33 @@ class FileAccessWindows : public FileAccess { void _close(); public: - virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file - virtual bool is_open() const; ///< true when file is open + virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file + virtual bool is_open() const override; ///< true when file is open - virtual String get_path() const; /// returns the path for the current open file - virtual String get_path_absolute() const; /// returns the absolute path for the current open file + virtual String get_path() const override; /// returns the path for the current open file + virtual String get_path_absolute() const override; /// returns the absolute path for the current open file - virtual void seek(uint64_t p_position); ///< seek to a given position - virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_length() const; ///< get size of the file + virtual void seek(uint64_t p_position) override; ///< seek to a given position + virtual void seek_end(int64_t p_position = 0) override; ///< seek from the end of file + virtual uint64_t get_position() const override; ///< get position in the file + virtual uint64_t get_length() const override; ///< get size of the file - virtual bool eof_reached() const; ///< reading passed EOF + virtual bool eof_reached() const override; ///< reading passed EOF - virtual uint8_t get_8() const; ///< get a byte - virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; + virtual uint8_t get_8() const override; ///< get a byte + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override; - virtual Error get_error() const; ///< get last error + virtual Error get_error() const override; ///< get last error - virtual void flush(); - virtual void store_8(uint8_t p_dest); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes + virtual void flush() override; + virtual void store_8(uint8_t p_dest) override; ///< store a byte + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes - virtual bool file_exists(const String &p_name); ///< return true if a file exists + virtual bool file_exists(const String &p_name) override; ///< return true if a file exists - uint64_t _get_modified_time(const String &p_file); - virtual uint32_t _get_unix_permissions(const String &p_file); - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions); + uint64_t _get_modified_time(const String &p_file) override; + virtual uint32_t _get_unix_permissions(const String &p_file) override; + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override; FileAccessWindows() {} virtual ~FileAccessWindows(); diff --git a/editor/SCsub b/editor/SCsub index a596c7d364..c217f162b4 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -76,7 +76,7 @@ if env["tools"]: # Editor translations to_include = ( - "ar,bg,ca,cs,de,el,eo,es_AR,es,fi,fr,gl,he,hu,id,it,ja,ko,lv,ms,nb,nl,pl,pt_BR,pt,ro,ru,sk,th,tr,uk,vi,zh_CN,zh_TW" + "ar,bg,ca,cs,de,el,eo,es_AR,es,fi,fr,gl,he,hu,id,it,ja,ko,lv,ms,nb,nl,pl,pt_BR,pt,ro,ru,sk,sv,th,tr,uk,vi,zh_CN,zh_TW" ).split(",") tlist = [env.Dir("#editor/translations").abspath + "/" + f + ".po" for f in to_include] env.Depends("#editor/editor_translations.gen.h", tlist) @@ -113,6 +113,7 @@ if env["tools"]: env.add_source_files(env.editor_sources, "register_exporters.gen.cpp") SConscript("debugger/SCsub") + SConscript("export/SCsub") SConscript("fileserver/SCsub") SConscript("icons/SCsub") SConscript("import/SCsub") diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp index 8c59d65c80..462f314471 100644 --- a/editor/action_map_editor.cpp +++ b/editor/action_map_editor.cpp @@ -720,7 +720,7 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() { for (int i = 0; i < MOD_MAX; i++) { String name = mods[i]; mod_checkboxes[i] = memnew(CheckBox); - mod_checkboxes[i]->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_mod_toggled), varray(i)); + mod_checkboxes[i]->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_mod_toggled).bind(i)); mod_checkboxes[i]->set_text(name); mod_container->add_child(mod_checkboxes[i]); } diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 44e04efb5d..ab9afda803 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -654,9 +654,9 @@ void AnimationBezierTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) { void AnimationBezierTrackEdit::set_editor(AnimationTrackEditor *p_editor) { editor = p_editor; - connect("clear_selection", Callable(editor, "_clear_selection"), varray(false)); - connect("select_key", Callable(editor, "_key_selected"), varray(), CONNECT_DEFERRED); - connect("deselect_key", Callable(editor, "_key_deselected"), varray(), CONNECT_DEFERRED); + connect("clear_selection", Callable(editor, "_clear_selection").bind(false)); + connect("select_key", Callable(editor, "_key_selected"), CONNECT_DEFERRED); + connect("deselect_key", Callable(editor, "_key_deselected"), CONNECT_DEFERRED); } void AnimationBezierTrackEdit::_play_position_draw() { diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 234bfb944c..83047caf98 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -37,6 +37,7 @@ #include "editor/editor_scale.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "scene/animation/animation_player.h" +#include "scene/gui/separator.h" #include "scene/gui/view_panner.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" @@ -3428,7 +3429,7 @@ void AnimationTrackEditor::set_root(Node *p_root) { root = p_root; if (root) { - root->connect("tree_exiting", callable_mp(this, &AnimationTrackEditor::_root_removed), make_binds(), CONNECT_ONESHOT); + root->connect("tree_exiting", callable_mp(this, &AnimationTrackEditor::_root_removed), CONNECT_ONESHOT); } _update_tracks(); @@ -3746,19 +3747,7 @@ void AnimationTrackEditor::_insert_track(bool p_reset_wanted, bool p_create_bezi undo_redo->commit_action(); if (advance) { - float step = animation->get_step(); - if (step == 0) { - step = 1; - } - - float pos = timeline->get_play_position(); - - pos = Math::snapped(pos + step, step); - if (pos > animation->get_length()) { - pos = animation->get_length(); - } - set_anim_pos(pos); - emit_signal(SNAME("timeline_changed"), pos, true, false); + _edit_menu_pressed(EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY); } } @@ -4086,12 +4075,20 @@ void AnimationTrackEditor::_confirm_insert_list() { } TrackIndices next_tracks(animation.ptr(), reset_anim.ptr()); + bool advance = false; while (insert_data.size()) { + if (insert_data.front()->get().advance) { + advance = true; + } next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, create_reset, reset_anim, insert_confirm_bezier->is_pressed()); insert_data.pop_front(); } undo_redo->commit_action(); + + if (advance) { + _edit_menu_pressed(EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY); + } } PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_base_path, Variant *r_current_val) { @@ -4518,20 +4515,20 @@ void AnimationTrackEditor::_update_tracks() { } track_edit->connect("timeline_changed", callable_mp(this, &AnimationTrackEditor::_timeline_changed)); - track_edit->connect("remove_request", callable_mp(this, &AnimationTrackEditor::_track_remove_request), varray(), CONNECT_DEFERRED); - track_edit->connect("dropped", callable_mp(this, &AnimationTrackEditor::_dropped_track), varray(), CONNECT_DEFERRED); - track_edit->connect("insert_key", callable_mp(this, &AnimationTrackEditor::_insert_key_from_track), varray(i), CONNECT_DEFERRED); - track_edit->connect("select_key", callable_mp(this, &AnimationTrackEditor::_key_selected), varray(i), CONNECT_DEFERRED); - track_edit->connect("deselect_key", callable_mp(this, &AnimationTrackEditor::_key_deselected), varray(i), CONNECT_DEFERRED); + track_edit->connect("remove_request", callable_mp(this, &AnimationTrackEditor::_track_remove_request), CONNECT_DEFERRED); + track_edit->connect("dropped", callable_mp(this, &AnimationTrackEditor::_dropped_track), CONNECT_DEFERRED); + track_edit->connect("insert_key", callable_mp(this, &AnimationTrackEditor::_insert_key_from_track).bind(i), CONNECT_DEFERRED); + track_edit->connect("select_key", callable_mp(this, &AnimationTrackEditor::_key_selected).bind(i), CONNECT_DEFERRED); + track_edit->connect("deselect_key", callable_mp(this, &AnimationTrackEditor::_key_deselected).bind(i), CONNECT_DEFERRED); track_edit->connect("move_selection_begin", callable_mp(this, &AnimationTrackEditor::_move_selection_begin)); track_edit->connect("move_selection", callable_mp(this, &AnimationTrackEditor::_move_selection)); track_edit->connect("move_selection_commit", callable_mp(this, &AnimationTrackEditor::_move_selection_commit)); track_edit->connect("move_selection_cancel", callable_mp(this, &AnimationTrackEditor::_move_selection_cancel)); - track_edit->connect("duplicate_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_DUPLICATE_SELECTION), CONNECT_DEFERRED); - track_edit->connect("duplicate_transpose_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_DUPLICATE_TRANSPOSED), CONNECT_DEFERRED); - track_edit->connect("create_reset_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_ADD_RESET_KEY), CONNECT_DEFERRED); - track_edit->connect("delete_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_DELETE_SELECTION), CONNECT_DEFERRED); + track_edit->connect("duplicate_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_DUPLICATE_SELECTION), CONNECT_DEFERRED); + track_edit->connect("duplicate_transpose_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_DUPLICATE_TRANSPOSED), CONNECT_DEFERRED); + track_edit->connect("create_reset_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_ADD_RESET_KEY), CONNECT_DEFERRED); + track_edit->connect("delete_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_DELETE_SELECTION), CONNECT_DEFERRED); } } @@ -5597,7 +5594,7 @@ void AnimationTrackEditor::goto_prev_step(bool p_from_mouse_event) { emit_signal(SNAME("timeline_changed"), pos, true, false); } -void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event) { +void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event, bool p_timeline_only) { if (animation.is_null()) { return; } @@ -5621,7 +5618,7 @@ void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event) { } set_anim_pos(pos); - emit_signal(SNAME("timeline_changed"), pos, true, false); + emit_signal(SNAME("timeline_changed"), pos, true, p_timeline_only); } void AnimationTrackEditor::_edit_menu_pressed(int p_option) { @@ -5969,8 +5966,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { _update_key_edit(); } } break; + case EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY: case EDIT_GOTO_NEXT_STEP: { - goto_next_step(false); + goto_next_step(false, p_option == EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY); } break; case EDIT_GOTO_PREV_STEP: { goto_prev_step(false); @@ -6480,7 +6478,7 @@ AnimationTrackEditor::AnimationTrackEditor() { optimize_max_angle->set_value(22); optimize_dialog->set_ok_button_text(TTR("Optimize")); - optimize_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_OPTIMIZE_ANIMATION_CONFIRM)); + optimize_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_OPTIMIZE_ANIMATION_CONFIRM)); // @@ -6506,7 +6504,7 @@ AnimationTrackEditor::AnimationTrackEditor() { cleanup_dialog->set_title(TTR("Clean-Up Animation(s) (NO UNDO!)")); cleanup_dialog->set_ok_button_text(TTR("Clean-Up")); - cleanup_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_CLEAN_UP_ANIMATION_CONFIRM)); + cleanup_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_CLEAN_UP_ANIMATION_CONFIRM)); // scale_dialog = memnew(ConfirmationDialog); @@ -6518,7 +6516,7 @@ AnimationTrackEditor::AnimationTrackEditor() { scale->set_max(99999); scale->set_step(0.001); vbc->add_margin_child(TTR("Scale Ratio:"), scale); - scale_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_SCALE_CONFIRM)); + scale_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_SCALE_CONFIRM)); add_child(scale_dialog); track_copy_dialog = memnew(ConfirmationDialog); @@ -6539,7 +6537,7 @@ AnimationTrackEditor::AnimationTrackEditor() { track_copy_select->set_v_size_flags(SIZE_EXPAND_FILL); track_copy_select->set_hide_root(true); track_vbox->add_child(track_copy_select); - track_copy_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_COPY_TRACKS_CONFIRM)); + track_copy_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_COPY_TRACKS_CONFIRM)); } AnimationTrackEditor::~AnimationTrackEditor() { diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index dede2e9bbe..cb7d3c7d96 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -33,11 +33,14 @@ #include "editor/editor_data.h" #include "editor/editor_spin_slider.h" -#include "editor/property_editor.h" #include "editor/property_selector.h" +#include "scene/3d/node_3d.h" +#include "scene/gui/check_box.h" #include "scene/gui/control.h" #include "scene/gui/menu_button.h" +#include "scene/gui/option_button.h" +#include "scene/gui/panel_container.h" #include "scene/gui/scroll_bar.h" #include "scene/gui/slider.h" #include "scene/gui/spin_box.h" @@ -518,6 +521,7 @@ public: EDIT_ADD_RESET_KEY, EDIT_DELETE_SELECTION, EDIT_GOTO_NEXT_STEP, + EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY, // Next step without updating animation. EDIT_GOTO_PREV_STEP, EDIT_APPLY_RESET, EDIT_OPTIMIZE_ANIMATION, @@ -563,7 +567,7 @@ public: void goto_prev_step(bool p_from_mouse_event); /** If `p_from_mouse_event` is `true`, handle Shift key presses for precise snapping. */ - void goto_next_step(bool p_from_mouse_event); + void goto_next_step(bool p_from_mouse_event, bool p_timeline_only = false); MenuButton *get_edit_menu(); AnimationTrackEditor(); diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp index fc47e1ef5c..b9e52ad7ad 100644 --- a/editor/audio_stream_preview.cpp +++ b/editor/audio_stream_preview.cpp @@ -200,6 +200,7 @@ Ref<AudioStreamPreview> AudioStreamPreviewGenerator::generate_preview(const Ref< if (preview->playback.is_valid()) { preview->thread = memnew(Thread); + preview->thread->set_name("AudioStreamPreviewGenerator"); preview->thread->start(_preview_thread, preview); } diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 99ca82b311..b0eb384efc 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1045,6 +1045,8 @@ void CodeTextEditor::update_editor_settings() { guideline_cols.append(EditorSettings::get_singleton()->get("text_editor/appearance/guidelines/line_length_guideline_soft_column")); } text_editor->set_line_length_guidelines(guideline_cols); + } else { + text_editor->set_line_length_guidelines(TypedArray<int>()); } } diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index ce94edd583..6fdd9563fb 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -627,7 +627,7 @@ void ConnectionsDock::_connect(ConnectDialog::ConnectionData p_cd) { Callable callable = p_cd.get_callable(); undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(p_cd.signal), String(p_cd.method))); - undo_redo->add_do_method(source, "connect", p_cd.signal, callable, varray(), p_cd.flags); + undo_redo->add_do_method(source, "connect", p_cd.signal, callable, p_cd.flags); undo_redo->add_undo_method(source, "disconnect", p_cd.signal, callable); undo_redo->add_do_method(this, "update_tree"); undo_redo->add_undo_method(this, "update_tree"); diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index dcfde8800a..d141d1a880 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -97,7 +97,7 @@ public: for (int i = 0; i < binds.size(); i++) { argptrs[i] = &binds[i]; } - return Callable(target, method).bind(argptrs, binds.size()); + return Callable(target, method).bindp(argptrs, binds.size()); } else { return Callable(target, method); } diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index c41eeb520a..e6168f4924 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -34,6 +34,7 @@ #include "core/os/keyboard.h" #include "editor/editor_feature_profile.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" @@ -378,7 +379,7 @@ void CreateDialog::_confirmed() { } { - Ref<FileAccess> f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::WRITE); + Ref<FileAccess> f = FileAccess::open(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::WRITE); if (f.is_valid()) { f->store_line(selected_item); @@ -655,7 +656,7 @@ void CreateDialog::_save_and_update_favorite_list() { TreeItem *root = favorites->create_item(); { - Ref<FileAccess> f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites." + base_type), FileAccess::WRITE); + Ref<FileAccess> f = FileAccess::open(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("favorites." + base_type), FileAccess::WRITE); if (f.is_valid()) { for (int i = 0; i < favorite_list.size(); i++) { String l = favorite_list[i]; @@ -680,7 +681,7 @@ void CreateDialog::_save_and_update_favorite_list() { } void CreateDialog::_load_favorites_and_history() { - String dir = EditorSettings::get_singleton()->get_project_settings_dir(); + String dir = EditorPaths::get_singleton()->get_project_settings_dir(); Ref<FileAccess> f = FileAccess::open(dir.plus_file("create_recent." + base_type), FileAccess::READ); if (f.is_valid()) { while (!f->eof_reached()) { diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.cpp b/editor/debugger/debug_adapter/debug_adapter_parser.cpp index 0caeb90108..3c3e4faa6f 100644 --- a/editor/debugger/debug_adapter/debug_adapter_parser.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_parser.cpp @@ -34,6 +34,7 @@ #include "editor/debugger/script_editor_debugger.h" #include "editor/editor_node.h" #include "editor/editor_run_native.h" +#include "editor/export/editor_export_platform.h" #include "editor/plugins/script_editor_plugin.h" void DebugAdapterParser::_bind_methods() { diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp index 92ea0f15e9..4c445eb766 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp @@ -37,6 +37,7 @@ #include "editor/doc_tools.h" #include "editor/editor_log.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" DebugAdapterProtocol *DebugAdapterProtocol::singleton = nullptr; diff --git a/editor/debugger/debug_adapter/debug_adapter_server.cpp b/editor/debugger/debug_adapter/debug_adapter_server.cpp index e9fc7ec913..41e6b1f308 100644 --- a/editor/debugger/debug_adapter/debug_adapter_server.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_server.cpp @@ -33,6 +33,7 @@ #include "core/os/os.h" #include "editor/editor_log.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" DebugAdapterServer::DebugAdapterServer() { _EDITOR_DEF("network/debug_adapter/remote_port", remote_port); diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index e13af59d69..472e53c0e8 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -92,17 +92,17 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() { ScriptEditorDebugger *node = memnew(ScriptEditorDebugger); int id = tabs->get_tab_count(); - node->connect("stop_requested", callable_mp(this, &EditorDebuggerNode::_debugger_wants_stop), varray(id)); - node->connect("stopped", callable_mp(this, &EditorDebuggerNode::_debugger_stopped), varray(id)); - node->connect("stack_frame_selected", callable_mp(this, &EditorDebuggerNode::_stack_frame_selected), varray(id)); - node->connect("error_selected", callable_mp(this, &EditorDebuggerNode::_error_selected), varray(id)); - node->connect("breakpoint_selected", callable_mp(this, &EditorDebuggerNode::_error_selected), varray(id)); + node->connect("stop_requested", callable_mp(this, &EditorDebuggerNode::_debugger_wants_stop).bind(id)); + node->connect("stopped", callable_mp(this, &EditorDebuggerNode::_debugger_stopped).bind(id)); + node->connect("stack_frame_selected", callable_mp(this, &EditorDebuggerNode::_stack_frame_selected).bind(id)); + node->connect("error_selected", callable_mp(this, &EditorDebuggerNode::_error_selected).bind(id)); + node->connect("breakpoint_selected", callable_mp(this, &EditorDebuggerNode::_error_selected).bind(id)); node->connect("clear_execution", callable_mp(this, &EditorDebuggerNode::_clear_execution)); - node->connect("breaked", callable_mp(this, &EditorDebuggerNode::_breaked), varray(id)); - node->connect("remote_tree_updated", callable_mp(this, &EditorDebuggerNode::_remote_tree_updated), varray(id)); - node->connect("remote_object_updated", callable_mp(this, &EditorDebuggerNode::_remote_object_updated), varray(id)); - node->connect("remote_object_property_updated", callable_mp(this, &EditorDebuggerNode::_remote_object_property_updated), varray(id)); - node->connect("remote_object_requested", callable_mp(this, &EditorDebuggerNode::_remote_object_requested), varray(id)); + node->connect("breaked", callable_mp(this, &EditorDebuggerNode::_breaked).bind(id)); + node->connect("remote_tree_updated", callable_mp(this, &EditorDebuggerNode::_remote_tree_updated).bind(id)); + node->connect("remote_object_updated", callable_mp(this, &EditorDebuggerNode::_remote_object_updated).bind(id)); + node->connect("remote_object_property_updated", callable_mp(this, &EditorDebuggerNode::_remote_object_property_updated).bind(id)); + node->connect("remote_object_requested", callable_mp(this, &EditorDebuggerNode::_remote_object_requested).bind(id)); node->connect("errors_cleared", callable_mp(this, &EditorDebuggerNode::_update_errors)); if (tabs->get_tab_count() > 0) { diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp index bdab1cfecb..dbd2c61d44 100644 --- a/editor/debugger/editor_debugger_tree.cpp +++ b/editor/debugger/editor_debugger_tree.cpp @@ -225,6 +225,39 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int updating_scene_tree = false; } +Variant EditorDebuggerTree::get_drag_data(const Point2 &p_point) { + if (get_button_id_at_position(p_point) != -1) { + return Variant(); + } + + TreeItem *selected = get_selected(); + if (!selected) { + return Variant(); + } + + String path = selected->get_text(0); + + HBoxContainer *hb = memnew(HBoxContainer); + TextureRect *tf = memnew(TextureRect); + tf->set_texture(selected->get_icon(0)); + tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); + hb->add_child(tf); + Label *label = memnew(Label(path)); + hb->add_child(label); + set_drag_preview(hb); + + if (!selected->get_parent() || !selected->get_parent()->get_parent()) { + path = "."; + } else { + while (selected->get_parent()->get_parent() != get_root()) { + selected = selected->get_parent(); + path = selected->get_text(0) + "/" + path; + } + } + + return vformat("\"%s\"", path); +} + String EditorDebuggerTree::get_selected_path() { if (!get_selected()) { return ""; diff --git a/editor/debugger/editor_debugger_tree.h b/editor/debugger/editor_debugger_tree.h index 9d163fd548..5b2df8abd5 100644 --- a/editor/debugger/editor_debugger_tree.h +++ b/editor/debugger/editor_debugger_tree.h @@ -65,6 +65,8 @@ protected: void _notification(int p_what); public: + virtual Variant get_drag_data(const Point2 &p_point) override; + String get_selected_path(); ObjectID get_selected_object(); int get_current_debugger(); // Would love to have one tree for every debugger. diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index ee67cbdaea..6f3dd1793c 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -796,7 +796,7 @@ EditorVisualProfiler::EditorVisualProfiler() { frame_delay->set_wait_time(0.1); frame_delay->set_one_shot(true); add_child(frame_delay); - frame_delay->connect("timeout", callable_mp(this, &EditorVisualProfiler::_update_frame), make_binds(false)); + frame_delay->connect("timeout", callable_mp(this, &EditorVisualProfiler::_update_frame).bind(false)); plot_delay = memnew(Timer); plot_delay->set_wait_time(0.1); diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index f8b82ecc51..ac2e958c5b 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -50,7 +50,6 @@ #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" -#include "editor/property_editor.h" #include "main/performance.h" #include "scene/3d/camera_3d.h" #include "scene/debugger/scene_debugger.h" @@ -753,7 +752,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da const Variant *args[2] = { &cmd, &data }; Variant retval; Callable::CallError err; - c.call(args, 2, retval, err); + c.callp(args, 2, retval, err); ERR_FAIL_COND_MSG(err.error != Callable::CallError::CALL_OK, "Error calling 'capture' to callable: " + Variant::get_callable_error_text(c, args, 2, err)); ERR_FAIL_COND_MSG(retval.get_type() != Variant::BOOL, "Error calling 'capture' to callable: " + String(c) + ". Return type is not bool."); parsed = retval; @@ -1877,7 +1876,7 @@ ScriptEditorDebugger::ScriptEditorDebugger() { profiler = memnew(EditorProfiler); profiler->set_name(TTR("Profiler")); tabs->add_child(profiler); - profiler->connect("enable_profiling", callable_mp(this, &ScriptEditorDebugger::_profiler_activate), varray(PROFILER_SCRIPTS_SERVERS)); + profiler->connect("enable_profiling", callable_mp(this, &ScriptEditorDebugger::_profiler_activate).bind(PROFILER_SCRIPTS_SERVERS)); profiler->connect("break_request", callable_mp(this, &ScriptEditorDebugger::_profiler_seeked)); } @@ -1885,14 +1884,14 @@ ScriptEditorDebugger::ScriptEditorDebugger() { visual_profiler = memnew(EditorVisualProfiler); visual_profiler->set_name(TTR("Visual Profiler")); tabs->add_child(visual_profiler); - visual_profiler->connect("enable_profiling", callable_mp(this, &ScriptEditorDebugger::_profiler_activate), varray(PROFILER_VISUAL)); + visual_profiler->connect("enable_profiling", callable_mp(this, &ScriptEditorDebugger::_profiler_activate).bind(PROFILER_VISUAL)); } { //network profiler network_profiler = memnew(EditorNetworkProfiler); network_profiler->set_name(TTR("Network Profiler")); tabs->add_child(network_profiler); - network_profiler->connect("enable_profiling", callable_mp(this, &ScriptEditorDebugger::_profiler_activate), varray(PROFILER_NETWORK)); + network_profiler->connect("enable_profiling", callable_mp(this, &ScriptEditorDebugger::_profiler_activate).bind(PROFILER_NETWORK)); } { //monitors diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 4f89e1b2d1..43961a7ceb 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -37,6 +37,7 @@ #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/gui/margin_container.h" void DependencyEditor::_searched(const String &p_path) { @@ -416,6 +417,45 @@ void DependencyRemoveDialog::_find_all_removed_dependencies(EditorFileSystemDire } } +void DependencyRemoveDialog::_find_localization_remaps_of_removed_files(Vector<RemovedDependency> &p_removed) { + for (KeyValue<String, String> &files : all_remove_files) { + const String &path = files.key; + + // Look for dependencies in the translation remaps. + if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { + Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + + if (remaps.has(path)) { + RemovedDependency dep; + dep.file = TTR("Localization remap"); + dep.file_type = ""; + dep.dependency = path; + dep.dependency_folder = files.value; + p_removed.push_back(dep); + } + + Array remap_keys = remaps.keys(); + for (int j = 0; j < remap_keys.size(); j++) { + PackedStringArray remapped_files = remaps[remap_keys[j]]; + for (int k = 0; k < remapped_files.size(); k++) { + int splitter_pos = remapped_files[k].rfind(":"); + String res_path = remapped_files[k].substr(0, splitter_pos); + if (res_path == path) { + String locale_name = remapped_files[k].substr(splitter_pos + 1); + + RemovedDependency dep; + dep.file = vformat(TTR("Localization remap for path '%s' and locale '%s'."), remap_keys[j], locale_name); + dep.file_type = ""; + dep.dependency = path; + dep.dependency_folder = files.value; + p_removed.push_back(dep); + } + } + } + } + } +} + void DependencyRemoveDialog::_build_removed_dependency_tree(const Vector<RemovedDependency> &p_removed) { owners->clear(); owners->create_item(); // root @@ -472,6 +512,7 @@ void DependencyRemoveDialog::show(const Vector<String> &p_folders, const Vector< Vector<RemovedDependency> removed_deps; _find_all_removed_dependencies(EditorFileSystem::get_singleton()->get_filesystem(), removed_deps); + _find_localization_remaps_of_removed_files(removed_deps); removed_deps.sort(); if (removed_deps.is_empty()) { owners->hide(); diff --git a/editor/dependency_editor.h b/editor/dependency_editor.h index 96d82d58eb..6e39015ec3 100644 --- a/editor/dependency_editor.h +++ b/editor/dependency_editor.h @@ -119,6 +119,7 @@ class DependencyRemoveDialog : public ConfirmationDialog { void _find_files_in_removed_folder(EditorFileSystemDirectory *efsd, const String &p_folder); void _find_all_removed_dependencies(EditorFileSystemDirectory *efsd, Vector<RemovedDependency> &p_removed); + void _find_localization_remaps_of_removed_files(Vector<RemovedDependency> &p_removed); void _build_removed_dependency_tree(const Vector<RemovedDependency> &p_removed); void ok_pressed() override; diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index 773fcc5017..a819458417 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -39,6 +39,7 @@ #include "core/object/script_language.h" #include "core/string/translation.h" #include "core/version.h" +#include "editor/editor_settings.h" #include "scene/resources/theme.h" // Used for a hack preserving Mono properties on non-Mono builds. @@ -363,8 +364,15 @@ void DocTools::generate(bool p_basic_types) { List<PropertyInfo> properties; List<PropertyInfo> own_properties; - if (name == "ProjectSettings") { - // Special case for project settings, so settings can be documented. + + // Special case for editor and project settings, so they can be documented. + if (name == "EditorSettings") { + // We don't create the full blown EditorSettings (+ config file) with `create()`, + // instead we just make a local instance to get default values. + Ref<EditorSettings> edset = memnew(EditorSettings); + edset->get_property_list(&properties); + own_properties = properties; + } else if (name == "ProjectSettings") { ProjectSettings::get_singleton()->get_property_list(&properties); own_properties = properties; } else { @@ -402,6 +410,13 @@ void DocTools::generate(bool p_basic_types) { bool default_value_valid = false; Variant default_value; + if (name == "EditorSettings") { + if (E.name == "resource_local_to_scene" || E.name == "resource_name" || E.name == "resource_path" || E.name == "script") { + // Don't include spurious properties in the generated EditorSettings class reference. + continue; + } + } + if (name == "ProjectSettings") { // Special case for project settings, so that settings are not taken from the current project's settings if (E.name == "script" || !ProjectSettings::get_singleton()->is_builtin_setting(E.name)) { @@ -424,8 +439,6 @@ void DocTools::generate(bool p_basic_types) { } } - //used to track uninitialized values using valgrind - //print_line("getting default value for " + String(name) + "." + String(E.name)); if (default_value_valid && default_value.get_type() != Variant::OBJECT) { prop.default_value = default_value.get_construct_string().replace("\n", " "); } diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index 8fa486408e..8dc8a0ab6b 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -100,8 +100,8 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { extension_guess["tga"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")); extension_guess["webp"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")); - extension_guess["wav"] = tree->get_theme_icon(SNAME("AudioStreamSample"), SNAME("EditorIcons")); - extension_guess["ogg"] = tree->get_theme_icon(SNAME("AudioStreamOGGVorbis"), SNAME("EditorIcons")); + extension_guess["wav"] = tree->get_theme_icon(SNAME("AudioStreamWAV"), SNAME("EditorIcons")); + extension_guess["ogg"] = tree->get_theme_icon(SNAME("AudioStreamOggVorbis"), SNAME("EditorIcons")); extension_guess["mp3"] = tree->get_theme_icon(SNAME("AudioStreamMP3"), SNAME("EditorIcons")); extension_guess["scn"] = tree->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index fa365c4368..b6d7bbc45f 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -37,6 +37,7 @@ #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "filesystem_dock.h" #include "scene/resources/font.h" #include "servers/audio_server.h" @@ -1007,11 +1008,11 @@ void EditorAudioBuses::_update_buses() { bool is_master = (i == 0); EditorAudioBus *audio_bus = memnew(EditorAudioBus(this, is_master)); bus_hb->add_child(audio_bus); - audio_bus->connect("delete_request", callable_mp(this, &EditorAudioBuses::_delete_bus), varray(audio_bus), CONNECT_DEFERRED); - audio_bus->connect("duplicate_request", callable_mp(this, &EditorAudioBuses::_duplicate_bus), varray(), CONNECT_DEFERRED); - audio_bus->connect("vol_reset_request", callable_mp(this, &EditorAudioBuses::_reset_bus_volume), varray(audio_bus), CONNECT_DEFERRED); + audio_bus->connect("delete_request", callable_mp(this, &EditorAudioBuses::_delete_bus).bind(audio_bus), CONNECT_DEFERRED); + audio_bus->connect("duplicate_request", callable_mp(this, &EditorAudioBuses::_duplicate_bus), CONNECT_DEFERRED); + audio_bus->connect("vol_reset_request", callable_mp(this, &EditorAudioBuses::_reset_bus_volume).bind(audio_bus), CONNECT_DEFERRED); audio_bus->connect("drop_end_request", callable_mp(this, &EditorAudioBuses::_request_drop_end)); - audio_bus->connect("dropped", callable_mp(this, &EditorAudioBuses::_drop_at_index), varray(), CONNECT_DEFERRED); + audio_bus->connect("dropped", callable_mp(this, &EditorAudioBuses::_drop_at_index), CONNECT_DEFERRED); } } @@ -1154,7 +1155,7 @@ void EditorAudioBuses::_request_drop_end() { bus_hb->add_child(drop_end); drop_end->set_custom_minimum_size(Object::cast_to<Control>(bus_hb->get_child(0))->get_size()); - drop_end->connect("dropped", callable_mp(this, &EditorAudioBuses::_drop_at_index), varray(), CONNECT_DEFERRED); + drop_end->connect("dropped", callable_mp(this, &EditorAudioBuses::_drop_at_index), CONNECT_DEFERRED); } } @@ -1174,7 +1175,7 @@ void EditorAudioBuses::_drop_at_index(int p_bus, int p_index) { void EditorAudioBuses::_server_save() { Ref<AudioBusLayout> state = AudioServer::get_singleton()->generate_bus_layout(); - ResourceSaver::save(edited_path, state); + ResourceSaver::save(state, edited_path); } void EditorAudioBuses::_select_layout() { @@ -1244,7 +1245,7 @@ void EditorAudioBuses::_file_dialog_callback(const String &p_string) { AudioServer::get_singleton()->set_bus_layout(empty_state); } - Error err = ResourceSaver::save(p_string, AudioServer::get_singleton()->generate_bus_layout()); + Error err = ResourceSaver::save(AudioServer::get_singleton()->generate_bus_layout(), p_string); if (err != OK) { EditorNode::get_singleton()->show_warning(vformat(TTR("Error saving file: %s"), p_string)); diff --git a/editor/editor_build_profile.cpp b/editor/editor_build_profile.cpp index 6a5604290f..0f0ab4a339 100644 --- a/editor/editor_build_profile.cpp +++ b/editor/editor_build_profile.cpp @@ -46,19 +46,68 @@ const char *EditorBuildProfile::build_option_identifiers[BUILD_OPTION_MAX] = { "disable_3d_physics", "disable_navigation", "openxr", + "rendering_device", // FIXME: there's no scons option to disable rendering device "opengl3", "vulkan", + "module_text_server_fb_enabled", + "module_text_server_adv_enabled", + "module_freetype_enabled", + "brotli", + "graphite", + "module_msdfgen_enabled" +}; + +const bool EditorBuildProfile::build_option_disabled_by_default[BUILD_OPTION_MAX] = { + // This maps to SCons build options. + false, // 3D + false, // PHYSICS_2D + false, // PHYSICS_3D + false, // NAVIGATION + false, // XR + false, // RENDERING_DEVICE + false, // OPENGL + false, // VULKAN + true, // TEXT_SERVER_FALLBACK + false, // TEXT_SERVER_COMPLEX + false, // DYNAMIC_FONTS + false, // WOFF2_FONTS + false, // GRPAHITE_FONTS + false, // MSDFGEN }; const bool EditorBuildProfile::build_option_disable_values[BUILD_OPTION_MAX] = { // This maps to SCons build options. - true, - true, - true, - true, - false, - false, - false + true, // 3D + true, // PHYSICS_2D + true, // PHYSICS_3D + true, // NAVIGATION + false, // XR + false, // RENDERING_DEVICE + false, // OPENGL + false, // VULKAN + false, // TEXT_SERVER_FALLBACK + false, // TEXT_SERVER_COMPLEX + false, // DYNAMIC_FONTS + false, // WOFF2_FONTS + false, // GRPAHITE_FONTS + false, // MSDFGEN +}; + +const EditorBuildProfile::BuildOptionCategory EditorBuildProfile::build_option_category[BUILD_OPTION_MAX] = { + BUILD_OPTION_CATEGORY_GENERAL, // 3D + BUILD_OPTION_CATEGORY_GENERAL, // PHYSICS_2D + BUILD_OPTION_CATEGORY_GENERAL, // PHYSICS_3D + BUILD_OPTION_CATEGORY_GENERAL, // NAVIGATION + BUILD_OPTION_CATEGORY_GENERAL, // XR + BUILD_OPTION_CATEGORY_GENERAL, // RENDERING_DEVICE + BUILD_OPTION_CATEGORY_GENERAL, // OPENGL + BUILD_OPTION_CATEGORY_GENERAL, // VULKAN + BUILD_OPTION_CATEGORY_TEXT_SERVER, // TEXT_SERVER_FALLBACK + BUILD_OPTION_CATEGORY_TEXT_SERVER, // TEXT_SERVER_COMPLEX + BUILD_OPTION_CATEGORY_TEXT_SERVER, // DYNAMIC_FONTS + BUILD_OPTION_CATEGORY_TEXT_SERVER, // WOFF2_FONTS + BUILD_OPTION_CATEGORY_TEXT_SERVER, // GRPAHITE_FONTS + BUILD_OPTION_CATEGORY_TEXT_SERVER, // MSDFGEN }; void EditorBuildProfile::set_disable_class(const StringName &p_class, bool p_disabled) { @@ -127,6 +176,12 @@ String EditorBuildProfile::get_build_option_name(BuildOption p_build_option) { TTRC("RenderingDevice"), TTRC("OpenGL"), TTRC("Vulkan"), + TTRC("Text Server: Fallback"), + TTRC("Text Server: Advanced"), + TTRC("TTF, OTF, Type 1, WOFF1 Fonts"), + TTRC("WOFF2 Fonts"), + TTRC("SIL Graphite Fonts"), + TTRC("Multi-channel Signed Distance Field Font Rendering"), }; return TTRGET(build_option_names[p_build_option]); } @@ -143,11 +198,33 @@ String EditorBuildProfile::get_build_option_description(BuildOption p_build_opti TTRC("RenderingDevice based rendering (if disabled, the OpenGL back-end is required)."), TTRC("OpenGL back-end (if disabled, the RenderingDevice back-end is required)."), TTRC("Vulkan back-end of RenderingDevice."), + TTRC("Fallback implementation of Text Server\nSupports basic text layouts."), + TTRC("Text Server implementation powered by ICU and HarfBuzz libraries.\nSupports complex text layouts, BiDi, and contextual OpenType font features."), + TTRC("TrueType, OpenType, Type 1, and WOFF1 font format support using FreeType library (if disabled, WOFF2 support is also disabled)."), + TTRC("WOFF2 font format support using FreeType and Brotli libraries."), + TTRC("SIL Graphite smart font technology support (supported by Advanced Text Server only)."), + TTRC("Multi-channel signed distance field font rendering support using msdfgen library (pre-rendered MSDF fonts can be used even if this option disabled)."), }; return TTRGET(build_option_descriptions[p_build_option]); } +EditorBuildProfile::BuildOptionCategory EditorBuildProfile::get_build_option_category(BuildOption p_build_option) { + ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, BUILD_OPTION_CATEGORY_GENERAL); + return build_option_category[p_build_option]; +} + +String EditorBuildProfile::get_build_option_category_name(BuildOptionCategory p_build_option_category) { + ERR_FAIL_INDEX_V(p_build_option_category, BUILD_OPTION_CATEGORY_MAX, String()); + + const char *build_option_subcategories[BUILD_OPTION_CATEGORY_MAX]{ + TTRC("General Features:"), + TTRC("Text Rendering and Font Options:"), + }; + + return TTRGET(build_option_subcategories[p_build_option_category]); +} + Error EditorBuildProfile::save_to_file(const String &p_path) { Dictionary data; data["type"] = "build_profile"; @@ -160,8 +237,12 @@ Error EditorBuildProfile::save_to_file(const String &p_path) { Dictionary dis_build_options; for (int i = 0; i < BUILD_OPTION_MAX; i++) { - if (build_options_disabled[i]) { - dis_build_options[build_option_identifiers[i]] = build_option_disable_values[i]; + if (build_options_disabled[i] != build_option_disabled_by_default[i]) { + if (build_options_disabled[i]) { + dis_build_options[build_option_identifiers[i]] = build_option_disable_values[i]; + } else { + dis_build_options[build_option_identifiers[i]] = !build_option_disable_values[i]; + } } } @@ -211,7 +292,7 @@ Error EditorBuildProfile::load_from_file(const String &p_path) { } for (int i = 0; i < BUILD_OPTION_MAX; i++) { - build_options_disabled[i] = false; + build_options_disabled[i] = build_option_disabled_by_default[i]; } if (data.has("disabled_build_options")) { @@ -259,10 +340,24 @@ void EditorBuildProfile::_bind_methods() { BIND_ENUM_CONSTANT(BUILD_OPTION_RENDERING_DEVICE); BIND_ENUM_CONSTANT(BUILD_OPTION_OPENGL); BIND_ENUM_CONSTANT(BUILD_OPTION_VULKAN); + BIND_ENUM_CONSTANT(BUILD_OPTION_TEXT_SERVER_FALLBACK); + BIND_ENUM_CONSTANT(BUILD_OPTION_TEXT_SERVER_ADVANCED); + BIND_ENUM_CONSTANT(BUILD_OPTION_DYNAMIC_FONTS); + BIND_ENUM_CONSTANT(BUILD_OPTION_WOFF2_FONTS); + BIND_ENUM_CONSTANT(BUILD_OPTION_GRPAHITE_FONTS); + BIND_ENUM_CONSTANT(BUILD_OPTION_MSDFGEN); BIND_ENUM_CONSTANT(BUILD_OPTION_MAX); + + BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_GENERAL); + BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_TEXT_SERVER); + BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_MAX); } -EditorBuildProfile::EditorBuildProfile() {} +EditorBuildProfile::EditorBuildProfile() { + for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_MAX; i++) { + build_options_disabled[i] = build_option_disabled_by_default[i]; + } +} ////////////////////////// @@ -633,11 +728,18 @@ void EditorBuildProfileManager::_update_edited_profile() { TreeItem *root = class_list->create_item(); - TreeItem *build_options = class_list->create_item(root); - build_options->set_text(0, TTR("General Features:")); + HashMap<EditorBuildProfile::BuildOptionCategory, TreeItem *> subcats; + for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_CATEGORY_MAX; i++) { + TreeItem *build_cat; + build_cat = class_list->create_item(root); + + build_cat->set_text(0, EditorBuildProfile::get_build_option_category_name(EditorBuildProfile::BuildOptionCategory(i))); + subcats[EditorBuildProfile::BuildOptionCategory(i)] = build_cat; + } + for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_MAX; i++) { TreeItem *build_option; - build_option = class_list->create_item(build_options); + build_option = class_list->create_item(subcats[EditorBuildProfile::get_build_option_category(EditorBuildProfile::BuildOption(i))]); build_option->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); build_option->set_text(0, EditorBuildProfile::get_build_option_name(EditorBuildProfile::BuildOption(i))); @@ -723,19 +825,19 @@ EditorBuildProfileManager::EditorBuildProfileManager() { profile_actions[ACTION_NEW] = memnew(Button(TTR("New"))); path_hbc->add_child(profile_actions[ACTION_NEW]); - profile_actions[ACTION_NEW]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_NEW)); + profile_actions[ACTION_NEW]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action).bind(ACTION_NEW)); profile_actions[ACTION_LOAD] = memnew(Button(TTR("Load"))); path_hbc->add_child(profile_actions[ACTION_LOAD]); - profile_actions[ACTION_LOAD]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_LOAD)); + profile_actions[ACTION_LOAD]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action).bind(ACTION_LOAD)); profile_actions[ACTION_SAVE] = memnew(Button(TTR("Save"))); path_hbc->add_child(profile_actions[ACTION_SAVE]); - profile_actions[ACTION_SAVE]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_SAVE)); + profile_actions[ACTION_SAVE]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action).bind(ACTION_SAVE)); profile_actions[ACTION_SAVE_AS] = memnew(Button(TTR("Save As"))); path_hbc->add_child(profile_actions[ACTION_SAVE_AS]); - profile_actions[ACTION_SAVE_AS]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_SAVE_AS)); + profile_actions[ACTION_SAVE_AS]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action).bind(ACTION_SAVE_AS)); main_vbc->add_margin_child(TTR("Profile:"), path_hbc); @@ -745,11 +847,11 @@ EditorBuildProfileManager::EditorBuildProfileManager() { profile_actions[ACTION_RESET] = memnew(Button(TTR("Reset to Defaults"))); profiles_hbc->add_child(profile_actions[ACTION_RESET]); - profile_actions[ACTION_RESET]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_RESET)); + profile_actions[ACTION_RESET]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action).bind(ACTION_RESET)); profile_actions[ACTION_DETECT] = memnew(Button(TTR("Detect from Project"))); profiles_hbc->add_child(profile_actions[ACTION_DETECT]); - profile_actions[ACTION_DETECT]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_DETECT)); + profile_actions[ACTION_DETECT]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action).bind(ACTION_DETECT)); main_vbc->add_margin_child(TTR("Actions:"), profiles_hbc); @@ -757,7 +859,7 @@ EditorBuildProfileManager::EditorBuildProfileManager() { class_list->set_hide_root(true); class_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); class_list->connect("cell_selected", callable_mp(this, &EditorBuildProfileManager::_class_list_item_selected)); - class_list->connect("item_edited", callable_mp(this, &EditorBuildProfileManager::_class_list_item_edited), varray(), CONNECT_DEFERRED); + class_list->connect("item_edited", callable_mp(this, &EditorBuildProfileManager::_class_list_item_edited), CONNECT_DEFERRED); class_list->connect("item_collapsed", callable_mp(this, &EditorBuildProfileManager::_class_list_item_collapsed)); // It will be displayed once the user creates or chooses a profile. main_vbc->add_margin_child(TTR("Configure Engine Build Profile:"), class_list, true); diff --git a/editor/editor_build_profile.h b/editor/editor_build_profile.h index bb6494b8c9..606c415429 100644 --- a/editor/editor_build_profile.h +++ b/editor/editor_build_profile.h @@ -53,7 +53,19 @@ public: BUILD_OPTION_RENDERING_DEVICE, BUILD_OPTION_OPENGL, BUILD_OPTION_VULKAN, - BUILD_OPTION_MAX + BUILD_OPTION_TEXT_SERVER_FALLBACK, + BUILD_OPTION_TEXT_SERVER_ADVANCED, + BUILD_OPTION_DYNAMIC_FONTS, + BUILD_OPTION_WOFF2_FONTS, + BUILD_OPTION_GRPAHITE_FONTS, + BUILD_OPTION_MSDFGEN, + BUILD_OPTION_MAX, + }; + + enum BuildOptionCategory { + BUILD_OPTION_CATEGORY_GENERAL, + BUILD_OPTION_CATEGORY_TEXT_SERVER, + BUILD_OPTION_CATEGORY_MAX, }; private: @@ -65,7 +77,9 @@ private: bool build_options_disabled[BUILD_OPTION_MAX] = {}; static const char *build_option_identifiers[BUILD_OPTION_MAX]; + static const bool build_option_disabled_by_default[BUILD_OPTION_MAX]; static const bool build_option_disable_values[BUILD_OPTION_MAX]; + static const BuildOptionCategory build_option_category[BUILD_OPTION_MAX]; String _get_build_option_name(BuildOption p_build_option) { return get_build_option_name(p_build_option); } @@ -93,11 +107,15 @@ public: static String get_build_option_name(BuildOption p_build_option); static String get_build_option_description(BuildOption p_build_option); static bool get_build_option_disable_value(BuildOption p_build_option); + static BuildOptionCategory get_build_option_category(BuildOption p_build_option); + + static String get_build_option_category_name(BuildOptionCategory p_build_option_category); EditorBuildProfile(); }; VARIANT_ENUM_CAST(EditorBuildProfile::BuildOption) +VARIANT_ENUM_CAST(EditorBuildProfile::BuildOptionCategory) class EditorFileSystemDirectory; diff --git a/editor/editor_command_palette.cpp b/editor/editor_command_palette.cpp index c1cd7f9c7b..ba1f2fd6af 100644 --- a/editor/editor_command_palette.cpp +++ b/editor/editor_command_palette.cpp @@ -32,6 +32,7 @@ #include "core/os/keyboard.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/gui/control.h" #include "scene/gui/tree.h" @@ -199,7 +200,7 @@ void EditorCommandPalette::add_command(String p_command_name, String p_key_name, } Command command; command.name = p_command_name; - command.callable = p_action.bind(argptrs, arguments.size()); + command.callable = p_action.bindp(argptrs, arguments.size()); command.shortcut = p_shortcut_text; commands[p_key_name] = command; @@ -225,7 +226,7 @@ void EditorCommandPalette::_add_command(String p_command_name, String p_key_name void EditorCommandPalette::execute_command(String &p_command_key) { ERR_FAIL_COND_MSG(!commands.has(p_command_key), p_command_key + " not found."); commands[p_command_key].last_used = OS::get_singleton()->get_unix_time(); - commands[p_command_key].callable.call_deferred(nullptr, 0); + commands[p_command_key].callable.call_deferredp(nullptr, 0); _save_history(); } @@ -311,8 +312,8 @@ 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->connect("item_selected", callable_mp((BaseButton *)get_ok_button(), &BaseButton::set_disabled).bind(false)); + search_options->connect("nothing_selected", callable_mp((BaseButton *)get_ok_button(), &BaseButton::set_disabled).bind(true)); search_options->create_item(); search_options->set_hide_root(true); search_options->set_columns(2); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index e9e3320a3d..2d4945db14 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -1028,7 +1028,7 @@ void EditorSelection::add_node(Node *p_node) { } selection[p_node] = meta; - p_node->connect("tree_exiting", callable_mp(this, &EditorSelection::_node_removed), varray(p_node), CONNECT_ONESHOT); + p_node->connect("tree_exiting", callable_mp(this, &EditorSelection::_node_removed).bind(p_node), CONNECT_ONESHOT); } void EditorSelection::remove_node(Node *p_node) { diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp index 4cbc0cf25d..4071722185 100644 --- a/editor/editor_dir_dialog.cpp +++ b/editor/editor_dir_dialog.cpp @@ -81,15 +81,15 @@ void EditorDirDialog::reload(const String &p_path) { void EditorDirDialog::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &EditorDirDialog::reload), make_binds("")); + EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &EditorDirDialog::reload).bind("")); reload(); if (!tree->is_connected("item_collapsed", callable_mp(this, &EditorDirDialog::_item_collapsed))) { - tree->connect("item_collapsed", callable_mp(this, &EditorDirDialog::_item_collapsed), varray(), CONNECT_DEFERRED); + tree->connect("item_collapsed", callable_mp(this, &EditorDirDialog::_item_collapsed), CONNECT_DEFERRED); } if (!EditorFileSystem::get_singleton()->is_connected("filesystem_changed", callable_mp(this, &EditorDirDialog::reload))) { - EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &EditorDirDialog::reload), make_binds("")); + EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &EditorDirDialog::reload).bind("")); } } break; diff --git a/editor/editor_export.h b/editor/editor_export.h deleted file mode 100644 index a632cd88cd..0000000000 --- a/editor/editor_export.h +++ /dev/null @@ -1,532 +0,0 @@ -/*************************************************************************/ -/* editor_export.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef EDITOR_EXPORT_H -#define EDITOR_EXPORT_H - -#include "core/io/dir_access.h" -#include "core/io/resource.h" -#include "scene/gui/rich_text_label.h" -#include "scene/main/node.h" -#include "scene/main/timer.h" -#include "scene/resources/texture.h" - -class FileAccess; -class EditorExportPlatform; -class EditorFileSystemDirectory; -struct EditorProgress; - -class EditorExportPreset : public RefCounted { - GDCLASS(EditorExportPreset, RefCounted); - -public: - enum ExportFilter { - EXPORT_ALL_RESOURCES, - EXPORT_SELECTED_SCENES, - EXPORT_SELECTED_RESOURCES, - EXCLUDE_SELECTED_RESOURCES, - }; - - enum ScriptExportMode { - MODE_SCRIPT_TEXT, - MODE_SCRIPT_COMPILED, - }; - -private: - Ref<EditorExportPlatform> platform; - ExportFilter export_filter = EXPORT_ALL_RESOURCES; - String include_filter; - String exclude_filter; - String export_path; - - String exporter; - HashSet<String> selected_files; - bool runnable = false; - - friend class EditorExport; - friend class EditorExportPlatform; - - List<PropertyInfo> properties; - HashMap<StringName, Variant> values; - - String name; - - String custom_features; - - String enc_in_filters; - String enc_ex_filters; - bool enc_pck = false; - bool enc_directory = false; - - int script_mode = MODE_SCRIPT_COMPILED; - String script_key; - -protected: - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; - -public: - Ref<EditorExportPlatform> get_platform() const; - - bool has(const StringName &p_property) const { return values.has(p_property); } - - void update_files_to_export(); - - Vector<String> get_files_to_export() const; - - void add_export_file(const String &p_path); - void remove_export_file(const String &p_path); - bool has_export_file(const String &p_path); - - void set_name(const String &p_name); - String get_name() const; - - void set_runnable(bool p_enable); - bool is_runnable() const; - - void set_export_filter(ExportFilter p_filter); - ExportFilter get_export_filter() const; - - void set_include_filter(const String &p_include); - String get_include_filter() const; - - void set_exclude_filter(const String &p_exclude); - String get_exclude_filter() const; - - void set_custom_features(const String &p_custom_features); - String get_custom_features() const; - - void set_export_path(const String &p_path); - String get_export_path() const; - - void set_enc_in_filter(const String &p_filter); - String get_enc_in_filter() const; - - void set_enc_ex_filter(const String &p_filter); - String get_enc_ex_filter() const; - - void set_enc_pck(bool p_enabled); - bool get_enc_pck() const; - - void set_enc_directory(bool p_enabled); - bool get_enc_directory() const; - - void set_script_export_mode(int p_mode); - int get_script_export_mode() const; - - void set_script_encryption_key(const String &p_key); - String get_script_encryption_key() const; - - const List<PropertyInfo> &get_properties() const { return properties; } - - EditorExportPreset() {} -}; - -struct SharedObject { - String path; - Vector<String> tags; - String target; - - SharedObject(const String &p_path, const Vector<String> &p_tags, const String &p_target) : - path(p_path), - tags(p_tags), - target(p_target) { - } - - SharedObject() {} -}; - -class EditorExportPlatform : public RefCounted { - GDCLASS(EditorExportPlatform, RefCounted); - -public: - typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); - typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so); - - enum ExportMessageType { - EXPORT_MESSAGE_NONE, - EXPORT_MESSAGE_INFO, - EXPORT_MESSAGE_WARNING, - EXPORT_MESSAGE_ERROR, - }; - - struct ExportMessage { - ExportMessageType msg_type; - String category; - String text; - }; - -private: - struct SavedData { - uint64_t ofs = 0; - uint64_t size = 0; - bool encrypted = false; - Vector<uint8_t> md5; - CharString path_utf8; - - bool operator<(const SavedData &p_data) const { - return path_utf8 < p_data.path_utf8; - } - }; - - struct PackData { - Ref<FileAccess> f; - Vector<SavedData> file_ofs; - EditorProgress *ep = nullptr; - Vector<SharedObject> *so_files = nullptr; - }; - - struct ZipData { - void *zip = nullptr; - EditorProgress *ep = nullptr; - }; - - struct FeatureContainers { - HashSet<String> features; - Vector<String> features_pv; - }; - - Vector<ExportMessage> messages; - - void _export_find_resources(EditorFileSystemDirectory *p_dir, HashSet<String> &p_paths); - void _export_find_dependencies(const String &p_path, HashSet<String> &p_paths); - - void gen_debug_flags(Vector<String> &r_flags, int p_flags); - static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); - static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); - - void _edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, HashSet<String> &r_list, bool exclude); - void _edit_filter_list(HashSet<String> &r_list, const String &p_filter, bool exclude); - - static Error _add_shared_object(void *p_userdata, const SharedObject &p_so); - -protected: - struct ExportNotifier { - ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); - ~ExportNotifier(); - }; - - FeatureContainers get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug); - - bool exists_export_template(String template_file_name, String *err) const; - String find_export_template(String template_file_name, String *err = nullptr) const; - void gen_export_flags(Vector<String> &r_flags, int p_flags); - -public: - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) = 0; - - struct ExportOption { - PropertyInfo option; - Variant default_value; - - ExportOption(const PropertyInfo &p_info, const Variant &p_default) : - option(p_info), - default_value(p_default) { - } - ExportOption() {} - }; - - virtual Ref<EditorExportPreset> create_preset(); - - virtual void clear_messages() { messages.clear(); } - virtual void add_message(ExportMessageType p_type, const String &p_category, const String &p_message) { - ExportMessage msg; - msg.category = p_category; - msg.text = p_message; - msg.msg_type = p_type; - messages.push_back(msg); - switch (p_type) { - case EXPORT_MESSAGE_INFO: { - print_line(vformat("%s: %s\n", msg.category, msg.text)); - } break; - case EXPORT_MESSAGE_WARNING: { - WARN_PRINT(vformat("%s: %s\n", msg.category, msg.text)); - } break; - case EXPORT_MESSAGE_ERROR: { - ERR_PRINT(vformat("%s: %s\n", msg.category, msg.text)); - } break; - default: - break; - } - } - - virtual int get_message_count() const { - return messages.size(); - } - - virtual ExportMessage get_message(int p_index) const { - ERR_FAIL_INDEX_V(p_index, messages.size(), ExportMessage()); - return messages[p_index]; - } - - virtual ExportMessageType get_worst_message_type() const { - ExportMessageType worst_type = EXPORT_MESSAGE_NONE; - for (int i = 0; i < messages.size(); i++) { - worst_type = MAX(worst_type, messages[i].msg_type); - } - return worst_type; - } - - virtual bool fill_log_messages(RichTextLabel *p_log, Error p_err); - - virtual void get_export_options(List<ExportOption> *r_options) = 0; - virtual bool should_update_export_options() { return false; } - virtual bool get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const { return true; } - - virtual String get_os_name() const = 0; - virtual String get_name() const = 0; - virtual Ref<Texture2D> get_logo() const = 0; - - Error export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr); - - Error save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr); - Error save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); - - virtual bool poll_export() { return false; } - virtual int get_options_count() const { return 0; } - virtual String get_options_tooltip() const { return ""; } - virtual Ref<ImageTexture> get_option_icon(int p_index) const; - virtual String get_option_label(int p_device) const { return ""; } - virtual String get_option_tooltip(int p_device) const { return ""; } - - enum DebugFlags { - DEBUG_FLAG_DUMB_CLIENT = 1, - DEBUG_FLAG_REMOTE_DEBUG = 2, - DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST = 4, - DEBUG_FLAG_VIEW_COLLISONS = 8, - DEBUG_FLAG_VIEW_NAVIGATION = 16, - }; - - virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { return OK; } - virtual Ref<Texture2D> get_run_icon() const { return get_logo(); } - - String test_etc2() const; - virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const = 0; - - virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const = 0; - virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) = 0; - virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); - virtual Error export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); - virtual void get_platform_features(List<String> *r_features) = 0; - virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) = 0; - virtual String get_debug_protocol() const { return "tcp://"; } - - EditorExportPlatform(); -}; - -class EditorExportPlugin : public RefCounted { - GDCLASS(EditorExportPlugin, RefCounted); - - friend class EditorExportPlatform; - - Ref<EditorExportPreset> export_preset; - - Vector<SharedObject> shared_objects; - struct ExtraFile { - String path; - Vector<uint8_t> data; - bool remap = false; - }; - Vector<ExtraFile> extra_files; - bool skipped = false; - - Vector<String> ios_frameworks; - Vector<String> ios_embedded_frameworks; - Vector<String> ios_project_static_libs; - String ios_plist_content; - String ios_linker_flags; - Vector<String> ios_bundle_files; - String ios_cpp_code; - - Vector<String> macos_plugin_files; - - _FORCE_INLINE_ void _clear() { - shared_objects.clear(); - extra_files.clear(); - skipped = false; - } - - _FORCE_INLINE_ void _export_end() { - ios_frameworks.clear(); - ios_embedded_frameworks.clear(); - ios_bundle_files.clear(); - ios_plist_content = ""; - ios_linker_flags = ""; - ios_cpp_code = ""; - macos_plugin_files.clear(); - } - - void _export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features); - void _export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags); - void _export_end_script(); - -protected: - void set_export_preset(const Ref<EditorExportPreset> &p_preset); - Ref<EditorExportPreset> get_export_preset() const; - - void add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap); - void add_shared_object(const String &p_path, const Vector<String> &tags, const String &p_target = String()); - - void add_ios_framework(const String &p_path); - void add_ios_embedded_framework(const String &p_path); - void add_ios_project_static_lib(const String &p_path); - void add_ios_plist_content(const String &p_plist_content); - void add_ios_linker_flags(const String &p_flags); - void add_ios_bundle_file(const String &p_path); - void add_ios_cpp_code(const String &p_code); - void add_macos_plugin_file(const String &p_path); - - void skip(); - - virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features); - virtual void _export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags); - - static void _bind_methods(); - - GDVIRTUAL3(_export_file, String, String, Vector<String>) - GDVIRTUAL4(_export_begin, Vector<String>, bool, String, uint32_t) - GDVIRTUAL0(_export_end) - -public: - Vector<String> get_ios_frameworks() const; - Vector<String> get_ios_embedded_frameworks() const; - Vector<String> get_ios_project_static_libs() const; - String get_ios_plist_content() const; - String get_ios_linker_flags() const; - Vector<String> get_ios_bundle_files() const; - String get_ios_cpp_code() const; - const Vector<String> &get_macos_plugin_files() const; - - EditorExportPlugin(); -}; - -class EditorExport : public Node { - GDCLASS(EditorExport, Node); - - Vector<Ref<EditorExportPlatform>> export_platforms; - Vector<Ref<EditorExportPreset>> export_presets; - Vector<Ref<EditorExportPlugin>> export_plugins; - - StringName _export_presets_updated; - - Timer *save_timer = nullptr; - bool block_save = false; - - static EditorExport *singleton; - - void _save(); - -protected: - friend class EditorExportPreset; - void save_presets(); - - void _notification(int p_what); - static void _bind_methods(); - -public: - static EditorExport *get_singleton() { return singleton; } - - void add_export_platform(const Ref<EditorExportPlatform> &p_platform); - int get_export_platform_count(); - Ref<EditorExportPlatform> get_export_platform(int p_idx); - - void add_export_preset(const Ref<EditorExportPreset> &p_preset, int p_at_pos = -1); - int get_export_preset_count() const; - Ref<EditorExportPreset> get_export_preset(int p_idx); - void remove_export_preset(int p_idx); - - void add_export_plugin(const Ref<EditorExportPlugin> &p_plugin); - void remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin); - Vector<Ref<EditorExportPlugin>> get_export_plugins(); - - void load_config(); - void update_export_presets(); - bool poll_export_platforms(); - - EditorExport(); - ~EditorExport(); -}; - -class EditorExportPlatformPC : public EditorExportPlatform { - GDCLASS(EditorExportPlatformPC, EditorExportPlatform); - -private: - Ref<ImageTexture> logo; - String name; - String os_name; - - int chmod_flags = -1; - -public: - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override; - - virtual void get_export_options(List<ExportOption> *r_options) override; - - virtual String get_name() const override; - virtual String get_os_name() const override; - virtual Ref<Texture2D> get_logo() const override; - - virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; - virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; - virtual Error sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); - virtual String get_template_file_name(const String &p_target, const String &p_arch) const = 0; - - virtual Error prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); - virtual Error modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { return OK; }; - virtual Error export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); - - void set_extension(const String &p_extension, const String &p_feature_key = "default"); - void set_name(const String &p_name); - void set_os_name(const String &p_name); - - void set_logo(const Ref<Texture2D> &p_logo); - - void add_platform_feature(const String &p_feature); - virtual void get_platform_features(List<String> *r_features) override; - virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override; - - int get_chmod_flags() const; - void set_chmod_flags(int p_flags); - - virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { - return Error::OK; - } -}; - -class EditorExportTextSceneToBinaryPlugin : public EditorExportPlugin { - GDCLASS(EditorExportTextSceneToBinaryPlugin, EditorExportPlugin); - -public: - virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) override; - EditorExportTextSceneToBinaryPlugin(); -}; - -#endif // EDITOR_EXPORT_H diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index 9e2d56b2b9..f0bf9fd5b3 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -34,6 +34,7 @@ #include "core/io/json.h" #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" #include "editor/editor_property_name_processor.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" @@ -314,7 +315,7 @@ void EditorFeatureProfileManager::_notification(int p_what) { current_profile = EDITOR_GET("_default_feature_profile"); if (!current_profile.is_empty()) { current.instantiate(); - Error err = current->load_from_file(EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(current_profile + ".profile")); + Error err = current->load_from_file(EditorPaths::get_singleton()->get_feature_profiles_dir().plus_file(current_profile + ".profile")); if (err != OK) { ERR_PRINT("Error loading default feature profile: " + current_profile); current_profile = String(); @@ -323,6 +324,11 @@ void EditorFeatureProfileManager::_notification(int p_what) { } _update_profile_list(current_profile); } break; + + case NOTIFICATION_THEME_CHANGED: { + // Make sure that the icons are correctly adjusted if the theme's lightness was switched. + _update_selected_profile(); + } break; } } @@ -340,7 +346,7 @@ void EditorFeatureProfileManager::_update_profile_list(const String &p_select_pr if (p_select_profile.is_empty()) { //default, keep if (profile_list->get_selected() >= 0) { selected_profile = profile_list->get_item_metadata(profile_list->get_selected()); - if (!FileAccess::exists(EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(selected_profile + ".profile"))) { + if (!FileAccess::exists(EditorPaths::get_singleton()->get_feature_profiles_dir().plus_file(selected_profile + ".profile"))) { selected_profile = String(); //does not exist } } @@ -349,8 +355,8 @@ void EditorFeatureProfileManager::_update_profile_list(const String &p_select_pr } Vector<String> profiles; - Ref<DirAccess> d = DirAccess::open(EditorSettings::get_singleton()->get_feature_profiles_dir()); - ERR_FAIL_COND_MSG(d.is_null(), "Cannot open directory '" + EditorSettings::get_singleton()->get_feature_profiles_dir() + "'."); + Ref<DirAccess> d = DirAccess::open(EditorPaths::get_singleton()->get_feature_profiles_dir()); + ERR_FAIL_COND_MSG(d.is_null(), "Cannot open directory '" + EditorPaths::get_singleton()->get_feature_profiles_dir() + "'."); d->list_dir_begin(); while (true) { @@ -452,8 +458,8 @@ void EditorFeatureProfileManager::_profile_action(int p_action) { void EditorFeatureProfileManager::_erase_selected_profile() { String selected = _get_selected_profile(); ERR_FAIL_COND(selected.is_empty()); - Ref<DirAccess> da = DirAccess::open(EditorSettings::get_singleton()->get_feature_profiles_dir()); - ERR_FAIL_COND_MSG(da.is_null(), "Cannot open directory '" + EditorSettings::get_singleton()->get_feature_profiles_dir() + "'."); + Ref<DirAccess> da = DirAccess::open(EditorPaths::get_singleton()->get_feature_profiles_dir()); + ERR_FAIL_COND_MSG(da.is_null(), "Cannot open directory '" + EditorPaths::get_singleton()->get_feature_profiles_dir() + "'."); da->remove(selected + ".profile"); if (selected == current_profile) { @@ -469,7 +475,7 @@ void EditorFeatureProfileManager::_create_new_profile() { EditorNode::get_singleton()->show_warning(TTR("Profile must be a valid filename and must not contain '.'")); return; } - String file = EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(name + ".profile"); + String file = EditorPaths::get_singleton()->get_feature_profiles_dir().plus_file(name + ".profile"); if (FileAccess::exists(file)) { EditorNode::get_singleton()->show_warning(TTR("Profile with this name already exists.")); return; @@ -748,8 +754,8 @@ void EditorFeatureProfileManager::_update_selected_profile() { } else { //reload edited, if different from current edited.instantiate(); - Error err = edited->load_from_file(EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(profile + ".profile")); - ERR_FAIL_COND_MSG(err != OK, "Error when loading EditorSettings from file '" + EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(profile + ".profile") + "'."); + Error err = edited->load_from_file(EditorPaths::get_singleton()->get_feature_profiles_dir().plus_file(profile + ".profile")); + ERR_FAIL_COND_MSG(err != OK, "Error when loading editor feature profile from file '" + EditorPaths::get_singleton()->get_feature_profiles_dir().plus_file(profile + ".profile") + "'."); } updating_features = true; @@ -804,7 +810,7 @@ void EditorFeatureProfileManager::_import_profiles(const Vector<String> &p_paths return; } - String dst_file = EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(basefile); + String dst_file = EditorPaths::get_singleton()->get_feature_profiles_dir().plus_file(basefile); if (FileAccess::exists(dst_file)) { EditorNode::get_singleton()->show_warning(vformat(TTR("Profile '%s' already exists. Remove it first before importing, import aborted."), basefile.get_basename())); @@ -819,7 +825,7 @@ void EditorFeatureProfileManager::_import_profiles(const Vector<String> &p_paths Error err = profile->load_from_file(p_paths[i]); ERR_CONTINUE(err != OK); String basefile = p_paths[i].get_file(); - String dst_file = EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(basefile); + String dst_file = EditorPaths::get_singleton()->get_feature_profiles_dir().plus_file(basefile); profile->save_to_file(dst_file); } @@ -843,7 +849,7 @@ void EditorFeatureProfileManager::_save_and_update() { ERR_FAIL_COND(edited_path.is_empty()); ERR_FAIL_COND(edited.is_null()); - edited->save_to_file(EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(edited_path + ".profile")); + edited->save_to_file(EditorPaths::get_singleton()->get_feature_profiles_dir().plus_file(edited_path + ".profile")); if (edited == current) { update_timer->start(); @@ -883,7 +889,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { profile_actions[PROFILE_CLEAR] = memnew(Button(TTR("Reset to Default"))); name_hbc->add_child(profile_actions[PROFILE_CLEAR]); profile_actions[PROFILE_CLEAR]->set_disabled(true); - profile_actions[PROFILE_CLEAR]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_CLEAR)); + profile_actions[PROFILE_CLEAR]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action).bind(PROFILE_CLEAR)); main_vbc->add_margin_child(TTR("Current Profile:"), name_hbc); @@ -897,12 +903,12 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { profile_actions[PROFILE_NEW] = memnew(Button(TTR("Create Profile"))); profiles_hbc->add_child(profile_actions[PROFILE_NEW]); - profile_actions[PROFILE_NEW]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_NEW)); + profile_actions[PROFILE_NEW]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action).bind(PROFILE_NEW)); profile_actions[PROFILE_ERASE] = memnew(Button(TTR("Remove Profile"))); profiles_hbc->add_child(profile_actions[PROFILE_ERASE]); profile_actions[PROFILE_ERASE]->set_disabled(true); - profile_actions[PROFILE_ERASE]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_ERASE)); + profile_actions[PROFILE_ERASE]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action).bind(PROFILE_ERASE)); main_vbc->add_margin_child(TTR("Available Profiles:"), profiles_hbc); @@ -911,18 +917,18 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { profile_actions[PROFILE_SET] = memnew(Button(TTR("Make Current"))); current_profile_hbc->add_child(profile_actions[PROFILE_SET]); profile_actions[PROFILE_SET]->set_disabled(true); - profile_actions[PROFILE_SET]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_SET)); + profile_actions[PROFILE_SET]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action).bind(PROFILE_SET)); current_profile_hbc->add_child(memnew(VSeparator)); profile_actions[PROFILE_IMPORT] = memnew(Button(TTR("Import"))); current_profile_hbc->add_child(profile_actions[PROFILE_IMPORT]); - profile_actions[PROFILE_IMPORT]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_IMPORT)); + profile_actions[PROFILE_IMPORT]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action).bind(PROFILE_IMPORT)); profile_actions[PROFILE_EXPORT] = memnew(Button(TTR("Export"))); current_profile_hbc->add_child(profile_actions[PROFILE_EXPORT]); profile_actions[PROFILE_EXPORT]->set_disabled(true); - profile_actions[PROFILE_EXPORT]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_EXPORT)); + profile_actions[PROFILE_EXPORT]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action).bind(PROFILE_EXPORT)); main_vbc->add_child(current_profile_hbc); @@ -939,7 +945,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { class_list->set_hide_root(true); class_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); class_list->connect("cell_selected", callable_mp(this, &EditorFeatureProfileManager::_class_list_item_selected)); - class_list->connect("item_edited", callable_mp(this, &EditorFeatureProfileManager::_class_list_item_edited), varray(), CONNECT_DEFERRED); + class_list->connect("item_edited", callable_mp(this, &EditorFeatureProfileManager::_class_list_item_edited), CONNECT_DEFERRED); class_list->connect("item_collapsed", callable_mp(this, &EditorFeatureProfileManager::_class_list_item_collapsed)); // It will be displayed once the user creates or chooses a profile. class_list_vbc->hide(); @@ -957,7 +963,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { property_list->set_hide_root(true); property_list->set_hide_folding(true); property_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); - property_list->connect("item_edited", callable_mp(this, &EditorFeatureProfileManager::_property_item_edited), varray(), CONNECT_DEFERRED); + property_list->connect("item_edited", callable_mp(this, &EditorFeatureProfileManager::_property_item_edited), CONNECT_DEFERRED); // It will be displayed once the user creates or chooses a profile. property_list_vbc->hide(); diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 9f446ab38f..2f1134e8ef 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -1681,7 +1681,7 @@ EditorFileDialog::EditorFileDialog() { mode_thumbnails = memnew(Button); mode_thumbnails->set_flat(true); - mode_thumbnails->connect("pressed", callable_mp(this, &EditorFileDialog::set_display_mode), varray(DISPLAY_THUMBNAILS)); + mode_thumbnails->connect("pressed", callable_mp(this, &EditorFileDialog::set_display_mode).bind(DISPLAY_THUMBNAILS)); mode_thumbnails->set_toggle_mode(true); mode_thumbnails->set_pressed(display_mode == DISPLAY_THUMBNAILS); mode_thumbnails->set_button_group(view_mode_group); @@ -1690,7 +1690,7 @@ EditorFileDialog::EditorFileDialog() { mode_list = memnew(Button); mode_list->set_flat(true); - mode_list->connect("pressed", callable_mp(this, &EditorFileDialog::set_display_mode), varray(DISPLAY_LIST)); + mode_list->connect("pressed", callable_mp(this, &EditorFileDialog::set_display_mode).bind(DISPLAY_LIST)); mode_list->set_toggle_mode(true); mode_list->set_pressed(display_mode == DISPLAY_LIST); mode_list->set_button_group(view_mode_group); @@ -1816,9 +1816,9 @@ EditorFileDialog::EditorFileDialog() { _update_drives(); connect("confirmed", callable_mp(this, &EditorFileDialog::_action_pressed)); - item_list->connect("item_selected", callable_mp(this, &EditorFileDialog::_item_selected), varray(), CONNECT_DEFERRED); - item_list->connect("multi_selected", callable_mp(this, &EditorFileDialog::_multi_selected), varray(), CONNECT_DEFERRED); - item_list->connect("item_activated", callable_mp(this, &EditorFileDialog::_item_dc_selected), varray()); + item_list->connect("item_selected", callable_mp(this, &EditorFileDialog::_item_selected), CONNECT_DEFERRED); + item_list->connect("multi_selected", callable_mp(this, &EditorFileDialog::_multi_selected), CONNECT_DEFERRED); + item_list->connect("item_activated", callable_mp(this, &EditorFileDialog::_item_dc_selected).bind()); item_list->connect("empty_clicked", callable_mp(this, &EditorFileDialog::_items_clear_selection)); dir->connect("text_submitted", callable_mp(this, &EditorFileDialog::_dir_submitted)); file->connect("text_submitted", callable_mp(this, &EditorFileDialog::_file_submitted)); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 56046a07d7..1a105c7fe8 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -40,6 +40,7 @@ #include "core/os/os.h" #include "core/variant/variant_parser.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" #include "editor/editor_resource_preview.h" #include "editor/editor_settings.h" @@ -218,7 +219,7 @@ void EditorFileSystem::_scan_filesystem() { String project = ProjectSettings::get_singleton()->get_resource_path(); - String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME); + String fscache = EditorPaths::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME); { Ref<FileAccess> f = FileAccess::open(fscache, FileAccess::READ); @@ -288,7 +289,7 @@ void EditorFileSystem::_scan_filesystem() { } } - String update_cache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4"); + String update_cache = EditorPaths::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4"); if (FileAccess::exists(update_cache)) { { @@ -331,7 +332,7 @@ void EditorFileSystem::_scan_filesystem() { void EditorFileSystem::_save_filesystem_cache() { group_file_cache.clear(); - String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME); + String fscache = EditorPaths::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME); Ref<FileAccess> f = FileAccess::open(fscache, FileAccess::WRITE); ERR_FAIL_COND_MSG(f.is_null(), "Cannot create file '" + fscache + "'. Check user write permissions."); @@ -1456,7 +1457,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p void EditorFileSystem::_save_late_updated_files() { //files that already existed, and were modified, need re-scanning for dependencies upon project restart. This is done via saving this special file - String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4"); + String fscache = EditorPaths::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4"); Ref<FileAccess> f = FileAccess::open(fscache, FileAccess::WRITE); ERR_FAIL_COND_MSG(f.is_null(), "Cannot create file '" + fscache + "'. Check user write permissions."); for (const String &E : late_update_files) { diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp index 8c508494c0..c1d6e505db 100644 --- a/editor/editor_folding.cpp +++ b/editor/editor_folding.cpp @@ -30,9 +30,10 @@ #include "editor_folding.h" +#include "core/io/config_file.h" #include "core/io/file_access.h" #include "editor/editor_inspector.h" -#include "editor/editor_settings.h" +#include "editor/editor_paths.h" Vector<String> EditorFolding::_get_unfolds(const Object *p_object) { Vector<String> sections; @@ -55,7 +56,7 @@ void EditorFolding::save_resource_folding(const Ref<Resource> &p_resource, const config->set_value("folding", "sections_unfolded", unfolds); String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg"; - file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file); + file = EditorPaths::get_singleton()->get_project_settings_dir().plus_file(file); config->save(file); } @@ -73,7 +74,7 @@ void EditorFolding::load_resource_folding(Ref<Resource> p_resource, const String config.instantiate(); String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg"; - file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file); + file = EditorPaths::get_singleton()->get_project_settings_dir().plus_file(file); if (config->load(file) != OK) { return; @@ -149,7 +150,7 @@ void EditorFolding::save_scene_folding(const Node *p_scene, const String &p_path config->set_value("folding", "nodes_folded", nodes_folded); String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg"; - file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file); + file = EditorPaths::get_singleton()->get_project_settings_dir().plus_file(file); config->save(file); } @@ -157,9 +158,9 @@ void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) { Ref<ConfigFile> config; config.instantiate(); - String path = EditorSettings::get_singleton()->get_project_settings_dir(); + String path = EditorPaths::get_singleton()->get_project_settings_dir(); String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg"; - file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file); + file = EditorPaths::get_singleton()->get_project_settings_dir().plus_file(file); if (config->load(file) != OK) { return; @@ -213,7 +214,7 @@ void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) { bool EditorFolding::has_folding_data(const String &p_path) { String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg"; - file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file); + file = EditorPaths::get_singleton()->get_project_settings_dir().plus_file(file); return FileAccess::exists(file); } diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 68141dd4a3..5c3038c468 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -2089,7 +2089,7 @@ EditorHelp::EditorHelp() { class_desc->connect("finished", callable_mp(this, &EditorHelp::_class_desc_finished)); class_desc->connect("meta_clicked", callable_mp(this, &EditorHelp::_class_desc_select)); class_desc->connect("gui_input", callable_mp(this, &EditorHelp::_class_desc_input)); - class_desc->connect("resized", callable_mp(this, &EditorHelp::_class_desc_resized), varray(false)); + class_desc->connect("resized", callable_mp(this, &EditorHelp::_class_desc_resized).bind(false)); _class_desc_resized(false); // Added second so it opens at the bottom so it won't offset the entire widget. diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index c48b443a0b..297d1226e3 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -34,6 +34,7 @@ #include "editor/editor_feature_profile.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" void EditorHelpSearch::_update_icons() { search_box->set_right_icon(results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); @@ -250,7 +251,7 @@ EditorHelpSearch::EditorHelpSearch() { results_tree->set_hide_root(true); results_tree->set_select_mode(Tree::SELECT_ROW); results_tree->connect("item_activated", callable_mp(this, &EditorHelpSearch::_confirmed)); - results_tree->connect("item_selected", callable_mp((BaseButton *)get_ok_button(), &BaseButton::set_disabled), varray(false)); + results_tree->connect("item_selected", callable_mp((BaseButton *)get_ok_button(), &BaseButton::set_disabled).bind(false)); vbox->add_child(results_tree, true); } diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index b610e09545..2064b6f3a1 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -471,6 +471,9 @@ void EditorProperty::update_revert_and_pin_status() { bool new_can_revert = EditorPropertyRevert::can_property_revert(object, property, ¤t) && !is_read_only(); if (new_can_revert != can_revert || new_pinned != pinned) { + if (new_can_revert != can_revert) { + emit_signal(SNAME("property_can_revert_changed"), property, new_can_revert); + } can_revert = new_can_revert; pinned = new_pinned; update(); @@ -554,7 +557,7 @@ void EditorProperty::_focusable_focused(int p_index) { } void EditorProperty::add_focusable(Control *p_control) { - p_control->connect("focus_entered", callable_mp(this, &EditorProperty::_focusable_focused), varray(focusables.size())); + p_control->connect("focus_entered", callable_mp(this, &EditorProperty::_focusable_focused).bind(focusables.size())); focusables.push_back(p_control); } @@ -784,6 +787,9 @@ void EditorProperty::expand_all_folding() { void EditorProperty::collapse_all_folding() { } +void EditorProperty::expand_revertable() { +} + void EditorProperty::set_selectable(bool p_selectable) { selectable = p_selectable; } @@ -966,6 +972,7 @@ void EditorProperty::_bind_methods() { ADD_SIGNAL(MethodInfo("property_keyed_with_value", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "checked"))); ADD_SIGNAL(MethodInfo("property_pinned", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "pinned"))); + ADD_SIGNAL(MethodInfo("property_can_revert_changed", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "can_revert"))); ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "focusable_idx"))); @@ -1225,12 +1232,15 @@ void EditorInspectorSection::_notification(int p_what) { // Get the section header font. Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")); + Color font_color = get_theme_color(SNAME("font_color"), SNAME("Editor")); // Get the right direction arrow texture, if the section is foldable. Ref<Texture2D> arrow; + bool folded = foldable; if (foldable) { if (object->editor_is_section_unfolded(section)) { arrow = get_theme_icon(SNAME("arrow"), SNAME("Tree")); + folded = false; } else { if (is_layout_rtl()) { arrow = get_theme_icon(SNAME("arrow_collapsed_mirrored"), SNAME("Tree")); @@ -1274,28 +1284,71 @@ void EditorInspectorSection::_notification(int p_what) { } draw_rect(header_rect, c); - // Draw header title and folding arrow. - const int arrow_margin = 2; - const int arrow_width = arrow.is_valid() ? arrow->get_width() : 0; - Color color = get_theme_color(SNAME("font_color")); - float text_width = get_size().width - Math::round(arrow_width + arrow_margin * EDSCALE) - section_indent; - Point2 text_offset = Point2(0, font->get_ascent(font_size) + (header_height - font->get_height(font_size)) / 2); - HorizontalAlignment text_align = HORIZONTAL_ALIGNMENT_LEFT; - if (rtl) { - text_align = HORIZONTAL_ALIGNMENT_RIGHT; - } else { - text_offset.x = section_indent + Math::round(arrow_width + arrow_margin * EDSCALE); - } - draw_string(font, text_offset.floor(), label, text_align, text_width, font_size, color); + // Draw header title, folding arrow and coutn of revertable properties. + { + int separation = Math::round(2 * EDSCALE); - if (arrow.is_valid()) { - Point2 arrow_position = Point2(0, (header_height - arrow->get_height()) / 2); + int margin_start = section_indent + separation; + int margin_end = separation; + + // - Arrow. + if (arrow.is_valid()) { + Point2 arrow_position; + if (rtl) { + arrow_position.x = get_size().width - (margin_start + arrow->get_width()); + } else { + arrow_position.x = margin_start; + } + arrow_position.y = (header_height - arrow->get_height()) / 2; + draw_texture(arrow, arrow_position); + margin_start += arrow->get_width(); + } + + int available = get_size().width - (margin_start + margin_end); + + // - Count of revertable properties. + String num_revertable_str; + int num_revertable_width = 0; + if (folded && revertable_properties.size()) { + int label_width = font->get_string_size(label, HORIZONTAL_ALIGNMENT_LEFT, available, font_size, TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS).x; + + Ref<Font> light_font = get_theme_font(SNAME("main"), SNAME("EditorFonts")); + int light_font_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts")); + Color light_font_color = get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")); + + // Can we fit the long version of the revertable count text? + if (revertable_properties.size() == 1) { + num_revertable_str = "(1 change)"; + } else { + num_revertable_str = vformat("(%d changes)", revertable_properties.size()); + } + num_revertable_width = light_font->get_string_size(num_revertable_str, HORIZONTAL_ALIGNMENT_LEFT, -1.0f, light_font_size, TextServer::JUSTIFICATION_NONE).x; + if (label_width + separation + num_revertable_width > available) { + // We'll have to use the short version. + num_revertable_str = vformat("(%d)", revertable_properties.size()); + num_revertable_width = light_font->get_string_size(num_revertable_str, HORIZONTAL_ALIGNMENT_LEFT, -1.0f, light_font_size, TextServer::JUSTIFICATION_NONE).x; + } + + Point2 text_offset = Point2( + margin_end, + light_font->get_ascent(light_font_size) + (header_height - light_font->get_height(light_font_size)) / 2); + if (!rtl) { + text_offset.x = get_size().width - (text_offset.x + num_revertable_width); + } + draw_string(light_font, text_offset, num_revertable_str, HORIZONTAL_ALIGNMENT_LEFT, -1.0f, light_font_size, light_font_color, TextServer::JUSTIFICATION_NONE); + margin_end += num_revertable_width + separation; + available -= num_revertable_width + separation; + } + + // - Label. + Point2 text_offset = Point2( + margin_start, + font->get_ascent(font_size) + (header_height - font->get_height(font_size)) / 2); if (rtl) { - arrow_position.x = get_size().width - section_indent - arrow->get_width() - Math::round(arrow_margin * EDSCALE); - } else { - arrow_position.x = section_indent + Math::round(arrow_margin * EDSCALE); + text_offset.x = margin_end; } - draw_texture(arrow, arrow_position.floor()); + HorizontalAlignment text_align = rtl ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT; + draw_string(font, text_offset, label, text_align, available, font_size, font_color, TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS); } // Draw dropping highlight. @@ -1471,6 +1524,22 @@ void EditorInspectorSection::fold() { update(); } +bool EditorInspectorSection::has_revertable_properties() const { + return !revertable_properties.is_empty(); +} + +void EditorInspectorSection::property_can_revert_changed(const String &p_path, bool p_can_revert) { + bool had_revertable_properties = has_revertable_properties(); + if (p_can_revert) { + revertable_properties.insert(p_path); + } else { + revertable_properties.erase(p_path); + } + if (has_revertable_properties() != had_revertable_properties) { + update(); + } +} + void EditorInspectorSection::_bind_methods() { ClassDB::bind_method(D_METHOD("setup", "section", "label", "object", "bg_color", "foldable"), &EditorInspectorSection::setup); ClassDB::bind_method(D_METHOD("get_vbox"), &EditorInspectorSection::get_vbox); @@ -1544,12 +1613,11 @@ void EditorInspectorArray::_rmb_popup_id_pressed(int p_id) { _clear_array(); break; case OPTION_RESIZE_ARRAY: - new_size = count; - new_size_line_edit->set_text(Variant(new_size)); + new_size_spin_box->set_value(count); resize_dialog->get_ok_button()->set_disabled(true); - resize_dialog->popup_centered(); - new_size_line_edit->grab_focus(); - new_size_line_edit->select_all(); + resize_dialog->popup_centered(Size2i(250, 0) * EDSCALE); + new_size_spin_box->get_line_edit()->grab_focus(); + new_size_spin_box->get_line_edit()->select_all(); break; default: break; @@ -1608,7 +1676,7 @@ void EditorInspectorArray::_panel_gui_input(Ref<InputEvent> p_event, int p_index Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == MouseButton::RIGHT) { + if (movable && mb->get_button_index() == MouseButton::RIGHT) { popup_array_index_pressed = begin_array_index + p_index; rmb_popup->set_item_disabled(OPTION_MOVE_UP, popup_array_index_pressed == 0); rmb_popup->set_item_disabled(OPTION_MOVE_DOWN, popup_array_index_pressed == count - 1); @@ -1637,49 +1705,118 @@ void EditorInspectorArray::_move_element(int p_element_index, int p_to_pos) { const Variant *args_p[] = { &args[0], &args[1], &args[2], &args[3], &args[4] }; Variant return_value; Callable::CallError call_error; - move_function.call(args_p, 5, return_value, call_error); + move_function.callp(args_p, 5, return_value, call_error); } else { WARN_PRINT(vformat("Could not find a function to move arrays elements for class %s. Register a move element function using EditorData::add_move_array_element_function", object->get_class_name())); } } else if (mode == MODE_USE_COUNT_PROPERTY) { ERR_FAIL_COND(p_to_pos < -1 || p_to_pos > count); - List<PropertyInfo> object_property_list; - object->get_property_list(&object_property_list); - Array properties_as_array = _extract_properties_as_array(object_property_list); - properties_as_array.resize(count); + if (!swap_method.is_empty()) { + ERR_FAIL_COND(!object->has_method(swap_method)); - // For undoing things - undo_redo->add_undo_property(object, count_property, properties_as_array.size()); - for (int i = 0; i < (int)properties_as_array.size(); i++) { - Dictionary d = Dictionary(properties_as_array[i]); - Array keys = d.keys(); - for (int j = 0; j < keys.size(); j++) { - String key = keys[j]; - undo_redo->add_undo_property(object, vformat(key, i), d[key]); - } - } + // Swap method was provided, use it. + if (p_element_index < 0) { + // Add an element at position + undo_redo->add_do_property(object, count_property, count + 1); + if (p_to_pos >= 0) { + for (int i = count; i > p_to_pos; i--) { + undo_redo->add_do_method(object, swap_method, i, i - 1); + } + for (int i = p_to_pos; i < count; i++) { + undo_redo->add_undo_method(object, swap_method, i, i + 1); + } + } + undo_redo->add_undo_property(object, count_property, count); + + } else if (p_to_pos < 0) { + if (count > 0) { + // Remove element at position + undo_redo->add_undo_property(object, count_property, count); + + List<PropertyInfo> object_property_list; + object->get_property_list(&object_property_list); - if (p_element_index < 0) { - // Add an element. - properties_as_array.insert(p_to_pos < 0 ? properties_as_array.size() : p_to_pos, Dictionary()); - } else if (p_to_pos < 0) { - // Delete the element. - properties_as_array.remove_at(p_element_index); + for (int i = p_element_index; i < count - 1; i++) { + undo_redo->add_do_method(object, swap_method, i, i + 1); + } + + for (int i = count; i > p_element_index; i--) { + undo_redo->add_undo_method(object, swap_method, i, i - 1); + } + + String erase_prefix = String(array_element_prefix) + itos(p_element_index); + + for (const PropertyInfo &E : object_property_list) { + if (E.name.begins_with(erase_prefix)) { + undo_redo->add_undo_property(object, E.name, object->get(E.name)); + } + } + + undo_redo->add_do_property(object, count_property, count - 1); + } + } else { + if (p_to_pos > p_element_index) { + p_to_pos--; + } + + if (p_to_pos < p_element_index) { + for (int i = p_element_index; i > p_to_pos; i--) { + undo_redo->add_do_method(object, swap_method, i, i - 1); + } + for (int i = p_to_pos; i < p_element_index; i++) { + undo_redo->add_undo_method(object, swap_method, i, i + 1); + } + } else if (p_to_pos > p_element_index) { + for (int i = p_element_index; i < p_to_pos; i++) { + undo_redo->add_do_method(object, swap_method, i, i + 1); + } + + for (int i = p_to_pos; i > p_element_index; i--) { + undo_redo->add_undo_method(object, swap_method, i, i - 1); + } + } + } } else { - // Move the element. - properties_as_array.insert(p_to_pos, properties_as_array[p_element_index].duplicate()); - properties_as_array.remove_at(p_to_pos < p_element_index ? p_element_index + 1 : p_element_index); - } + // Use standard properties. + List<PropertyInfo> object_property_list; + object->get_property_list(&object_property_list); - // Change the array size then set the properties. - undo_redo->add_do_property(object, count_property, properties_as_array.size()); - for (int i = 0; i < (int)properties_as_array.size(); i++) { - Dictionary d = properties_as_array[i]; - Array keys = d.keys(); - for (int j = 0; j < keys.size(); j++) { - String key = keys[j]; - undo_redo->add_do_property(object, vformat(key, i), d[key]); + Array properties_as_array = _extract_properties_as_array(object_property_list); + properties_as_array.resize(count); + + // For undoing things + undo_redo->add_undo_property(object, count_property, properties_as_array.size()); + for (int i = 0; i < (int)properties_as_array.size(); i++) { + Dictionary d = Dictionary(properties_as_array[i]); + Array keys = d.keys(); + for (int j = 0; j < keys.size(); j++) { + String key = keys[j]; + undo_redo->add_undo_property(object, vformat(key, i), d[key]); + } + } + + if (p_element_index < 0) { + // Add an element. + properties_as_array.insert(p_to_pos < 0 ? properties_as_array.size() : p_to_pos, Dictionary()); + } else if (p_to_pos < 0) { + // Delete the element. + properties_as_array.remove_at(p_element_index); + } else { + // Move the element. + properties_as_array.insert(p_to_pos, properties_as_array[p_element_index].duplicate()); + properties_as_array.remove_at(p_to_pos < p_element_index ? p_element_index + 1 : p_element_index); + } + + // Change the array size then set the properties. + undo_redo->add_do_property(object, count_property, properties_as_array.size()); + for (int i = 0; i < (int)properties_as_array.size(); i++) { + Dictionary d = properties_as_array[i]; + Array keys = d.keys(); + for (int j = 0; j < keys.size(); j++) { + String key = keys[j]; + undo_redo->add_do_property(object, vformat(key, i), d[key]); + } } } } @@ -1712,7 +1849,7 @@ void EditorInspectorArray::_clear_array() { const Variant *args_p[] = { &args[0], &args[1], &args[2], &args[3], &args[4] }; Variant return_value; Callable::CallError call_error; - move_function.call(args_p, 5, return_value, call_error); + move_function.callp(args_p, 5, return_value, call_error); } else { WARN_PRINT(vformat("Could not find a function to move arrays elements for class %s. Register a move element function using EditorData::add_move_array_element_function", object->get_class_name())); } @@ -1765,7 +1902,7 @@ void EditorInspectorArray::_resize_array(int p_size) { const Variant *args_p[] = { &args[0], &args[1], &args[2], &args[3], &args[4] }; Variant return_value; Callable::CallError call_error; - move_function.call(args_p, 5, return_value, call_error); + move_function.callp(args_p, 5, return_value, call_error); } else { WARN_PRINT(vformat("Could not find a function to move arrays elements for class %s. Register a move element function using EditorData::add_move_array_element_function", object->get_class_name())); } @@ -1784,7 +1921,7 @@ void EditorInspectorArray::_resize_array(int p_size) { const Variant *args_p[] = { &args[0], &args[1], &args[2], &args[3], &args[4] }; Variant return_value; Callable::CallError call_error; - move_function.call(args_p, 5, return_value, call_error); + move_function.callp(args_p, 5, return_value, call_error); } else { WARN_PRINT(vformat("Could not find a function to move arrays elements for class %s. Register a move element function using EditorData::add_move_array_element_function", object->get_class_name())); } @@ -1875,36 +2012,21 @@ int EditorInspectorArray::_drop_position() const { return -1; } -void EditorInspectorArray::_new_size_line_edit_text_changed(String p_text) { - bool valid = false; - if (p_text.is_valid_int()) { - int val = p_text.to_int(); - if (val > 0 && val != count) { - valid = true; - } +void EditorInspectorArray::_resize_dialog_confirmed() { + if (int(new_size_spin_box->get_value()) == count) { + return; } - resize_dialog->get_ok_button()->set_disabled(!valid); + + resize_dialog->hide(); + _resize_array(int(new_size_spin_box->get_value())); } -void EditorInspectorArray::_new_size_line_edit_text_submitted(String p_text) { - bool valid = false; - if (p_text.is_valid_int()) { - int val = p_text.to_int(); - if (val > 0 && val != count) { - new_size = val; - valid = true; - } - } - if (valid) { - resize_dialog->hide(); - _resize_array(new_size); - } else { - new_size_line_edit->set_text(Variant(new_size)); - } +void EditorInspectorArray::_new_size_spin_box_value_changed(float p_value) { + resize_dialog->get_ok_button()->set_disabled(int(p_value) == count); } -void EditorInspectorArray::_resize_dialog_confirmed() { - _new_size_line_edit_text_submitted(new_size_line_edit->get_text()); +void EditorInspectorArray::_new_size_spin_box_text_submitted(String p_text) { + _resize_dialog_confirmed(); } void EditorInspectorArray::_setup() { @@ -1919,6 +2041,20 @@ void EditorInspectorArray::_setup() { page = CLAMP(page, 0, max_page); } + Ref<Font> numbers_font; + int numbers_min_w = 0; + + if (numbered) { + numbers_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + int digits_found = count; + String test; + while (digits_found) { + test += "8"; + digits_found /= 10; + } + numbers_min_w = numbers_font->get_string_size(test).width; + } + for (int i = 0; i < (int)array_elements.size(); i++) { ArrayElement &ae = array_elements[i]; @@ -1931,8 +2067,8 @@ void EditorInspectorArray::_setup() { ae.panel->set_tooltip(vformat(TTR("Element %d: %s%d*"), i, array_element_prefix, i)); ae.panel->connect("focus_entered", callable_mp((CanvasItem *)ae.panel, &PanelContainer::update)); ae.panel->connect("focus_exited", callable_mp((CanvasItem *)ae.panel, &PanelContainer::update)); - ae.panel->connect("draw", callable_bind(callable_mp(this, &EditorInspectorArray::_panel_draw), i)); - ae.panel->connect("gui_input", callable_bind(callable_mp(this, &EditorInspectorArray::_panel_gui_input), i)); + ae.panel->connect("draw", callable_mp(this, &EditorInspectorArray::_panel_draw).bind(i)); + ae.panel->connect("gui_input", callable_mp(this, &EditorInspectorArray::_panel_gui_input).bind(i)); ae.panel->add_theme_style_override(SNAME("panel"), i % 2 ? odd_style : even_style); elements_vbox->add_child(ae.panel); @@ -1953,19 +2089,38 @@ void EditorInspectorArray::_setup() { ae.margin->add_child(ae.hbox); // Move button. - ae.move_texture_rect = memnew(TextureRect); - ae.move_texture_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); - ae.move_texture_rect->set_default_cursor_shape(Control::CURSOR_MOVE); - if (is_inside_tree()) { - ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons"))); + if (movable) { + ae.move_texture_rect = memnew(TextureRect); + ae.move_texture_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); + ae.move_texture_rect->set_default_cursor_shape(Control::CURSOR_MOVE); + + if (is_inside_tree()) { + ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons"))); + } + ae.hbox->add_child(ae.move_texture_rect); + } + + if (numbered) { + ae.number = memnew(Label); + ae.number->add_theme_font_override("font", numbers_font); + ae.number->set_custom_minimum_size(Size2(numbers_min_w, 0)); + ae.number->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); + ae.number->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); + ae.number->set_text(itos(begin_array_index + i)); + ae.hbox->add_child(ae.number); } - ae.hbox->add_child(ae.move_texture_rect); // Right vbox. ae.vbox = memnew(VBoxContainer); ae.vbox->set_h_size_flags(SIZE_EXPAND_FILL); ae.vbox->set_v_size_flags(SIZE_EXPAND_FILL); ae.hbox->add_child(ae.vbox); + + ae.erase = memnew(Button); + ae.erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); + ae.erase->set_v_size_flags(SIZE_SHRINK_CENTER); + ae.erase->connect("pressed", callable_mp(this, &EditorInspectorArray::_remove_item).bind(begin_array_index + i)); + ae.hbox->add_child(ae.erase); } // Hide/show the add button. @@ -1980,7 +2135,14 @@ void EditorInspectorArray::_setup() { } } +void EditorInspectorArray::_remove_item(int p_index) { + _move_element(p_index, -1); +} + Variant EditorInspectorArray::get_drag_data_fw(const Point2 &p_point, Control *p_from) { + if (!movable) { + return Variant(); + } int index = p_from->get_meta("index"); Dictionary dict; dict["type"] = "property_array_element"; @@ -2002,6 +2164,9 @@ void EditorInspectorArray::drop_data_fw(const Point2 &p_point, const Variant &p_ } bool EditorInspectorArray::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + if (!movable) { + return false; + } // First, update drawing. control_dropping->update(); @@ -2026,18 +2191,24 @@ void EditorInspectorArray::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { Color color = get_theme_color(SNAME("dark_color_1"), SNAME("Editor")); - odd_style->set_bg_color(color.lightened(0.15)); - even_style->set_bg_color(color.darkened(0.15)); + odd_style->set_bg_color(color.darkened(-0.08)); + even_style->set_bg_color(color.darkened(0.08)); for (int i = 0; i < (int)array_elements.size(); i++) { ArrayElement &ae = array_elements[i]; - ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons"))); + if (ae.move_texture_rect) { + ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons"))); + } Size2 min_size = get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles"))->get_minimum_size(); ae.margin->add_theme_constant_override("margin_left", min_size.x / 2); ae.margin->add_theme_constant_override("margin_top", min_size.y / 2); ae.margin->add_theme_constant_override("margin_right", min_size.x / 2); ae.margin->add_theme_constant_override("margin_bottom", min_size.y / 2); + + if (ae.erase) { + ae.erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); + } } add_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); @@ -2073,23 +2244,31 @@ void EditorInspectorArray::set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; } -void EditorInspectorArray::setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable) { +void EditorInspectorArray::setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable, bool p_numbered, int p_page_length, const String &p_add_item_text) { count_property = ""; mode = MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION; array_element_prefix = p_array_element_prefix; page = p_page; + movable = p_movable; + page_length = p_page_length; + numbered = p_numbered; EditorInspectorSection::setup(String(p_array_element_prefix) + "_array", p_label, p_object, p_bg_color, p_foldable, 0); _setup(); } -void EditorInspectorArray::setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable) { +void EditorInspectorArray::setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable, bool p_numbered, int p_page_length, const String &p_add_item_text, const String &p_swap_method) { count_property = p_count_property; mode = MODE_USE_COUNT_PROPERTY; array_element_prefix = p_array_element_prefix; page = p_page; + movable = p_movable; + page_length = p_page_length; + numbered = p_numbered; + swap_method = p_swap_method; + add_button->set_text(p_add_item_text); EditorInspectorSection::setup(String(count_property) + "_array", p_label, p_object, p_bg_color, p_foldable, 0); _setup(); @@ -2147,10 +2326,11 @@ EditorInspectorArray::EditorInspectorArray() { VBoxContainer *resize_dialog_vbox = memnew(VBoxContainer); resize_dialog->add_child(resize_dialog_vbox); - new_size_line_edit = memnew(LineEdit); - new_size_line_edit->connect("text_changed", callable_mp(this, &EditorInspectorArray::_new_size_line_edit_text_changed)); - new_size_line_edit->connect("text_submitted", callable_mp(this, &EditorInspectorArray::_new_size_line_edit_text_submitted)); - resize_dialog_vbox->add_margin_child(TTRC("New Size:"), new_size_line_edit); + new_size_spin_box = memnew(SpinBox); + new_size_spin_box->set_max(16384); + new_size_spin_box->connect("value_changed", callable_mp(this, &EditorInspectorArray::_new_size_spin_box_value_changed)); + new_size_spin_box->get_line_edit()->connect("text_submitted", callable_mp(this, &EditorInspectorArray::_new_size_spin_box_text_submitted)); + resize_dialog_vbox->add_margin_child(TTRC("New Size:"), new_size_spin_box); vbox->connect("visibility_changed", callable_mp(this, &EditorInspectorArray::_vbox_visibility_changed)); } @@ -2330,7 +2510,7 @@ String EditorInspector::get_selected_path() const { return property_selected; } -void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<EditorInspectorPlugin> ped) { +void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, EditorInspectorSection *p_section, Ref<EditorInspectorPlugin> ped) { for (const EditorInspectorPlugin::AddedEditor &F : ped->added_editors) { EditorProperty *ep = Object::cast_to<EditorProperty>(F.property_editor); current_vbox->add_child(F.property_editor); @@ -2339,14 +2519,14 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit ep->object = object; ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed)); ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed)); - ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED); + ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), CONNECT_DEFERRED); ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked)); ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned)); ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed)); - ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED); - ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), varray(), CONNECT_DEFERRED); + ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), CONNECT_DEFERRED); + ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), CONNECT_DEFERRED); if (F.properties.size()) { if (F.properties.size() == 1) { @@ -2370,6 +2550,10 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit } } + if (p_section) { + ep->connect("property_can_revert_changed", callable_mp(p_section, &EditorInspectorSection::property_can_revert_changed)); + } + ep->set_read_only(read_only); ep->update_property(); ep->_update_pin_flags(); @@ -2466,7 +2650,6 @@ void EditorInspector::update_tree() { List<PropertyInfo> plist; object->get_property_list(&plist, true); - _update_script_class_properties(*object, plist); HashMap<VBoxContainer *, HashMap<String, VBoxContainer *>> vbox_per_path; HashMap<String, EditorInspectorArray *> editor_inspector_array_per_prefix; @@ -2476,9 +2659,11 @@ void EditorInspector::update_tree() { // Get the lists of editors to add the beginning. for (Ref<EditorInspectorPlugin> &ped : valid_plugins) { ped->parse_begin(object); - _parse_added_editors(main_vbox, ped); + _parse_added_editors(main_vbox, nullptr, ped); } + StringName type_name; + // Get the lists of editors for properties. for (List<PropertyInfo>::Element *E_property = plist.front(); E_property; E_property = E_property->next()) { PropertyInfo &p = E_property->get(); @@ -2549,17 +2734,24 @@ void EditorInspector::update_tree() { category_vbox = nullptr; //reset String type = p.name; + String label = p.name; + type_name = p.name; // Set the category icon. if (!ClassDB::class_exists(type) && !ScriptServer::is_global_class(type) && p.hint_string.length() && FileAccess::exists(p.hint_string)) { // If we have a category inside a script, search for the first script with a valid icon. Ref<Script> script = ResourceLoader::load(p.hint_string, "Script"); StringName base_type; + StringName name; if (script.is_valid()) { base_type = script->get_instance_base_type(); + name = EditorNode::get_editor_data().script_class_get_name(script->get_path()); + if (name != StringName() && label != name) { + label = name; + } } while (script.is_valid()) { - StringName name = EditorNode::get_editor_data().script_class_get_name(script->get_path()); + name = EditorNode::get_editor_data().script_class_get_name(script->get_path()); String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name); if (name != StringName() && icon_path.length()) { category->icon = ResourceLoader::load(icon_path, "Texture"); @@ -2578,28 +2770,27 @@ void EditorInspector::update_tree() { } // Set the category label. - category->label = type; + category->label = label; if (use_doc_hints) { // Sets the category tooltip to show documentation. - StringName type2 = p.name; - if (!class_descr_cache.has(type2)) { + if (!class_descr_cache.has(type_name)) { String descr; DocTools *dd = EditorHelp::get_doc_data(); - HashMap<String, DocData::ClassDoc>::Iterator E = dd->class_list.find(type2); + HashMap<String, DocData::ClassDoc>::Iterator E = dd->class_list.find(type_name); if (E) { descr = DTR(E->value.brief_description); } - class_descr_cache[type2] = descr; + class_descr_cache[type_name] = descr; } - category->set_tooltip(p.name + "::" + (class_descr_cache[type2].is_empty() ? "" : class_descr_cache[type2])); + category->set_tooltip(p.name + "::" + (class_descr_cache[type_name].is_empty() ? "" : class_descr_cache[type_name])); } // Add editors at the start of a category. for (Ref<EditorInspectorPlugin> &ped : valid_plugins) { ped->parse_category(object, p.name); - _parse_added_editors(main_vbox, ped); + _parse_added_editors(main_vbox, nullptr, ped); } continue; @@ -2791,7 +2982,7 @@ void EditorInspector::update_tree() { // Add editors at the start of a group. for (Ref<EditorInspectorPlugin> &ped : valid_plugins) { ped->parse_group(object, path); - _parse_added_editors(section->get_vbox(), ped); + _parse_added_editors(section->get_vbox(), section, ped); } vbox_per_path[root_vbox][acc_path] = section->get_vbox(); @@ -2812,26 +3003,52 @@ void EditorInspector::update_tree() { StringName array_element_prefix; Color c = sscolor; c.a /= level; + + Vector<String> class_name_components = String(p.class_name).split(","); + + int page_size = 5; + bool movable = true; + bool numbered = false; + bool foldable = use_folding; + String add_button_text; + String swap_method; + for (int i = (p.type == Variant::NIL ? 1 : 2); i < class_name_components.size(); i++) { + if (class_name_components[i].begins_with("page_size") && class_name_components[i].get_slice_count("=") == 2) { + page_size = class_name_components[i].get_slice("=", 1).to_int(); + } else if (class_name_components[i].begins_with("add_button_text") && class_name_components[i].get_slice_count("=") == 2) { + add_button_text = class_name_components[i].get_slice("=", 1).strip_edges(); + } else if (class_name_components[i] == "static") { + movable = false; + } else if (class_name_components[i] == "numbered") { + numbered = true; + } else if (class_name_components[i] == "unfoldable") { + foldable = false; + } else if (class_name_components[i].begins_with("swap_method") && class_name_components[i].get_slice_count("=") == 2) { + swap_method = class_name_components[i].get_slice("=", 1).strip_edges(); + } + } + if (p.type == Variant::NIL) { // Setup the array to use a method to create/move/delete elements. - array_element_prefix = p.class_name; + array_element_prefix = class_name_components[0]; editor_inspector_array = memnew(EditorInspectorArray); String array_label = path.contains("/") ? path.substr(path.rfind("/") + 1) : path; array_label = EditorPropertyNameProcessor::get_singleton()->process_name(property_label_string, property_name_style); int page = per_array_page.has(array_element_prefix) ? per_array_page[array_element_prefix] : 0; editor_inspector_array->setup_with_move_element_function(object, array_label, array_element_prefix, page, c, use_folding); - editor_inspector_array->connect("page_change_request", callable_mp(this, &EditorInspector::_page_change_request), varray(array_element_prefix)); + editor_inspector_array->connect("page_change_request", callable_mp(this, &EditorInspector::_page_change_request).bind(array_element_prefix)); editor_inspector_array->set_undo_redo(undo_redo); } else if (p.type == Variant::INT) { // Setup the array to use the count property and built-in functions to create/move/delete elements. - Vector<String> class_name_components = String(p.class_name).split(","); - if (class_name_components.size() == 2) { + if (class_name_components.size() >= 2) { array_element_prefix = class_name_components[1]; editor_inspector_array = memnew(EditorInspectorArray); int page = per_array_page.has(array_element_prefix) ? per_array_page[array_element_prefix] : 0; - editor_inspector_array->setup_with_count_property(object, class_name_components[0], p.name, array_element_prefix, page, c, use_folding); - editor_inspector_array->connect("page_change_request", callable_mp(this, &EditorInspector::_page_change_request), varray(array_element_prefix)); + + editor_inspector_array->setup_with_count_property(object, class_name_components[0], p.name, array_element_prefix, page, c, foldable, movable, numbered, page_size, add_button_text, swap_method); + editor_inspector_array->connect("page_change_request", callable_mp(this, &EditorInspector::_page_change_request).bind(array_element_prefix)); + editor_inspector_array->set_undo_redo(undo_redo); } } @@ -2840,6 +3057,7 @@ void EditorInspector::update_tree() { current_vbox->add_child(editor_inspector_array); editor_inspector_array_per_prefix[array_element_prefix] = editor_inspector_array; } + continue; } @@ -2864,7 +3082,7 @@ void EditorInspector::update_tree() { // Build the doc hint, to use as tooltip. // Get the class name. - StringName classname = object->get_class_name(); + StringName classname = type_name == "" ? object->get_class_name() : type_name; if (!object_class.is_empty()) { classname = object_class; } @@ -2973,6 +3191,12 @@ void EditorInspector::update_tree() { editor_property_map[prop].push_back(ep); } } + + EditorInspectorSection *section = Object::cast_to<EditorInspectorSection>(current_vbox->get_parent()); + if (section) { + ep->connect("property_can_revert_changed", callable_mp(section, &EditorInspectorSection::property_can_revert_changed)); + } + ep->set_draw_warning(draw_warning); ep->set_use_folding(use_folding); ep->set_checkable(checkable); @@ -2987,16 +3211,16 @@ void EditorInspector::update_tree() { if (ep) { // Eventually, set other properties/signals after the property editor got added to the tree. bool update_all = (p.usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED); - ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed), varray(update_all)); + ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed).bind(update_all)); ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed)); - ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED); + ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), CONNECT_DEFERRED); ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked)); ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned)); ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed)); - ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED); - ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), varray(), CONNECT_DEFERRED); + ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), CONNECT_DEFERRED); + ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), CONNECT_DEFERRED); if (!doc_info.description.is_empty()) { ep->set_tooltip(property_prefix + p.name + "::" + doc_info.description); } else { @@ -3016,6 +3240,11 @@ void EditorInspector::update_tree() { } if (!hide_metadata) { + // Add 4px of spacing between the "Add Metadata" button and the content above it. + Control *spacer = memnew(Control); + spacer->set_custom_minimum_size(Size2(0, 4) * EDSCALE); + main_vbox->add_child(spacer); + Button *add_md = EditorInspector::create_inspector_action_button(TTR("Add Metadata")); add_md->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_md->connect(SNAME("pressed"), callable_mp(this, &EditorInspector::_show_add_meta_dialog)); @@ -3025,7 +3254,7 @@ void EditorInspector::update_tree() { // Get the lists of to add at the end. for (Ref<EditorInspectorPlugin> &ped : valid_plugins) { ped->parse_end(object); - _parse_added_editors(main_vbox, ped); + _parse_added_editors(main_vbox, nullptr, ped); } } @@ -3178,6 +3407,44 @@ void EditorInspector::expand_all_folding() { } } +void EditorInspector::expand_revertable() { + HashSet<EditorInspectorSection *> sections_to_unfold[2]; + for (EditorInspectorSection *E : sections) { + if (E->has_revertable_properties()) { + sections_to_unfold[0].insert(E); + } + } + + // Climb up the hierachy doing double buffering with the sets. + int a = 0; + int b = 1; + while (sections_to_unfold[a].size()) { + for (EditorInspectorSection *E : sections_to_unfold[a]) { + E->unfold(); + + Node *n = E->get_parent(); + while (n) { + if (Object::cast_to<EditorInspector>(n)) { + break; + } + if (Object::cast_to<EditorInspectorSection>(n) && !sections_to_unfold[a].has((EditorInspectorSection *)n)) { + sections_to_unfold[b].insert((EditorInspectorSection *)n); + } + n = n->get_parent(); + } + } + + sections_to_unfold[a].clear(); + SWAP(a, b); + } + + for (const KeyValue<StringName, List<EditorProperty *>> &F : editor_property_map) { + for (EditorProperty *E : F.value) { + E->expand_revertable(); + } + } +} + void EditorInspector::set_scroll_offset(int p_offset) { set_v_scroll(p_offset); } @@ -3277,14 +3544,23 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo undo_redo->add_undo_property(object, p_name, value); } - 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) { - valid = false; - value = object->get(linked_prop, &valid); - if (valid) { - undo_redo->add_undo_property(object, linked_prop, value); - } + List<StringName> linked_properties; + ClassDB::get_linked_properties_info(object->get_class_name(), p_name, &linked_properties); + + for (const StringName &linked_prop : linked_properties) { + valid = false; + Variant undo_value = object->get(linked_prop, &valid); + if (valid) { + undo_redo->add_undo_property(object, linked_prop, undo_value); + } + } + + PackedStringArray linked_properties_dynamic = object->call("_get_linked_undo_properties", p_name, p_value); + for (int i = 0; i < linked_properties_dynamic.size(); i++) { + valid = false; + Variant undo_value = object->get(linked_properties_dynamic[i], &valid); + if (valid) { + undo_redo->add_undo_property(object, linked_properties_dynamic[i], undo_value); } } @@ -3298,7 +3574,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo Variant return_value; Callable::CallError call_error; - callback.call(p_arguments, 4, return_value, call_error); + callback.callp(p_arguments, 4, return_value, call_error); if (call_error.error != Callable::CallError::CALL_OK) { ERR_PRINT("Invalid UndoRedo callback."); } @@ -3640,88 +3916,6 @@ void EditorInspector::_feature_profile_changed() { update_tree(); } -void EditorInspector::_update_script_class_properties(const Object &p_object, List<PropertyInfo> &r_list) const { - Ref<Script> script = p_object.get_script(); - if (script.is_null()) { - return; - } - - List<Ref<Script>> classes; - - // NodeC -> NodeB -> NodeA - while (script.is_valid()) { - classes.push_front(script); - script = script->get_base_script(); - } - - if (classes.is_empty()) { - return; - } - - // Script Variables -> to insert: NodeC..B..A -> bottom (insert_here) - List<PropertyInfo>::Element *script_variables = nullptr; - List<PropertyInfo>::Element *bottom = nullptr; - List<PropertyInfo>::Element *insert_here = nullptr; - for (List<PropertyInfo>::Element *E = r_list.front(); E; E = E->next()) { - PropertyInfo &pi = E->get(); - if (pi.name != "Script Variables") { - continue; - } - script_variables = E; - bottom = r_list.insert_after(script_variables, PropertyInfo()); - insert_here = bottom; - break; - } - - HashSet<StringName> added; - for (const Ref<Script> &s : classes) { - String path = s->get_path(); - String name = EditorNode::get_editor_data().script_class_get_name(path); - if (name.is_empty()) { - if (s->is_built_in()) { - if (s->get_name().is_empty()) { - name = TTR("Built-in script"); - } else { - name = vformat("%s (%s)", s->get_name(), TTR("Built-in")); - } - } else { - name = path.get_file(); - } - } - - List<PropertyInfo> props; - s->get_script_property_list(&props); - - // Script Variables -> NodeA -> bottom (insert_here) - List<PropertyInfo>::Element *category = r_list.insert_before(insert_here, PropertyInfo(Variant::NIL, name, PROPERTY_HINT_NONE, path, PROPERTY_USAGE_CATEGORY)); - - // Script Variables -> NodeA -> A props... -> bottom (insert_here) - for (List<PropertyInfo>::Element *P = props.front(); P; P = P->next()) { - PropertyInfo &pi = P->get(); - if (added.has(pi.name)) { - continue; - } - added.insert(pi.name); - - r_list.insert_before(insert_here, pi); - } - - // Script Variables -> NodeA (insert_here) -> A props... -> bottom - insert_here = category; - } - - // NodeC -> C props... -> NodeB..C.. - if (script_variables) { - r_list.erase(script_variables); - List<PropertyInfo>::Element *to_delete = bottom->next(); - while (to_delete && !(to_delete->get().usage & PROPERTY_USAGE_CATEGORY)) { - r_list.erase(to_delete); - to_delete = bottom->next(); - } - r_list.erase(bottom); - } -} - void EditorInspector::set_restrict_to_basic_settings(bool p_restrict) { restrict_to_basic = p_restrict; update_tree(); diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 4ec3513da5..baba9ec1f4 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -39,6 +39,7 @@ #include "scene/gui/option_button.h" #include "scene/gui/panel_container.h" #include "scene/gui/scroll_container.h" +#include "scene/gui/spin_box.h" #include "scene/gui/texture_rect.h" class UndoRedo; @@ -184,6 +185,7 @@ public: virtual void expand_all_folding(); virtual void collapse_all_folding(); + virtual void expand_revertable(); virtual Variant get_drag_data(const Point2 &p_point) override; virtual void update_cache(); @@ -281,6 +283,8 @@ class EditorInspectorSection : public Container { Timer *dropping_unfold_timer = nullptr; bool dropping = false; + HashSet<StringName> revertable_properties; + void _test_unfold(); protected: @@ -299,6 +303,9 @@ public: void unfold(); void fold(); + bool has_revertable_properties() const; + void property_can_revert_changed(const String &p_path, bool p_can_revert); + EditorInspectorSection(); ~EditorInspectorSection(); }; @@ -315,6 +322,7 @@ class EditorInspectorArray : public EditorInspectorSection { } mode; StringName count_property; StringName array_element_prefix; + String swap_method; int count = 0; @@ -326,8 +334,7 @@ class EditorInspectorArray : public EditorInspectorSection { Button *add_button = nullptr; AcceptDialog *resize_dialog = nullptr; - int new_size = 0; - LineEdit *new_size_line_edit = nullptr; + SpinBox *new_size_spin_box = nullptr; // Pagination int page_length = 5; @@ -336,6 +343,9 @@ class EditorInspectorArray : public EditorInspectorSection { int begin_array_index = 0; int end_array_index = 0; + bool movable = true; + bool numbered = false; + enum MenuOptions { OPTION_MOVE_UP = 0, OPTION_MOVE_DOWN, @@ -353,7 +363,9 @@ class EditorInspectorArray : public EditorInspectorSection { MarginContainer *margin = nullptr; HBoxContainer *hbox = nullptr; TextureRect *move_texture_rect = nullptr; + Label *number = nullptr; VBoxContainer *vbox = nullptr; + Button *erase = nullptr; }; LocalVector<ArrayElement> array_elements; @@ -378,8 +390,8 @@ class EditorInspectorArray : public EditorInspectorSection { Array _extract_properties_as_array(const List<PropertyInfo> &p_list); int _drop_position() const; - void _new_size_line_edit_text_changed(String p_text); - void _new_size_line_edit_text_submitted(String p_text); + void _new_size_spin_box_value_changed(float p_value); + void _new_size_spin_box_text_submitted(String p_text); void _resize_dialog_confirmed(); void _update_elements_visibility(); @@ -389,6 +401,8 @@ class EditorInspectorArray : public EditorInspectorSection { void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + void _remove_item(int p_index); + protected: void _notification(int p_what); static void _bind_methods(); @@ -396,8 +410,8 @@ protected: public: void set_undo_redo(UndoRedo *p_undo_redo); - void setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable); - void setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable); + void setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable = true, bool p_numbered = false, int p_page_length = 5, const String &p_add_item_text = ""); + void setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable = true, bool p_numbered = false, int p_page_length = 5, const String &p_add_item_text = "", const String &p_swap_method = ""); VBoxContainer *get_vbox(int p_index); EditorInspectorArray(); @@ -517,12 +531,11 @@ class EditorInspector : public ScrollContainer { void _edit_request_change(Object *p_object, const String &p_prop); void _filter_changed(const String &p_text); - void _parse_added_editors(VBoxContainer *current_vbox, Ref<EditorInspectorPlugin> ped); + void _parse_added_editors(VBoxContainer *current_vbox, EditorInspectorSection *p_section, Ref<EditorInspectorPlugin> ped); void _vscroll_changed(double); void _feature_profile_changed(); - void _update_script_class_properties(const Object &p_object, List<PropertyInfo> &r_list) const; bool _is_property_disabled_by_feature_profile(const StringName &p_property); @@ -579,6 +592,7 @@ public: void collapse_all_folding(); void expand_all_folding(); + void expand_revertable(); void set_scroll_offset(int p_offset); int get_scroll_offset() const; diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index f26f47dbc7..38cc85bb4e 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -33,8 +33,11 @@ #include "core/os/keyboard.h" #include "core/version.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/gui/center_container.h" +#include "scene/gui/separator.h" #include "scene/resources/font.h" void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type) { @@ -122,7 +125,7 @@ void EditorLog::_save_state() { Ref<ConfigFile> config; config.instantiate(); // Load and amend existing config if it exists. - config->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); + config->load(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); const String section = "editor_log"; for (const KeyValue<MessageType, LogFilter *> &E : type_filter_map) { @@ -132,7 +135,7 @@ void EditorLog::_save_state() { config->set_value(section, "collapse", collapse); config->set_value(section, "show_search", search_box->is_visible()); - config->save(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); + config->save(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); } void EditorLog::_load_state() { @@ -140,7 +143,7 @@ void EditorLog::_load_state() { Ref<ConfigFile> config; config.instantiate(); - config->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); + config->load(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); // Run the below code even if config->load returns an error, since we want the defaults to be set even if the file does not exist yet. const String section = "editor_log"; diff --git a/editor/editor_log.h b/editor/editor_log.h index 653fba9524..003a148b9b 100644 --- a/editor/editor_log.h +++ b/editor/editor_log.h @@ -88,7 +88,7 @@ private: toggle_button->add_theme_color_override("icon_color_pressed", Color(1, 1, 1, 1)); toggle_button->set_focus_mode(FOCUS_NONE); // When toggled call the callback and pass the MessageType this button is for. - toggle_button->connect("toggled", p_toggled_callback, varray(type)); + toggle_button->connect("toggled", p_toggled_callback.bind(type)); } int get_message_count() { diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e7957b6fd1..e7946f56da 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -49,6 +49,7 @@ #include "main/main.h" #include "scene/3d/importer_mesh_instance_3d.h" #include "scene/gui/center_container.h" +#include "scene/gui/color_picker.h" #include "scene/gui/control.h" #include "scene/gui/dialogs.h" #include "scene/gui/file_dialog.h" @@ -78,7 +79,6 @@ #include "editor/editor_build_profile.h" #include "editor/editor_command_palette.h" #include "editor/editor_data.h" -#include "editor/editor_export.h" #include "editor/editor_feature_profile.h" #include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" @@ -104,7 +104,9 @@ #include "editor/editor_themes.h" #include "editor/editor_toaster.h" #include "editor/editor_translation_parser.h" -#include "editor/export_template_manager.h" +#include "editor/export/editor_export.h" +#include "editor/export/export_template_manager.h" +#include "editor/export/project_export.h" #include "editor/filesystem_dock.h" #include "editor/import/audio_stream_import_settings.h" #include "editor/import/dynamic_font_import_settings.h" @@ -139,6 +141,7 @@ #include "editor/plugins/bone_map_editor_plugin.h" #include "editor/plugins/camera_3d_editor_plugin.h" #include "editor/plugins/canvas_item_editor_plugin.h" +#include "editor/plugins/cast_2d_editor_plugin.h" #include "editor/plugins/collision_polygon_2d_editor_plugin.h" #include "editor/plugins/collision_shape_2d_editor_plugin.h" #include "editor/plugins/control_editor_plugin.h" @@ -148,6 +151,7 @@ #include "editor/plugins/debugger_editor_plugin.h" #include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/editor_preview_plugins.h" +#include "editor/plugins/editor_resource_conversion_plugin.h" #include "editor/plugins/font_config_plugin.h" #include "editor/plugins/gdextension_export_plugin.h" #include "editor/plugins/gpu_particles_2d_editor_plugin.h" @@ -173,8 +177,6 @@ #include "editor/plugins/physical_bone_3d_editor_plugin.h" #include "editor/plugins/polygon_2d_editor_plugin.h" #include "editor/plugins/polygon_3d_editor_plugin.h" -#include "editor/plugins/ray_cast_2d_editor_plugin.h" -#include "editor/plugins/replication_editor_plugin.h" #include "editor/plugins/resource_preloader_editor_plugin.h" #include "editor/plugins/root_motion_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" @@ -199,7 +201,6 @@ #include "editor/plugins/visual_shader_editor_plugin.h" #include "editor/plugins/voxel_gi_editor_plugin.h" #include "editor/progress_dialog.h" -#include "editor/project_export.h" #include "editor/project_settings_editor.h" #include "editor/register_exporters.h" #include "editor/scene_tree_dock.h" @@ -553,6 +554,19 @@ void EditorNode::_update_from_settings() { tree->set_debug_collision_contact_color(GLOBAL_GET("debug/shapes/collision/contact_color")); tree->set_debug_navigation_color(GLOBAL_GET("debug/shapes/navigation/geometry_color")); tree->set_debug_navigation_disabled_color(GLOBAL_GET("debug/shapes/navigation/disabled_geometry_color")); + +#ifdef DEBUG_ENABLED + NavigationServer3D::get_singleton_mut()->set_debug_navigation_edge_connection_color(GLOBAL_GET("debug/shapes/navigation/edge_connection_color")); + NavigationServer3D::get_singleton_mut()->set_debug_navigation_geometry_edge_color(GLOBAL_GET("debug/shapes/navigation/geometry_edge_color")); + NavigationServer3D::get_singleton_mut()->set_debug_navigation_geometry_face_color(GLOBAL_GET("debug/shapes/navigation/geometry_face_color")); + NavigationServer3D::get_singleton_mut()->set_debug_navigation_geometry_edge_disabled_color(GLOBAL_GET("debug/shapes/navigation/geometry_edge_disabled_color")); + NavigationServer3D::get_singleton_mut()->set_debug_navigation_geometry_face_disabled_color(GLOBAL_GET("debug/shapes/navigation/geometry_face_disabled_color")); + NavigationServer3D::get_singleton_mut()->set_debug_navigation_enable_edge_connections(GLOBAL_GET("debug/shapes/navigation/enable_edge_connections")); + NavigationServer3D::get_singleton_mut()->set_debug_navigation_enable_edge_connections_xray(GLOBAL_GET("debug/shapes/navigation/enable_edge_connections_xray")); + NavigationServer3D::get_singleton_mut()->set_debug_navigation_enable_edge_lines(GLOBAL_GET("debug/shapes/navigation/enable_edge_lines")); + NavigationServer3D::get_singleton_mut()->set_debug_navigation_enable_edge_lines_xray(GLOBAL_GET("debug/shapes/navigation/enable_edge_lines_xray")); + NavigationServer3D::get_singleton_mut()->set_debug_navigation_enable_geometry_face_random_color(GLOBAL_GET("debug/shapes/navigation/enable_geometry_face_random_color")); +#endif // DEBUG_ENABLED } void EditorNode::_select_default_main_screen_plugin() { @@ -1035,7 +1049,7 @@ void EditorNode::_sources_changed(bool p_exist) { // Reload the global shader variables, but this time // loading textures, as they are now properly imported. - RenderingServer::get_singleton()->global_variables_load_settings(true); + RenderingServer::get_singleton()->global_shader_uniforms_load_settings(true); // Start preview thread now that it's safe. if (!singleton->cmdline_export_mode) { @@ -1213,7 +1227,7 @@ void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const St } String path = ProjectSettings::get_singleton()->localize_path(p_path); - Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); + Error err = ResourceSaver::save(p_resource, path, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); if (err != OK) { if (ResourceLoader::is_imported(p_resource->get_path())) { @@ -1364,7 +1378,7 @@ void EditorNode::_get_scene_metadata(const String &p_file) { return; } - String path = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg"); + String path = EditorPaths::get_singleton()->get_project_settings_dir().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg"); Ref<ConfigFile> cf; cf.instantiate(); @@ -1396,7 +1410,7 @@ void EditorNode::_set_scene_metadata(const String &p_file, int p_idx) { return; } - String path = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg"); + String path = EditorPaths::get_singleton()->get_project_settings_dir().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg"); Ref<ConfigFile> cf; cf.instantiate(); @@ -1436,7 +1450,7 @@ bool EditorNode::_find_and_save_resource(Ref<Resource> p_res, HashMap<Ref<Resour if (p_res->get_path().is_resource_file()) { if (changed || subchanged) { - ResourceSaver::save(p_res->get_path(), p_res, flags); + ResourceSaver::save(p_res, p_res->get_path(), flags); } processed[p_res] = false; // Because it's a file. return false; @@ -1667,7 +1681,7 @@ int EditorNode::_save_external_resources() { if (ps.is_valid()) { continue; // Do not save PackedScenes, this will mess up the editor. } - ResourceSaver::save(res->get_path(), res, flg); + ResourceSaver::save(res, res->get_path(), flg); saved++; } @@ -1738,7 +1752,7 @@ void EditorNode::_save_scene(String p_file, int idx) { } flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; - err = ResourceSaver::save(p_file, sdata, flg); + err = ResourceSaver::save(sdata, p_file, flg); // This needs to be emitted before saving external resources. emit_signal(SNAME("scene_saved"), p_file); @@ -1945,7 +1959,7 @@ void EditorNode::_dialog_action(String p_file) { MeshLibraryEditor::update_library_file(editor_data.get_edited_scene_root(), ml, true, file_export_lib_apply_xforms->is_pressed()); - Error err = ResourceSaver::save(p_file, ml); + Error err = ResourceSaver::save(ml, p_file); if (err) { show_accept(TTR("Error saving MeshLibrary!"), TTR("OK")); return; @@ -2188,9 +2202,10 @@ void EditorNode::_edit_current(bool p_skip_foreign) { Object *prev_inspected_object = InspectorDock::get_inspector_singleton()->get_edited_object(); bool disable_folding = bool(EDITOR_GET("interface/inspector/disable_folding")); - bool stay_in_script_editor_on_node_selected = bool(EDITOR_GET("text_editor/behavior/navigation/stay_in_script_editor_on_node_selected")); bool is_resource = current_obj->is_class("Resource"); bool is_node = current_obj->is_class("Node"); + bool stay_in_script_editor_on_node_selected = bool(EDITOR_GET("text_editor/behavior/navigation/stay_in_script_editor_on_node_selected")); + bool skip_main_plugin = false; String editable_warning; // None by default. @@ -2227,8 +2242,8 @@ void EditorNode::_edit_current(bool p_skip_foreign) { NodeDock::get_singleton()->set_node(current_node); SceneTreeDock::get_singleton()->set_selected(current_node); InspectorDock::get_singleton()->update(current_node); - if (!inspector_only) { - inspector_only = stay_in_script_editor_on_node_selected && ScriptEditor::get_singleton()->is_visible_in_tree(); + if (!inspector_only && !skip_main_plugin) { + skip_main_plugin = stay_in_script_editor_on_node_selected && ScriptEditor::get_singleton()->is_visible_in_tree(); } } else { NodeDock::get_singleton()->set_node(nullptr); @@ -2304,7 +2319,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { } } - if (main_plugin) { + if (main_plugin && !skip_main_plugin) { // Special case if use of external editor is true. Resource *current_res = Object::cast_to<Resource>(current_obj); if (main_plugin->get_name() == "Script" && !current_obj->is_class("VisualScript") && current_res && !current_res->is_built_in() && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { @@ -3010,7 +3025,7 @@ void EditorNode::_tool_menu_option(int p_idx) { Callable callback = tool_menu->get_item_metadata(p_idx); Callable::CallError ce; Variant result; - callback.call(nullptr, 0, result, ce); + callback.callp(nullptr, 0, result, ce); if (ce.error != Callable::CallError::CALL_OK) { String err = Variant::get_callable_error_text(callback, nullptr, 0, ce); @@ -3045,7 +3060,7 @@ void EditorNode::_export_as_menu_option(int p_idx) { Callable callback = export_as_menu->get_item_metadata(p_idx); Callable::CallError ce; Variant result; - callback.call(nullptr, 0, result, ce); + callback.callp(nullptr, 0, result, ce); if (ce.error != Callable::CallError::CALL_OK) { String err = Variant::get_callable_error_text(callback, nullptr, 0, ce); @@ -3250,7 +3265,7 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed Button *tb = memnew(Button); tb->set_flat(true); tb->set_toggle_mode(true); - tb->connect("pressed", callable_mp(singleton, &EditorNode::_editor_select), varray(singleton->main_editor_buttons.size())); + tb->connect("pressed", callable_mp(singleton, &EditorNode::_editor_select).bind(singleton->main_editor_buttons.size())); tb->set_name(p_editor->get_name()); tb->set_text(p_editor->get_name()); @@ -4375,7 +4390,7 @@ void EditorNode::_dock_make_float() { window->set_size(dock_size); window->set_position(dock_screen_pos); window->set_transient(true); - window->connect("close_requested", callable_mp(this, &EditorNode::_dock_floating_close_request), varray(dock)); + window->connect("close_requested", callable_mp(this, &EditorNode::_dock_floating_close_request).bind(dock)); window->set_meta("dock_slot", dock_popup_selected_idx); window->set_meta("dock_index", dock_index); gui_base->add_child(window); @@ -4596,13 +4611,13 @@ void EditorNode::_save_docks() { Ref<ConfigFile> config; config.instantiate(); // Load and amend existing config if it exists. - config->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); + config->load(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); _save_docks_to_config(config, "docks"); _save_open_scenes_to_config(config, "EditorNode"); editor_data.get_plugin_window_layout(config); - config->save(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); + config->save(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); } void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String &p_section) { @@ -4666,7 +4681,7 @@ void EditorNode::_dock_split_dragged(int ofs) { void EditorNode::_load_docks() { Ref<ConfigFile> config; config.instantiate(); - Error err = config->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); + Error err = config->load(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); if (err != OK) { // No config. if (overridden_default_layout >= 0) { @@ -4899,7 +4914,7 @@ bool EditorNode::has_scenes_in_session() { } Ref<ConfigFile> config; config.instantiate(); - Error err = config->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); + Error err = config->load(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); if (err != OK) { return false; } @@ -5234,7 +5249,7 @@ void EditorNode::_scene_tab_changed(int p_tab) { Button *EditorNode::add_bottom_panel_item(String p_text, Control *p_item) { Button *tb = memnew(Button); tb->set_flat(true); - tb->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch), varray(bottom_panel_items.size())); + tb->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch).bind(bottom_panel_items.size())); tb->set_text(p_text); tb->set_toggle_mode(true); tb->set_focus_mode(Control::FOCUS_NONE); @@ -5281,7 +5296,7 @@ void EditorNode::raise_bottom_panel_item(Control *p_item) { for (int i = 0; i < bottom_panel_items.size(); i++) { bottom_panel_items[i].button->disconnect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch)); - bottom_panel_items[i].button->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch), varray(i)); + bottom_panel_items[i].button->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch).bind(i)); } } @@ -5301,7 +5316,7 @@ void EditorNode::remove_bottom_panel_item(Control *p_item) { for (int i = 0; i < bottom_panel_items.size(); i++) { bottom_panel_items[i].button->disconnect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch)); - bottom_panel_items[i].button->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch), varray(i)); + bottom_panel_items[i].button->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch).bind(i)); } } @@ -5929,7 +5944,11 @@ EditorNode::EditorNode() { AudioServer::get_singleton()->set_enable_tagging_used_audio_streams(true); // No navigation server by default if in editor. - NavigationServer3D::get_singleton()->set_active(false); + if (NavigationServer3D::get_singleton()->get_debug_enabled()) { + NavigationServer3D::get_singleton()->set_active(true); + } else { + NavigationServer3D::get_singleton()->set_active(false); + } // No physics by default if in editor. PhysicsServer3D::get_singleton()->set_active(false); @@ -6138,8 +6157,6 @@ EditorNode::EditorNode() { register_exporters(); - ClassDB::set_class_enabled("RootMotionView", true); - EDITOR_DEF("interface/editor/save_on_focus_loss", false); EDITOR_DEF("interface/editor/show_update_spinner", false); EDITOR_DEF("interface/editor/update_continuously", false); @@ -6156,7 +6173,14 @@ EditorNode::EditorNode() { EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false); EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true); EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true); - EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "Script,MeshLibrary"); + + PackedStringArray open_in_new_inspector_defaults; + // Required for the script editor to work. + open_in_new_inspector_defaults.push_back("Script"); + // Required for the GridMap editor to work. + open_in_new_inspector_defaults.push_back("MeshLibrary"); + EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", open_in_new_inspector_defaults); + EDITOR_DEF("interface/inspector/default_color_picker_mode", 0); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW,OKHSL", PROPERTY_USAGE_DEFAULT)); EDITOR_DEF("interface/inspector/default_color_picker_shape", (int32_t)ColorPicker::SHAPE_OKHSL_CIRCLE); @@ -6322,7 +6346,7 @@ EditorNode::EditorNode() { dock_slot[i]->set_custom_minimum_size(Size2(170, 0) * EDSCALE); dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL); dock_slot[i]->set_popup(dock_select_popup); - dock_slot[i]->connect("pre_popup_pressed", callable_mp(this, &EditorNode::_dock_pre_popup), varray(i)); + dock_slot[i]->connect("pre_popup_pressed", callable_mp(this, &EditorNode::_dock_pre_popup).bind(i)); dock_slot[i]->set_drag_to_rearrange_enabled(true); dock_slot[i]->set_tabs_rearrange_group(1); dock_slot[i]->connect("tab_changed", callable_mp(this, &EditorNode::_dock_tab_changed)); @@ -6370,7 +6394,7 @@ EditorNode::EditorNode() { scene_tabs->set_drag_to_rearrange_enabled(true); scene_tabs->connect("tab_changed", callable_mp(this, &EditorNode::_scene_tab_changed)); scene_tabs->connect("tab_button_pressed", callable_mp(this, &EditorNode::_scene_tab_script_edited)); - scene_tabs->connect("tab_close_pressed", callable_mp(this, &EditorNode::_scene_tab_closed), varray(SCENE_TAB_CLOSE)); + scene_tabs->connect("tab_close_pressed", callable_mp(this, &EditorNode::_scene_tab_closed).bind(SCENE_TAB_CLOSE)); scene_tabs->connect("tab_hovered", callable_mp(this, &EditorNode::_scene_tab_hovered)); scene_tabs->connect("mouse_exited", callable_mp(this, &EditorNode::_scene_tab_exit)); scene_tabs->connect("gui_input", callable_mp(this, &EditorNode::_scene_tab_input)); @@ -6389,7 +6413,7 @@ EditorNode::EditorNode() { scene_tab_add->set_icon(gui_base->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); scene_tab_add->add_theme_color_override("icon_normal_color", Color(0.6f, 0.6f, 0.6f, 0.8f)); scene_tabs->add_child(scene_tab_add); - scene_tab_add->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(FILE_NEW_SCENE)); + scene_tab_add->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(FILE_NEW_SCENE)); scene_tab_add_ph = memnew(Control); scene_tab_add_ph->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); @@ -6441,7 +6465,7 @@ EditorNode::EditorNode() { prev_scene->set_icon(gui_base->get_theme_icon(SNAME("PrevScene"), SNAME("EditorIcons"))); prev_scene->set_tooltip(TTR("Go to previously opened scene.")); prev_scene->set_disabled(true); - prev_scene->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(FILE_OPEN_PREV)); + prev_scene->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(FILE_OPEN_PREV)); gui_base->add_child(prev_scene); prev_scene->set_position(Point2(3, 24)); prev_scene->hide(); @@ -6452,7 +6476,7 @@ EditorNode::EditorNode() { save_accept = memnew(AcceptDialog); gui_base->add_child(save_accept); - save_accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), make_binds((int)MenuOptions::FILE_SAVE_AS_SCENE)); + save_accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind((int)MenuOptions::FILE_SAVE_AS_SCENE)); project_export = memnew(ProjectExportDialog); gui_base->add_child(project_export); @@ -6695,7 +6719,7 @@ EditorNode::EditorNode() { play_button->set_toggle_mode(true); play_button->set_icon(gui_base->get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); play_button->set_focus_mode(Control::FOCUS_NONE); - play_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(RUN_PLAY)); + play_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY)); play_button->set_tooltip(TTR("Play the project.")); ED_SHORTCUT_AND_COMMAND("editor/play", TTR("Play"), Key::F5); @@ -6720,7 +6744,7 @@ EditorNode::EditorNode() { play_hb->add_child(stop_button); stop_button->set_focus_mode(Control::FOCUS_NONE); stop_button->set_icon(gui_base->get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"))); - stop_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(RUN_STOP)); + stop_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_STOP)); stop_button->set_tooltip(TTR("Stop the scene.")); stop_button->set_disabled(true); @@ -6738,7 +6762,7 @@ EditorNode::EditorNode() { play_scene_button->set_toggle_mode(true); play_scene_button->set_focus_mode(Control::FOCUS_NONE); play_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons"))); - play_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(RUN_PLAY_SCENE)); + play_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_SCENE)); play_scene_button->set_tooltip(TTR("Play the edited scene.")); ED_SHORTCUT_AND_COMMAND("editor/play_scene", TTR("Play Scene"), Key::F6); @@ -6751,7 +6775,7 @@ EditorNode::EditorNode() { play_custom_scene_button->set_toggle_mode(true); play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE); play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons"))); - play_custom_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(RUN_PLAY_CUSTOM_SCENE)); + play_custom_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_CUSTOM_SCENE)); play_custom_scene_button->set_tooltip(TTR("Play custom scene")); ED_SHORTCUT_AND_COMMAND("editor/play_custom_scene", TTR("Play Custom Scene"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::F5); @@ -6818,7 +6842,7 @@ EditorNode::EditorNode() { video_restart_dialog = memnew(ConfirmationDialog); video_restart_dialog->set_text(TTR("Changing the video driver requires restarting the editor.")); video_restart_dialog->set_ok_button_text(TTR("Save & Restart")); - video_restart_dialog->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(SET_RENDERING_DRIVER_SAVE_AND_RESTART)); + video_restart_dialog->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind(SET_RENDERING_DRIVER_SAVE_AND_RESTART)); gui_base->add_child(video_restart_dialog); progress_hb = memnew(BackgroundProgress); @@ -6851,6 +6875,7 @@ EditorNode::EditorNode() { filesystem_dock->connect("inherit", callable_mp(this, &EditorNode::_inherit_request)); filesystem_dock->connect("instance", callable_mp(this, &EditorNode::_instantiate_request)); filesystem_dock->connect("display_mode_changed", callable_mp(this, &EditorNode::_save_docks)); + get_project_settings()->connect_filesystem_dock_signals(filesystem_dock); // Scene: Top left. dock_slot[DOCK_SLOT_LEFT_UR]->add_child(SceneTreeDock::get_singleton()); @@ -6987,8 +7012,8 @@ EditorNode::EditorNode() { custom_build_manage_templates = memnew(ConfirmationDialog); custom_build_manage_templates->set_text(TTR("Android build template is missing, please install relevant templates.")); custom_build_manage_templates->set_ok_button_text(TTR("Manage Templates")); - custom_build_manage_templates->add_button(TTR("Install from file"))->connect("pressed", callable_mp(this, &EditorNode::_menu_option), varray(SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE)); - custom_build_manage_templates->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(SETTINGS_MANAGE_EXPORT_TEMPLATES)); + custom_build_manage_templates->add_button(TTR("Install from file"))->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE)); + custom_build_manage_templates->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind(SETTINGS_MANAGE_EXPORT_TEMPLATES)); gui_base->add_child(custom_build_manage_templates); file_android_build_source = memnew(EditorFileDialog); @@ -7008,7 +7033,7 @@ EditorNode::EditorNode() { remove_android_build_template = memnew(ConfirmationDialog); remove_android_build_template->set_text(TTR("The Android build template is already installed in this project and it won't be overwritten.\nRemove the \"res://android/build\" directory manually before attempting this operation again.")); remove_android_build_template->set_ok_button_text(TTR("Show in File Manager")); - remove_android_build_template->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(FILE_EXPLORE_ANDROID_BUILD_TEMPLATES)); + remove_android_build_template->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind(FILE_EXPLORE_ANDROID_BUILD_TEMPLATES)); gui_base->add_child(remove_android_build_template); file_templates = memnew(EditorFileDialog); @@ -7142,7 +7167,6 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(Path3DEditorPlugin)); add_editor_plugin(memnew(PhysicalBone3DEditorPlugin)); add_editor_plugin(memnew(Polygon3DEditorPlugin)); - add_editor_plugin(memnew(ReplicationEditorPlugin)); add_editor_plugin(memnew(ResourcePreloaderEditorPlugin)); add_editor_plugin(memnew(ShaderEditorPlugin)); add_editor_plugin(memnew(ShaderFileEditorPlugin)); @@ -7168,7 +7192,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(NavigationPolygonEditorPlugin)); add_editor_plugin(memnew(Path2DEditorPlugin)); add_editor_plugin(memnew(Polygon2DEditorPlugin)); - add_editor_plugin(memnew(RayCast2DEditorPlugin)); + add_editor_plugin(memnew(Cast2DEditorPlugin)); add_editor_plugin(memnew(Skeleton2DEditorPlugin)); add_editor_plugin(memnew(Sprite2DEditorPlugin)); add_editor_plugin(memnew(TilesEditorPlugin)); @@ -7301,7 +7325,7 @@ EditorNode::EditorNode() { pick_main_scene = memnew(ConfirmationDialog); gui_base->add_child(pick_main_scene); pick_main_scene->set_ok_button_text(TTR("Select")); - pick_main_scene->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(SETTINGS_PICK_MAIN_SCENE)); + pick_main_scene->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind(SETTINGS_PICK_MAIN_SCENE)); select_current_scene_button = pick_main_scene->add_button(TTR("Select Current"), true, "select_current"); pick_main_scene->connect("custom_action", callable_mp(this, &EditorNode::_pick_main_scene_custom_action)); diff --git a/editor/editor_node.h b/editor/editor_node.h index 53c2312022..0201e84eaf 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -32,12 +32,11 @@ #define EDITOR_NODE_H #include "core/templates/safe_refcount.h" -#include "editor/editor_export.h" #include "editor/editor_folding.h" #include "editor/editor_native_shader_source_visualizer.h" #include "editor/editor_run.h" +#include "editor/export/editor_export.h" #include "editor/inspector_dock.h" -#include "editor/property_editor.h" typedef void (*EditorNodeInitCallback)(); typedef void (*EditorPluginInitializeCallback)(); @@ -48,6 +47,7 @@ class AudioStreamPreviewGenerator; class BackgroundProgress; class Button; class CenterContainer; +class ColorPicker; class ConfirmationDialog; class Control; class DependencyEditor; @@ -67,6 +67,7 @@ class EditorPlugin; class EditorPluginList; class EditorQuickOpen; class EditorResourcePreview; +class EditorResourceConversionPlugin; class EditorRun; class EditorRunNative; class EditorSettingsDialog; diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp index a5c2fe093c..b6364e1ab7 100644 --- a/editor/editor_paths.cpp +++ b/editor/editor_paths.cpp @@ -66,6 +66,30 @@ String EditorPaths::get_self_contained_file() const { return self_contained_file; } +String EditorPaths::get_export_templates_dir() const { + return get_data_dir().plus_file(export_templates_folder); +} + +String EditorPaths::get_project_settings_dir() const { + return get_project_data_dir().plus_file("editor"); +} + +String EditorPaths::get_text_editor_themes_dir() const { + return get_config_dir().plus_file(text_editor_themes_folder); +} + +String EditorPaths::get_script_templates_dir() const { + return get_config_dir().plus_file(script_templates_folder); +} + +String EditorPaths::get_project_script_templates_dir() const { + return ProjectSettings::get_singleton()->get("editor/script/templates_search_path"); +} + +String EditorPaths::get_feature_profiles_dir() const { + return get_config_dir().plus_file(feature_profiles_folder); +} + void EditorPaths::create() { ERR_FAIL_COND(singleton != nullptr); memnew(EditorPaths()); @@ -82,6 +106,8 @@ void EditorPaths::_bind_methods() { ClassDB::bind_method(D_METHOD("get_cache_dir"), &EditorPaths::get_cache_dir); ClassDB::bind_method(D_METHOD("is_self_contained"), &EditorPaths::is_self_contained); ClassDB::bind_method(D_METHOD("get_self_contained_file"), &EditorPaths::get_self_contained_file); + + ClassDB::bind_method(D_METHOD("get_project_settings_dir"), &EditorPaths::get_project_settings_dir); } EditorPaths::EditorPaths() { @@ -153,8 +179,8 @@ EditorPaths::EditorPaths() { } } - if (!dir->dir_exists("templates")) { - dir->make_dir("templates"); + if (!dir->dir_exists(export_templates_folder)) { + dir->make_dir(export_templates_folder); } } @@ -168,14 +194,14 @@ EditorPaths::EditorPaths() { } } - if (!dir->dir_exists("text_editor_themes")) { - dir->make_dir("text_editor_themes"); + if (!dir->dir_exists(text_editor_themes_folder)) { + dir->make_dir(text_editor_themes_folder); } - if (!dir->dir_exists("script_templates")) { - dir->make_dir("script_templates"); + if (!dir->dir_exists(script_templates_folder)) { + dir->make_dir(script_templates_folder); } - if (!dir->dir_exists("feature_profiles")) { - dir->make_dir("feature_profiles"); + if (!dir->dir_exists(feature_profiles_folder)) { + dir->make_dir(feature_profiles_folder); } } @@ -192,7 +218,6 @@ EditorPaths::EditorPaths() { // Validate or create project-specific editor data dir, // including shader cache subdir. - if (Engine::get_singleton()->is_project_manager_hint() || Main::is_cmdline_tool()) { // Nothing to create, use shared editor data dir for shader cache. Engine::get_singleton()->set_shader_cache_path(data_dir); diff --git a/editor/editor_paths.h b/editor/editor_paths.h index 7d863a7c6c..9cff1063c5 100644 --- a/editor/editor_paths.h +++ b/editor/editor_paths.h @@ -45,6 +45,10 @@ class EditorPaths : public Object { String project_data_dir; // Project-specific data (metadata, shader cache, etc.). bool self_contained = false; // Self-contained means everything goes to `editor_data` dir. String self_contained_file; // Self-contained file with configuration. + String export_templates_folder = "export_templates"; + String text_editor_themes_folder = "text_editor_themes"; + String script_templates_folder = "script_templates"; + String feature_profiles_folder = "feature_profiles"; static EditorPaths *singleton; @@ -58,6 +62,12 @@ public: String get_config_dir() const; String get_cache_dir() const; String get_project_data_dir() const; + String get_export_templates_dir() const; + String get_project_settings_dir() const; + String get_text_editor_themes_dir() const; + String get_script_templates_dir() const; + String get_project_script_templates_dir() const; + String get_feature_profiles_dir() const; bool is_self_contained() const; String get_self_contained_file() const; diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index d9c2a42114..566c22f5a9 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -31,11 +31,11 @@ #include "editor_plugin.h" #include "editor/editor_command_palette.h" -#include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_resource_preview.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" #include "editor/filesystem_dock.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index 3a0b875b8c..5a010a66c1 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -37,6 +37,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "scene/gui/margin_container.h" +#include "scene/gui/tree.h" void EditorPluginSettings::_notification(int p_what) { switch (p_what) { diff --git a/editor/editor_plugin_settings.h b/editor/editor_plugin_settings.h index 7c6d93e6f4..9c619066f2 100644 --- a/editor/editor_plugin_settings.h +++ b/editor/editor_plugin_settings.h @@ -34,8 +34,8 @@ #include "core/object/undo_redo.h" #include "editor/editor_data.h" #include "editor/plugin_config_dialog.h" -#include "property_editor.h" -#include "scene/gui/dialogs.h" + +class Tree; class EditorPluginSettings : public VBoxContainer { GDCLASS(EditorPluginSettings, VBoxContainer); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index d145a1e820..f434df3a1e 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -133,6 +133,11 @@ void EditorPropertyMultilineText::_text_changed() { void EditorPropertyMultilineText::_open_big_text() { if (!big_text_dialog) { big_text = memnew(TextEdit); + if (expression) { + big_text->set_syntax_highlighter(text->get_syntax_highlighter()); + big_text->add_theme_font_override("font", get_theme_font(SNAME("expression"), SNAME("EditorFonts"))); + big_text->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts"))); + } big_text->connect("text_changed", callable_mp(this, &EditorPropertyMultilineText::_big_text_changed)); big_text->set_line_wrapping_mode(TextEdit::LineWrappingMode::LINE_WRAPPING_BOUNDARY); big_text_dialog = memnew(AcceptDialog); @@ -162,12 +167,24 @@ void EditorPropertyMultilineText::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { Ref<Texture2D> df = get_theme_icon(SNAME("DistractionFree"), SNAME("EditorIcons")); open_big_text->set_icon(df); - Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label")); - int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); - text->set_custom_minimum_size(Vector2(0, font->get_height(font_size) * 6)); - text->add_theme_font_override("font", get_theme_font("expression", "EditorFonts")); - text->add_theme_font_size_override("font_size", get_theme_font_size("expression_size", "EditorFonts")); + Ref<Font> font; + int font_size; + if (expression) { + font = get_theme_font(SNAME("expression"), SNAME("EditorFonts")); + font_size = get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts")); + + text->add_theme_font_override("font", font); + text->add_theme_font_size_override("font_size", font_size); + if (big_text) { + big_text->add_theme_font_override("font", font); + big_text->add_theme_font_size_override("font_size", font_size); + } + } else { + font = get_theme_font(SNAME("font"), SNAME("TextEdit")); + font_size = get_theme_font_size(SNAME("font_size"), SNAME("TextEdit")); + } + text->set_custom_minimum_size(Vector2(0, font->get_height(font_size) * 6)); } break; } } @@ -490,13 +507,55 @@ void EditorPropertyPath::_path_focus_exited() { _path_selected(path->get_text()); } +void EditorPropertyPath::_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + const Dictionary drag_data = p_data; + if (!drag_data.has("type")) { + return; + } + if (String(drag_data["type"]) != "files") { + return; + } + const Vector<String> filesPaths = drag_data["files"]; + if (filesPaths.size() == 0) { + return; + } + + emit_changed(get_edited_property(), filesPaths[0]); + update_property(); +} + +bool EditorPropertyPath::_can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + const Dictionary drag_data = p_data; + if (!drag_data.has("type")) { + return false; + } + if (String(drag_data["type"]) != "files") { + return false; + } + const Vector<String> filesPaths = drag_data["files"]; + if (filesPaths.size() == 0) { + return false; + } + + for (const String &extension : extensions) { + if (filesPaths[0].ends_with(extension.substr(1, extension.size() - 1))) { + return true; + } + } + + return false; +} + void EditorPropertyPath::_bind_methods() { + ClassDB::bind_method(D_METHOD("_can_drop_data_fw", "position", "data", "from"), &EditorPropertyPath::_can_drop_data_fw); + ClassDB::bind_method(D_METHOD("_drop_data_fw", "position", "data", "from"), &EditorPropertyPath::_drop_data_fw); } EditorPropertyPath::EditorPropertyPath() { HBoxContainer *path_hb = memnew(HBoxContainer); add_child(path_hb); path = memnew(LineEdit); + path->set_drag_forwarding(this); path->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE); path_hb->add_child(path); path->connect("text_submitted", callable_mp(this, &EditorPropertyPath::_path_selected)); @@ -774,7 +833,7 @@ void EditorPropertyFlags::setup(const Vector<String> &p_options) { CheckBox *cb = memnew(CheckBox); cb->set_text(option); cb->set_clip_text(true); - cb->connect("pressed", callable_mp(this, &EditorPropertyFlags::_flag_toggled), varray(i)); + cb->connect("pressed", callable_mp(this, &EditorPropertyFlags::_flag_toggled).bind(i)); add_focusable(cb); vbox->add_child(cb); flags.push_back(cb); @@ -1088,6 +1147,17 @@ void EditorPropertyLayersGrid::_bind_methods() { ADD_SIGNAL(MethodInfo("rename_confirmed", PropertyInfo(Variant::INT, "layer_id"), PropertyInfo(Variant::STRING, "new_name"))); } +void EditorPropertyLayers::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + button->set_normal_texture(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); + button->set_pressed_texture(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); + button->set_disabled_texture(get_theme_icon(SNAME("GuiTabMenu"), SNAME("EditorIcons"))); + } break; + } +} + void EditorPropertyLayers::_set_read_only(bool p_read_only) { button->set_disabled(p_read_only); grid->set_read_only(p_read_only); @@ -1224,9 +1294,9 @@ EditorPropertyLayers::EditorPropertyLayers() { grid->set_h_size_flags(SIZE_EXPAND_FILL); hb->add_child(grid); - button = memnew(Button); + button = memnew(TextureButton); + button->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); button->set_toggle_mode(true); - button->set_text("..."); button->connect("pressed", callable_mp(this, &EditorPropertyLayers::_button_pressed)); hb->add_child(button); @@ -1236,7 +1306,7 @@ EditorPropertyLayers::EditorPropertyLayers() { add_child(layers); layers->set_hide_on_checkable_item_selection(false); layers->connect("id_pressed", callable_mp(this, &EditorPropertyLayers::_menu_pressed)); - layers->connect("popup_hide", callable_mp((BaseButton *)button, &BaseButton::set_pressed), varray(false)); + layers->connect("popup_hide", callable_mp((BaseButton *)button, &BaseButton::set_pressed).bind(false)); EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &EditorPropertyLayers::_refresh_names)); } @@ -1580,6 +1650,11 @@ void EditorPropertyEasing::_spin_value_changed(double p_value) { // which can cause crashes and other issues. p_value = CLAMP(p_value, -1'000'000, 1'000'000); + if (positive_only) { + // Force a positive or zero value if a negative value was manually entered by double-clicking. + p_value = MAX(0.0, p_value); + } + emit_changed(get_edited_property(), p_value); _spin_focus_exited(); } @@ -1591,9 +1666,9 @@ void EditorPropertyEasing::_spin_focus_exited() { easing_draw->update(); } -void EditorPropertyEasing::setup(bool p_full, bool p_flip) { +void EditorPropertyEasing::setup(bool p_positive_only, bool p_flip) { flip = p_flip; - full = p_full; + positive_only = p_positive_only; } void EditorPropertyEasing::_notification(int p_what) { @@ -1601,13 +1676,13 @@ void EditorPropertyEasing::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_ENTER_TREE: { preset->clear(); - preset->add_icon_item(get_theme_icon(SNAME("CurveConstant"), SNAME("EditorIcons")), "Zero", EASING_ZERO); preset->add_icon_item(get_theme_icon(SNAME("CurveLinear"), SNAME("EditorIcons")), "Linear", EASING_LINEAR); - preset->add_icon_item(get_theme_icon(SNAME("CurveIn"), SNAME("EditorIcons")), "In", EASING_IN); - preset->add_icon_item(get_theme_icon(SNAME("CurveOut"), SNAME("EditorIcons")), "Out", EASING_OUT); - if (full) { - preset->add_icon_item(get_theme_icon(SNAME("CurveInOut"), SNAME("EditorIcons")), "In-Out", EASING_IN_OUT); - preset->add_icon_item(get_theme_icon(SNAME("CurveOutIn"), SNAME("EditorIcons")), "Out-In", EASING_OUT_IN); + preset->add_icon_item(get_theme_icon(SNAME("CurveIn"), SNAME("EditorIcons")), "Ease In", EASING_IN); + preset->add_icon_item(get_theme_icon(SNAME("CurveOut"), SNAME("EditorIcons")), "Ease Out", EASING_OUT); + preset->add_icon_item(get_theme_icon(SNAME("CurveConstant"), SNAME("EditorIcons")), "Zero", EASING_ZERO); + if (!positive_only) { + preset->add_icon_item(get_theme_icon(SNAME("CurveInOut"), SNAME("EditorIcons")), "Ease In-Out", EASING_IN_OUT); + preset->add_icon_item(get_theme_icon(SNAME("CurveOutIn"), SNAME("EditorIcons")), "Ease Out-In", EASING_OUT_IN); } easing_draw->set_custom_minimum_size(Size2(0, get_theme_font(SNAME("font"), SNAME("Label"))->get_height(get_theme_font_size(SNAME("font_size"), SNAME("Label"))) * 2)); } break; @@ -1755,7 +1830,7 @@ EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) { spin[i]->set_label(desc[i]); bc->add_child(spin[i]); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector2::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector2::_value_changed).bind(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -1865,7 +1940,7 @@ EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) { } add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2::_value_changed).bind(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -2037,7 +2112,7 @@ EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) { spin[i]->set_label(desc[i]); bc->add_child(spin[i]); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector3::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector3::_value_changed).bind(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -2168,7 +2243,7 @@ EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) { spin[i]->set_label(desc[i]); bc->add_child(spin[i]); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector2i::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector2i::_value_changed).bind(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -2278,7 +2353,7 @@ EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) { } add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2i::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2i::_value_changed).bind(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -2420,7 +2495,7 @@ EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) { spin[i]->set_label(desc[i]); bc->add_child(spin[i]); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector3i::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector3i::_value_changed).bind(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -2521,7 +2596,7 @@ EditorPropertyPlane::EditorPropertyPlane(bool p_force_wide) { spin[i]->set_label(desc[i]); bc->add_child(spin[i]); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyPlane::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyPlane::_value_changed).bind(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -2613,7 +2688,7 @@ EditorPropertyQuaternion::EditorPropertyQuaternion() { spin[i]->set_label(desc[i]); bc->add_child(spin[i]); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyQuaternion::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyQuaternion::_value_changed).bind(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -2704,7 +2779,7 @@ EditorPropertyVector4::EditorPropertyVector4() { spin[i]->set_label(desc[i]); bc->add_child(spin[i]); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector4::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector4::_value_changed).bind(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -2793,7 +2868,7 @@ EditorPropertyVector4i::EditorPropertyVector4i() { spin[i]->set_label(desc[i]); bc->add_child(spin[i]); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector4i::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector4i::_value_changed).bind(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -2882,7 +2957,7 @@ EditorPropertyAABB::EditorPropertyAABB() { g->add_child(spin[i]); spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyAABB::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyAABB::_value_changed).bind(desc[i])); } set_bottom_editor(g); } @@ -2973,7 +3048,7 @@ EditorPropertyTransform2D::EditorPropertyTransform2D(bool p_include_origin) { } spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyTransform2D::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyTransform2D::_value_changed).bind(desc[i])); } set_bottom_editor(g); } @@ -3063,7 +3138,7 @@ EditorPropertyBasis::EditorPropertyBasis() { g->add_child(spin[i]); spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyBasis::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyBasis::_value_changed).bind(desc[i])); } set_bottom_editor(g); } @@ -3161,7 +3236,7 @@ EditorPropertyTransform3D::EditorPropertyTransform3D() { g->add_child(spin[i]); spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyTransform3D::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyTransform3D::_value_changed).bind(desc[i])); } set_bottom_editor(g); } @@ -3267,7 +3342,7 @@ EditorPropertyProjection::EditorPropertyProjection() { g->add_child(spin[i]); spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyProjection::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyProjection::_value_changed).bind(desc[i])); } set_bottom_editor(g); } @@ -3336,7 +3411,7 @@ EditorPropertyColor::EditorPropertyColor() { picker->set_flat(true); picker->connect("color_changed", callable_mp(this, &EditorPropertyColor::_color_changed)); picker->connect("popup_closed", callable_mp(this, &EditorPropertyColor::_popup_closed)); - picker->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(picker->get_picker())); + picker->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(picker->get_picker())); picker->get_popup()->connect("about_to_popup", callable_mp(this, &EditorPropertyColor::_picker_opening)); } @@ -3603,7 +3678,10 @@ void EditorPropertyResource::_resource_selected(const Ref<Resource> &p_resource, void EditorPropertyResource::_resource_changed(const Ref<Resource> &p_resource) { // Make visual script the correct type. Ref<Script> s = p_resource; + bool is_script = false; if (get_edited_object() && s.is_valid()) { + is_script = true; + InspectorDock::get_singleton()->store_script_properties(get_edited_object()); s->call("set_instance_base_type", get_edited_object()->get_class()); } @@ -3629,6 +3707,11 @@ void EditorPropertyResource::_resource_changed(const Ref<Resource> &p_resource) emit_changed(get_edited_property(), p_resource); update_property(); + if (is_script) { + // Restore properties if script was changed. + InspectorDock::get_singleton()->apply_script_properties(get_edited_object()); + } + // Automatically suggest setting up the path for a ViewportTexture. if (vpt.is_valid() && vpt->get_viewport_path_in_scene().is_empty()) { if (!scene_tree) { @@ -3910,6 +3993,12 @@ void EditorPropertyResource::expand_all_folding() { } } +void EditorPropertyResource::expand_revertable() { + if (sub_inspector) { + sub_inspector->expand_revertable(); + } +} + void EditorPropertyResource::set_use_sub_inspector(bool p_enable) { use_sub_inspector = p_enable; } @@ -4091,20 +4180,20 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ case Variant::FLOAT: { if (p_hint == PROPERTY_HINT_EXP_EASING) { EditorPropertyEasing *editor = memnew(EditorPropertyEasing); - bool full = true; + bool positive_only = false; bool flip = false; - Vector<String> hints = p_hint_text.split(","); + const Vector<String> hints = p_hint_text.split(","); for (int i = 0; i < hints.size(); i++) { - String h = hints[i].strip_edges(); - if (h == "attenuation") { + const String hint = hints[i].strip_edges(); + if (hint == "attenuation") { flip = true; } - if (h == "inout") { - full = true; + if (hint == "positive_only") { + positive_only = true; } } - editor->setup(full, flip); + editor->setup(positive_only, flip); return editor; } else { @@ -4348,11 +4437,11 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ editor->setup(p_object, p_path, p_hint == PROPERTY_HINT_RESOURCE_TYPE ? p_hint_text : "Resource"); if (p_hint == PROPERTY_HINT_RESOURCE_TYPE) { - String open_in_new = EDITOR_GET("interface/inspector/resources_to_open_in_new_inspector"); - for (int i = 0; i < open_in_new.get_slice_count(","); i++) { - String type = open_in_new.get_slicec(',', i).strip_edges(); + const PackedStringArray open_in_new_inspector = EDITOR_GET("interface/inspector/resources_to_open_in_new_inspector"); + + for (const String &type : open_in_new_inspector) { for (int j = 0; j < p_hint_text.get_slice_count(","); j++) { - String inherits = p_hint_text.get_slicec(',', j); + const String inherits = p_hint_text.get_slicec(',', j); if (ClassDB::is_parent_class(inherits, type)) { editor->set_use_sub_inspector(false); } diff --git a/editor/editor_properties.h b/editor/editor_properties.h index b3aac6e8ca..c1dfb5cb1e 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -142,6 +142,8 @@ class EditorPropertyPath : public EditorProperty { void _path_selected(const String &p_path); void _path_pressed(); void _path_focus_exited(); + void _drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); + bool _can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; protected: virtual void _set_read_only(bool p_read_only) override; @@ -340,13 +342,14 @@ private: String basename; LayerType layer_type; PopupMenu *layers = nullptr; - Button *button = nullptr; + TextureButton *button = nullptr; void _button_pressed(); void _menu_pressed(int p_menu); void _refresh_names(); protected: + void _notification(int p_what); virtual void _set_read_only(bool p_read_only) override; static void _bind_methods(); @@ -443,6 +446,7 @@ class EditorPropertyEasing : public EditorProperty { bool dragging = false; bool full = false; bool flip = false; + bool positive_only = false; enum { EASING_ZERO, @@ -471,7 +475,7 @@ protected: public: virtual void update_property() override; - void setup(bool p_full, bool p_flip); + void setup(bool p_positive_only, bool p_flip); EditorPropertyEasing(); }; @@ -856,6 +860,7 @@ public: void collapse_all_folding() override; void expand_all_folding() override; + void expand_revertable() override; void set_use_sub_inspector(bool p_enable); diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index e83b070f6b..9a83082d1e 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -329,7 +329,7 @@ void EditorPropertyArray::update_property() { reorder_button->set_icon(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons"))); reorder_button->set_default_cursor_shape(Control::CURSOR_MOVE); reorder_button->connect("gui_input", callable_mp(this, &EditorPropertyArray::_reorder_button_gui_input)); - reorder_button->connect("button_down", callable_mp(this, &EditorPropertyArray::_reorder_button_down), varray(i + offset)); + reorder_button->connect("button_down", callable_mp(this, &EditorPropertyArray::_reorder_button_down).bind(i + offset)); reorder_button->connect("button_up", callable_mp(this, &EditorPropertyArray::_reorder_button_up)); hbox->add_child(reorder_button); @@ -366,11 +366,11 @@ void EditorPropertyArray::update_property() { Button *edit = memnew(Button); edit->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); hbox->add_child(edit); - edit->connect("pressed", callable_mp(this, &EditorPropertyArray::_change_type), varray(edit, i + offset)); + edit->connect("pressed", callable_mp(this, &EditorPropertyArray::_change_type).bind(edit, i + offset)); } else { Button *remove = memnew(Button); remove->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); - remove->connect("pressed", callable_mp(this, &EditorPropertyArray::_remove_pressed), varray(i + offset)); + remove->connect("pressed", callable_mp(this, &EditorPropertyArray::_remove_pressed).bind(i + offset)); hbox->add_child(remove); } @@ -1136,7 +1136,7 @@ void EditorPropertyDictionary::update_property() { Button *edit = memnew(Button); edit->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); hbox->add_child(edit); - edit->connect("pressed", callable_mp(this, &EditorPropertyDictionary::_change_type), varray(edit, change_index)); + edit->connect("pressed", callable_mp(this, &EditorPropertyDictionary::_change_type).bind(edit, change_index)); prop->update_property(); @@ -1375,7 +1375,7 @@ void EditorPropertyLocalizableString::update_property() { Button *edit = memnew(Button); edit->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); hbox->add_child(edit); - edit->connect("pressed", callable_mp(this, &EditorPropertyLocalizableString::_remove_item), varray(edit, remove_index)); + edit->connect("pressed", callable_mp(this, &EditorPropertyLocalizableString::_remove_item).bind(edit, remove_index)); prop->update_property(); } diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h index 44623149d0..82aeebe14a 100644 --- a/editor/editor_properties_array_dict.h +++ b/editor/editor_properties_array_dict.h @@ -81,10 +81,7 @@ class EditorPropertyArray : public EditorProperty { GDCLASS(EditorPropertyArray, EditorProperty); PopupMenu *change_type = nullptr; - bool updating = false; - bool dropping = false; - Ref<EditorPropertyArrayObject> object; int page_length = 20; int page_index = 0; int changing_type_index; @@ -106,29 +103,35 @@ class EditorPropertyArray : public EditorProperty { Button *reorder_selected_button = nullptr; void _page_changed(int p_page); - void _length_changed(double p_page); - void _add_element(); - void _edit_pressed(); - void _property_changed(const String &p_property, Variant p_value, const String &p_name = "", bool p_changing = false); - void _change_type(Object *p_button, int p_index); - void _change_type_menu(int p_index); - - void _object_id_selected(const StringName &p_property, ObjectID p_id); - void _remove_pressed(int p_index); - - void _button_draw(); - bool _is_drop_valid(const Dictionary &p_drag_data) const; - bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; - void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); void _reorder_button_gui_input(const Ref<InputEvent> &p_event); void _reorder_button_down(int p_index); void _reorder_button_up(); protected: + Ref<EditorPropertyArrayObject> object; + + bool updating = false; + bool dropping = false; + static void _bind_methods(); void _notification(int p_what); + virtual void _add_element(); + virtual void _length_changed(double p_page); + virtual void _edit_pressed(); + virtual void _property_changed(const String &p_property, Variant p_value, const String &p_name = "", bool p_changing = false); + virtual void _change_type(Object *p_button, int p_index); + virtual void _change_type_menu(int p_index); + + virtual void _object_id_selected(const StringName &p_property, ObjectID p_id); + virtual void _remove_pressed(int p_index); + + virtual void _button_draw(); + virtual bool _is_drop_valid(const Dictionary &p_drag_data) const; + virtual bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + virtual void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); + public: void setup(Variant::Type p_array_type, const String &p_hint_string = ""); virtual void update_property() override; diff --git a/editor/editor_property_name_processor.cpp b/editor/editor_property_name_processor.cpp index 09d2992e07..6c713de94a 100644 --- a/editor/editor_property_name_processor.cpp +++ b/editor/editor_property_name_processor.cpp @@ -114,6 +114,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["bidi"] = "BiDi"; capitalize_string_remaps["bp"] = "BP"; capitalize_string_remaps["bpc"] = "BPC"; + capitalize_string_remaps["bpm"] = "BPM"; capitalize_string_remaps["bptc"] = "BPTC"; capitalize_string_remaps["bvh"] = "BVH"; capitalize_string_remaps["ca"] = "CA"; diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index e0903ea5ce..e5c1836205 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -38,6 +38,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/filesystem_dock.h" +#include "editor/plugins/editor_resource_conversion_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/scene_tree_dock.h" @@ -183,6 +184,21 @@ void EditorResourcePicker::_update_menu_items() { edit_menu->add_icon_item(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), TTR("Edit"), OBJ_MENU_EDIT); edit_menu->add_icon_item(get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), TTR("Clear"), OBJ_MENU_CLEAR); edit_menu->add_icon_item(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE); + + // Check whether the resource has subresources. + List<PropertyInfo> property_list; + edited_resource->get_property_list(&property_list); + bool has_subresources = false; + for (PropertyInfo &p : property_list) { + if ((p.type == Variant::OBJECT) && (p.hint == PROPERTY_HINT_RESOURCE_TYPE) && (p.name != "script")) { + has_subresources = true; + break; + } + } + if (has_subresources) { + edit_menu->add_icon_item(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), TTR("Make Unique (Recursive)"), OBJ_MENU_MAKE_UNIQUE_RECURSIVE); + } + edit_menu->add_icon_item(get_theme_icon(SNAME("Save"), SNAME("EditorIcons")), TTR("Save"), OBJ_MENU_SAVE); if (edited_resource->get_path().is_resource_file()) { @@ -296,28 +312,22 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { return; } - List<PropertyInfo> property_list; - edited_resource->get_property_list(&property_list); - List<Pair<String, Variant>> propvalues; - for (const PropertyInfo &pi : property_list) { - Pair<String, Variant> p; - if (pi.usage & PROPERTY_USAGE_STORAGE) { - p.first = pi.name; - p.second = edited_resource->get(pi.name); - } + Ref<Resource> unique_resource = edited_resource->duplicate(); + ERR_FAIL_COND(unique_resource.is_null()); - propvalues.push_back(p); + edited_resource = unique_resource; + emit_signal(SNAME("resource_changed"), edited_resource); + _update_resource(); + } break; + + case OBJ_MENU_MAKE_UNIQUE_RECURSIVE: { + if (edited_resource.is_null()) { + return; } - String orig_type = edited_resource->get_class(); - Object *inst = ClassDB::instantiate(orig_type); - Ref<Resource> unique_resource = Ref<Resource>(Object::cast_to<Resource>(inst)); + Ref<Resource> unique_resource = edited_resource->duplicate(true); ERR_FAIL_COND(unique_resource.is_null()); - for (const Pair<String, Variant> &p : propvalues) { - unique_resource->set(p.first, p.second); - } - edited_resource = unique_resource; emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); @@ -871,7 +881,7 @@ void EditorResourcePicker::_ensure_resource_menu() { edit_menu = memnew(PopupMenu); add_child(edit_menu); edit_menu->connect("id_pressed", callable_mp(this, &EditorResourcePicker::_edit_menu_cbk)); - edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false)); + edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed).bind(false)); } EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) { diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h index d36e742bcd..3a4d5985bd 100644 --- a/editor/editor_resource_picker.h +++ b/editor/editor_resource_picker.h @@ -66,6 +66,7 @@ class EditorResourcePicker : public HBoxContainer { OBJ_MENU_EDIT, OBJ_MENU_CLEAR, OBJ_MENU_MAKE_UNIQUE, + OBJ_MENU_MAKE_UNIQUE_RECURSIVE, OBJ_MENU_SAVE, OBJ_MENU_COPY, OBJ_MENU_PASTE, diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index b84e654d42..c0ea2b743e 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -195,9 +195,9 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref< if (r_texture.is_valid()) { //wow it generated a preview... save cache bool has_small_texture = r_small_texture.is_valid(); - ResourceSaver::save(cache_base + ".png", r_texture); + ResourceSaver::save(r_texture, cache_base + ".png"); if (has_small_texture) { - ResourceSaver::save(cache_base + "_small.png", r_small_texture); + ResourceSaver::save(r_small_texture, cache_base + "_small.png"); } Ref<FileAccess> f = FileAccess::open(cache_base + ".txt", FileAccess::WRITE); ERR_FAIL_COND_MSG(f.is_null(), "Cannot create file '" + cache_base + ".txt'. Check user write permissions."); diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 854885c707..d8b738be17 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -30,9 +30,10 @@ #include "editor_run_native.h" -#include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" +#include "editor/export/editor_export_platform.h" void EditorRunNative::_notification(int p_what) { switch (p_what) { @@ -51,8 +52,8 @@ void EditorRunNative::_notification(int p_what) { im->resize(16 * EDSCALE, 16 * EDSCALE); Ref<ImageTexture> small_icon = ImageTexture::create_from_image(im); MenuButton *mb = memnew(MenuButton); - mb->get_popup()->connect("id_pressed", callable_mp(this, &EditorRunNative::run_native), varray(i)); - mb->connect("pressed", callable_mp(this, &EditorRunNative::run_native), varray(-1, i)); + mb->get_popup()->connect("id_pressed", callable_mp(this, &EditorRunNative::run_native).bind(i)); + mb->connect("pressed", callable_mp(this, &EditorRunNative::run_native).bind(-1, i)); mb->set_icon(small_icon); add_child(mb); menus[i] = mb; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index c73caa78f3..80e77a1125 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -685,7 +685,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { // Visual editors EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/visual_editors/minimap_opacity", 0.85, "0.0,1.0,0.01") EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/visual_editors/lines_curvature", 0.5, "0.0,1.0,0.01") - EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "editors/visual_editors/visualshader/port_preview_size", 160, "100,400,0.01") + EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "editors/visual_editors/visual_shader/port_preview_size", 160, "100,400,0.01") /* Run */ @@ -867,7 +867,6 @@ void EditorSettings::create() { } singleton->save_changed_setting = true; - singleton->config_file_path = config_file_path; print_verbose("EditorSettings: Load OK!"); @@ -892,8 +891,8 @@ fail: } singleton = Ref<EditorSettings>(memnew(EditorSettings)); + singleton->set_path(config_file_path, true); singleton->save_changed_setting = true; - singleton->config_file_path = config_file_path; singleton->_load_defaults(extra_config); singleton->setup_language(); singleton->setup_network(); @@ -953,15 +952,10 @@ void EditorSettings::save() { return; } - if (singleton->config_file_path.is_empty()) { - ERR_PRINT("Cannot save EditorSettings config, no valid path"); - return; - } - - Error err = ResourceSaver::save(singleton->config_file_path, singleton); + Error err = ResourceSaver::save(singleton); if (err != OK) { - ERR_PRINT("Error saving editor settings to " + singleton->config_file_path); + ERR_PRINT("Error saving editor settings to " + singleton->get_path()); } else { singleton->changed_settings.clear(); print_verbose("EditorSettings: Save OK!"); @@ -1057,6 +1051,8 @@ void EditorSettings::set_initial_value(const StringName &p_setting, const Varian } Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default, bool p_restart_if_changed) { + ERR_FAIL_NULL_V_MSG(EditorSettings::get_singleton(), p_default, "EditorSettings not instantiated yet."); + Variant ret = p_default; if (EditorSettings::get_singleton()->has_setting(p_setting)) { ret = EditorSettings::get_singleton()->get(p_setting); @@ -1073,7 +1069,7 @@ Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default, bool p_re } Variant _EDITOR_GET(const String &p_setting) { - ERR_FAIL_COND_V(!EditorSettings::get_singleton()->has_setting(p_setting), Variant()); + ERR_FAIL_COND_V(!EditorSettings::get_singleton() || !EditorSettings::get_singleton()->has_setting(p_setting), Variant()); return EditorSettings::get_singleton()->get(p_setting); } @@ -1103,38 +1099,11 @@ void EditorSettings::add_property_hint(const PropertyInfo &p_hint) { hints[p_hint.name] = p_hint; } -// Editor data and config directories -// EditorPaths::create() is responsible for the creation of these directories. - -String EditorSettings::get_export_templates_dir() const { - return EditorPaths::get_singleton()->get_data_dir().plus_file("export_templates"); -} - -String EditorSettings::get_project_settings_dir() const { - return EditorPaths::get_singleton()->get_project_data_dir().plus_file("editor"); -} - -String EditorSettings::get_text_editor_themes_dir() const { - return EditorPaths::get_singleton()->get_config_dir().plus_file("text_editor_themes"); -} - -String EditorSettings::get_script_templates_dir() const { - return EditorPaths::get_singleton()->get_config_dir().plus_file("script_templates"); -} - -String EditorSettings::get_project_script_templates_dir() const { - return ProjectSettings::get_singleton()->get("editor/script/templates_search_path"); -} - -String EditorSettings::get_feature_profiles_dir() const { - return EditorPaths::get_singleton()->get_config_dir().plus_file("feature_profiles"); -} - // Metadata void EditorSettings::set_project_metadata(const String &p_section, const String &p_key, Variant p_data) { Ref<ConfigFile> cf = memnew(ConfigFile); - String path = get_project_settings_dir().plus_file("project_metadata.cfg"); + String path = EditorPaths::get_singleton()->get_project_settings_dir().plus_file("project_metadata.cfg"); Error err; err = cf->load(path); ERR_FAIL_COND_MSG(err != OK && err != ERR_FILE_NOT_FOUND, "Cannot load editor settings from file '" + path + "'."); @@ -1145,7 +1114,7 @@ void EditorSettings::set_project_metadata(const String &p_section, const String Variant EditorSettings::get_project_metadata(const String &p_section, const String &p_key, Variant p_default) const { Ref<ConfigFile> cf = memnew(ConfigFile); - String path = get_project_settings_dir().plus_file("project_metadata.cfg"); + String path = EditorPaths::get_singleton()->get_project_settings_dir().plus_file("project_metadata.cfg"); Error err = cf->load(path); if (err != OK) { return p_default; @@ -1159,7 +1128,7 @@ void EditorSettings::set_favorites(const Vector<String> &p_favorites) { if (Engine::get_singleton()->is_project_manager_hint()) { favorites_file = EditorPaths::get_singleton()->get_config_dir().plus_file("favorite_dirs"); } else { - favorites_file = get_project_settings_dir().plus_file("favorites"); + favorites_file = EditorPaths::get_singleton()->get_project_settings_dir().plus_file("favorites"); } Ref<FileAccess> f = FileAccess::open(favorites_file, FileAccess::WRITE); if (f.is_valid()) { @@ -1179,7 +1148,7 @@ void EditorSettings::set_recent_dirs(const Vector<String> &p_recent_dirs) { if (Engine::get_singleton()->is_project_manager_hint()) { recent_dirs_file = EditorPaths::get_singleton()->get_config_dir().plus_file("recent_dirs"); } else { - recent_dirs_file = get_project_settings_dir().plus_file("recent_dirs"); + recent_dirs_file = EditorPaths::get_singleton()->get_project_settings_dir().plus_file("recent_dirs"); } Ref<FileAccess> f = FileAccess::open(recent_dirs_file, FileAccess::WRITE); if (f.is_valid()) { @@ -1200,8 +1169,8 @@ void EditorSettings::load_favorites_and_recent_dirs() { favorites_file = EditorPaths::get_singleton()->get_config_dir().plus_file("favorite_dirs"); recent_dirs_file = EditorPaths::get_singleton()->get_config_dir().plus_file("recent_dirs"); } else { - favorites_file = get_project_settings_dir().plus_file("favorites"); - recent_dirs_file = get_project_settings_dir().plus_file("recent_dirs"); + favorites_file = EditorPaths::get_singleton()->get_project_settings_dir().plus_file("favorites"); + recent_dirs_file = EditorPaths::get_singleton()->get_project_settings_dir().plus_file("recent_dirs"); } Ref<FileAccess> f = FileAccess::open(favorites_file, FileAccess::READ); if (f.is_valid()) { @@ -1233,7 +1202,7 @@ bool EditorSettings::is_dark_theme() { void EditorSettings::list_text_editor_themes() { String themes = "Default,Godot 2,Custom"; - Ref<DirAccess> d = DirAccess::open(get_text_editor_themes_dir()); + Ref<DirAccess> d = DirAccess::open(EditorPaths::get_singleton()->get_text_editor_themes_dir()); if (d.is_valid()) { List<String> custom_themes; d->list_dir_begin(); @@ -1264,7 +1233,7 @@ void EditorSettings::load_text_editor_theme() { return; // sorry for "Settings changed" console spam } - String theme_path = get_text_editor_themes_dir().plus_file(p_file + ".tet"); + String theme_path = EditorPaths::get_singleton()->get_text_editor_themes_dir().plus_file(p_file + ".tet"); Ref<ConfigFile> cf = memnew(ConfigFile); Error err = cf->load(theme_path); @@ -1299,9 +1268,9 @@ bool EditorSettings::import_text_editor_theme(String p_file) { return false; } - Ref<DirAccess> d = DirAccess::open(get_text_editor_themes_dir()); + Ref<DirAccess> d = DirAccess::open(EditorPaths::get_singleton()->get_text_editor_themes_dir()); if (d.is_valid()) { - d->copy(p_file, get_text_editor_themes_dir().plus_file(p_file.get_file())); + d->copy(p_file, EditorPaths::get_singleton()->get_text_editor_themes_dir().plus_file(p_file.get_file())); return true; } } @@ -1314,7 +1283,7 @@ bool EditorSettings::save_text_editor_theme() { if (_is_default_text_editor_theme(p_file.get_file().to_lower())) { return false; } - String theme_path = get_text_editor_themes_dir().plus_file(p_file + ".tet"); + String theme_path = EditorPaths::get_singleton()->get_text_editor_themes_dir().plus_file(p_file + ".tet"); return _save_text_editor_theme(theme_path); } @@ -1331,7 +1300,7 @@ bool EditorSettings::save_text_editor_theme_as(String p_file) { list_text_editor_themes(); String theme_name = p_file.substr(0, p_file.length() - 4).get_file(); - if (p_file.get_base_dir() == get_text_editor_themes_dir()) { + if (p_file.get_base_dir() == EditorPaths::get_singleton()->get_text_editor_themes_dir()) { _initial_set("text_editor/theme/color_theme", theme_name); load_text_editor_theme(); } @@ -1347,7 +1316,7 @@ bool EditorSettings::is_default_text_editor_theme() { Vector<String> EditorSettings::get_script_templates(const String &p_extension, const String &p_custom_path) { Vector<String> templates; - String template_dir = get_script_templates_dir(); + String template_dir = EditorPaths::get_singleton()->get_script_templates_dir(); if (!p_custom_path.is_empty()) { template_dir = p_custom_path; } @@ -1455,9 +1424,7 @@ void EditorSettings::get_shortcut_list(List<String> *r_shortcuts) { } Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path) { - if (!EditorSettings::get_singleton()) { - return nullptr; - } + ERR_FAIL_NULL_V_MSG(EditorSettings::get_singleton(), nullptr, "EditorSettings not instantiated yet."); Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path); @@ -1467,6 +1434,8 @@ Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path) { } void ED_SHORTCUT_OVERRIDE(const String &p_path, const String &p_feature, Key p_keycode) { + ERR_FAIL_NULL_MSG(EditorSettings::get_singleton(), "EditorSettings not instantiated yet."); + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path); ERR_FAIL_COND_MSG(!sc.is_valid(), "Used ED_SHORTCUT_OVERRIDE with invalid shortcut: " + p_path + "."); @@ -1477,6 +1446,8 @@ void ED_SHORTCUT_OVERRIDE(const String &p_path, const String &p_feature, Key p_k } void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, const PackedInt32Array &p_keycodes) { + ERR_FAIL_NULL_MSG(EditorSettings::get_singleton(), "EditorSettings not instantiated yet."); + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path); ERR_FAIL_COND_MSG(!sc.is_valid(), "Used ED_SHORTCUT_OVERRIDE_ARRAY with invalid shortcut: " + p_path + "."); @@ -1654,8 +1625,6 @@ void EditorSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &EditorSettings::property_get_revert); ClassDB::bind_method(D_METHOD("add_property_info", "info"), &EditorSettings::_add_property_info_bind); - ClassDB::bind_method(D_METHOD("get_project_settings_dir"), &EditorSettings::get_project_settings_dir); - ClassDB::bind_method(D_METHOD("set_project_metadata", "section", "key", "data"), &EditorSettings::set_project_metadata); ClassDB::bind_method(D_METHOD("get_project_metadata", "section", "key", "default"), &EditorSettings::get_project_metadata, DEFVAL(Variant())); diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 56c73685bb..5faeec88c8 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -88,8 +88,6 @@ private: mutable HashMap<String, Ref<Shortcut>> shortcuts; HashMap<String, List<Ref<InputEvent>>> builtin_action_overrides; - String config_file_path; - Vector<String> favorites; Vector<String> recent_dirs; @@ -150,14 +148,6 @@ public: void set_resource_clipboard(const Ref<Resource> &p_resource) { clipboard = p_resource; } Ref<Resource> get_resource_clipboard() const { return clipboard; } - String get_data_dir() const; - String get_export_templates_dir() const; - String get_project_settings_dir() const; - String get_text_editor_themes_dir() const; - String get_script_templates_dir() const; - String get_project_script_templates_dir() const; - String get_feature_profiles_dir() const; - void set_project_metadata(const String &p_section, const String &p_key, Variant p_data); Variant get_project_metadata(const String &p_section, const String &p_key, Variant p_default) const; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 5d60baf202..a3086a2ccf 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -641,6 +641,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Add a highlight line at the top of the selected tab. style_tab_selected->set_border_width_all(0); + style_tab_selected->set_default_margin(SIDE_LEFT, widget_default_margin.x - border_width); style_tab_selected->set_border_width(SIDE_TOP, Math::round(2 * EDSCALE)); // Make the highlight line prominent, but not too prominent as to not be distracting. Color tab_highlight = dark_color_2.lerp(accent_color, 0.75); @@ -653,6 +654,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // We can't prevent them with both rounded corners and non-zero border width, though style_tab_selected->set_expand_margin_size(SIDE_BOTTOM, corner_width > 0 ? corner_width : border_width); + // When using a border width greater than 0, visually line up the left of the selected tab with the underlying panel. + style_tab_selected->set_expand_margin_size(SIDE_LEFT, -border_width); + style_tab_selected->set_default_margin(SIDE_LEFT, widget_default_margin.x + 2 * EDSCALE); style_tab_selected->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 2 * EDSCALE); style_tab_selected->set_default_margin(SIDE_BOTTOM, widget_default_margin.y); @@ -830,6 +834,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("pressed", "CheckButton", style_menu); theme->set_stylebox("disabled", "CheckButton", style_menu); theme->set_stylebox("hover", "CheckButton", style_menu); + theme->set_stylebox("hover_pressed", "CheckButton", style_menu); theme->set_icon("on", "CheckButton", theme->get_icon(SNAME("GuiToggleOn"), SNAME("EditorIcons"))); theme->set_icon("on_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabled"), SNAME("EditorIcons"))); @@ -867,6 +872,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("pressed", "CheckBox", sb_checkbox); theme->set_stylebox("disabled", "CheckBox", sb_checkbox); theme->set_stylebox("hover", "CheckBox", sb_checkbox); + theme->set_stylebox("hover_pressed", "CheckBox", sb_checkbox); theme->set_icon("checked", "CheckBox", theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons"))); theme->set_icon("unchecked", "CheckBox", theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons"))); theme->set_icon("radio_checked", "CheckBox", theme->get_icon(SNAME("GuiRadioChecked"), SNAME("EditorIcons"))); @@ -895,17 +901,16 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("panel", "PopupDialog", style_popup); // PopupMenu - const int popup_menu_margin_size = default_margin_size * 1.5 * EDSCALE; Ref<StyleBoxFlat> style_popup_menu = style_popup->duplicate(); // Use 1 pixel for the sides, since if 0 is used, the highlight of hovered items is drawn // on top of the popup border. This causes a 'gap' in the panel border when an item is highlighted, // and it looks weird. 1px solves this. - style_popup_menu->set_default_margin(SIDE_LEFT, 1 * EDSCALE); - style_popup_menu->set_default_margin(SIDE_TOP, popup_menu_margin_size); - style_popup_menu->set_default_margin(SIDE_RIGHT, 1 * EDSCALE); - style_popup_menu->set_default_margin(SIDE_BOTTOM, popup_menu_margin_size); + style_popup_menu->set_default_margin(SIDE_LEFT, EDSCALE); + style_popup_menu->set_default_margin(SIDE_TOP, 2 * EDSCALE); + style_popup_menu->set_default_margin(SIDE_RIGHT, EDSCALE); + style_popup_menu->set_default_margin(SIDE_BOTTOM, 2 * EDSCALE); // Always display a border for PopupMenus so they can be distinguished from their background. - style_popup_menu->set_border_width_all(1 * EDSCALE); + style_popup_menu->set_border_width_all(EDSCALE); style_popup_menu->set_border_color(dark_color_2); theme->set_stylebox("panel", "PopupMenu", style_popup_menu); @@ -939,12 +944,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Force the v_separation to be even so that the spacing on top and bottom is even. // If the vsep is odd and cannot be split into 2 even groups (of pixels), then it will be lopsided. - // We add 2 to the vsep to give it some extra spacing which looks a bit more modern (see Windows, for example) - int vsep_base = extra_spacing + default_margin_size + 2; - int force_even_vsep = vsep_base + (vsep_base % 2); + // We add 2 to the vsep to give it some extra spacing which looks a bit more modern (see Windows, for example). + const int vsep_base = extra_spacing + default_margin_size + 6; + const int force_even_vsep = vsep_base + (vsep_base % 2); theme->set_constant("v_separation", "PopupMenu", force_even_vsep * EDSCALE); - theme->set_constant("item_start_padding", "PopupMenu", popup_menu_margin_size * EDSCALE); - theme->set_constant("item_end_padding", "PopupMenu", popup_menu_margin_size * EDSCALE); + theme->set_constant("item_start_padding", "PopupMenu", default_margin_size * 1.5 * EDSCALE); + theme->set_constant("item_end_padding", "PopupMenu", default_margin_size * 1.5 * EDSCALE); // Sub-inspectors for (int i = 0; i < 16; i++) { @@ -1660,6 +1665,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_dictionary_add_item->set_expand_margin_size(SIDE_RIGHT, 4 * EDSCALE); theme->set_stylebox("DictionaryAddItem", "EditorStyles", style_dictionary_add_item); + Ref<StyleBoxEmpty> vshader_label_style = make_empty_stylebox(2, 1, 2, 1); + theme->set_stylebox("label_style", "VShaderEditor", vshader_label_style); + // adaptive script theme constants // for comments and elements with lower relevance const Color dim_color = Color(font_color.r, font_color.g, font_color.b, 0.5); @@ -1669,17 +1677,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color alpha2 = Color(mono_value, mono_value, mono_value, 0.14); const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.27); - // editor main color - const Color main_color = dark_theme ? Color(0.34, 0.7, 1.0) : Color(0.02, 0.5, 1.0); - - const Color symbol_color = Color(0.34, 0.57, 1.0).lerp(mono_color, dark_theme ? 0.5 : 0.3); - const Color keyword_color = Color(1.0, 0.44, 0.52); - const Color control_flow_keyword_color = dark_theme ? Color(1.0, 0.55, 0.8) : Color(0.8, 0.4, 0.6); - const Color basetype_color = dark_theme ? Color(0.26, 1.0, 0.76) : Color(0.0, 0.76, 0.38); - const Color type_color = basetype_color.lerp(mono_color, dark_theme ? 0.4 : 0.3); - const Color usertype_color = basetype_color.lerp(mono_color, dark_theme ? 0.7 : 0.5); - const Color comment_color = dim_color; - const Color string_color = (dark_theme ? Color(1.0, 0.85, 0.26) : Color(1.0, 0.82, 0.09)).lerp(mono_color, dark_theme ? 0.5 : 0.3); + const Color symbol_color = dark_theme ? Color(0.67, 0.79, 1) : Color(0, 0, 0.61); + const Color keyword_color = dark_theme ? Color(1.0, 0.44, 0.52) : Color(0.9, 0.135, 0.51); + const Color control_flow_keyword_color = dark_theme ? Color(1.0, 0.55, 0.8) : Color(0.743, 0.12, 0.8); + const Color base_type_color = dark_theme ? Color(0.26, 1.0, 0.76) : Color(0, 0.6, 0.2); + const Color engine_type_color = dark_theme ? Color(0.56, 1, 0.86) : Color(0.11, 0.55, 0.4); + const Color user_type_color = dark_theme ? Color(0.78, 1, 0.93) : Color(0.18, 0.45, 0.4); + const Color comment_color = dark_theme ? dim_color : Color(0.08, 0.08, 0.08, 0.5); + const Color string_color = dark_theme ? Color(1, 0.93, 0.63) : Color(0.6, 0.42, 0); // Use the brightest background color on a light theme (which generally uses a negative contrast rate). const Color te_background_color = dark_theme ? background_color : dark_color_3; @@ -1692,24 +1697,24 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color completion_font_color = font_color; const Color text_color = font_color; const Color line_number_color = dim_color; - const Color safe_line_number_color = dim_color * Color(1, 1.2, 1, 1.5); + const Color safe_line_number_color = dark_theme ? (dim_color * Color(1, 1.2, 1, 1.5)) : Color(0, 0.4, 0, 0.75); const Color caret_color = mono_color; const Color caret_background_color = mono_color.inverted(); const Color text_selected_color = dark_color_3; - const Color brace_mismatch_color = error_color; + const Color brace_mismatch_color = dark_theme ? error_color : Color(1, 0.08, 0, 1); const Color current_line_color = alpha1; const Color line_length_guideline_color = dark_theme ? base_color : background_color; const Color word_highlighted_color = alpha1; - const Color number_color = basetype_color.lerp(mono_color, dark_theme ? 0.5 : 0.3); - const Color function_color = main_color; - const Color member_variable_color = main_color.lerp(mono_color, 0.6); + const Color number_color = dark_theme ? Color(0.63, 1, 0.88) : Color(0, 0.55, 0.28, 1); + const Color function_color = dark_theme ? Color(0.34, 0.7, 1.0) : Color(0, 0.225, 0.9, 1); + const Color member_variable_color = dark_theme ? Color(0.34, 0.7, 1.0).lerp(mono_color, 0.6) : Color(0, 0.4, 0.68, 1); const Color mark_color = Color(error_color.r, error_color.g, error_color.b, 0.3); const Color bookmark_color = Color(0.08, 0.49, 0.98); - const Color breakpoint_color = error_color; + const Color breakpoint_color = dark_theme ? error_color : Color(1, 0.27, 0.2, 1); const Color executing_line_color = Color(0.98, 0.89, 0.27); const Color code_folding_color = alpha3; const Color search_result_color = alpha1; - const Color search_result_border_color = Color(0.41, 0.61, 0.91, 0.38); + const Color search_result_border_color = dark_theme ? Color(0.41, 0.61, 0.91, 0.38) : Color(0, 0.4, 1, 0.38); EditorSettings *setting = EditorSettings::get_singleton(); String text_editor_color_theme = setting->get("text_editor/theme/color_theme"); @@ -1717,9 +1722,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { setting->set_initial_value("text_editor/theme/highlighting/symbol_color", symbol_color, true); setting->set_initial_value("text_editor/theme/highlighting/keyword_color", keyword_color, true); setting->set_initial_value("text_editor/theme/highlighting/control_flow_keyword_color", control_flow_keyword_color, true); - setting->set_initial_value("text_editor/theme/highlighting/base_type_color", basetype_color, true); - setting->set_initial_value("text_editor/theme/highlighting/engine_type_color", type_color, true); - setting->set_initial_value("text_editor/theme/highlighting/user_type_color", usertype_color, true); + setting->set_initial_value("text_editor/theme/highlighting/base_type_color", base_type_color, true); + setting->set_initial_value("text_editor/theme/highlighting/engine_type_color", engine_type_color, true); + setting->set_initial_value("text_editor/theme/highlighting/user_type_color", user_type_color, true); setting->set_initial_value("text_editor/theme/highlighting/comment_color", comment_color, true); setting->set_initial_value("text_editor/theme/highlighting/string_color", string_color, true); setting->set_initial_value("text_editor/theme/highlighting/background_color", te_background_color, true); diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp index 4986bccc35..050cde6069 100644 --- a/editor/editor_toaster.cpp +++ b/editor/editor_toaster.cpp @@ -356,7 +356,7 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_ break; } panel->set_modulate(Color(1, 1, 1, 0)); - panel->connect("draw", callable_bind(callable_mp(this, &EditorToaster::_draw_progress), panel)); + panel->connect("draw", callable_mp(this, &EditorToaster::_draw_progress).bind(panel)); // Horizontal container. HBoxContainer *hbox_container = memnew(HBoxContainer); @@ -372,8 +372,8 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_ Button *close_button = memnew(Button); close_button->set_flat(true); close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); - close_button->connect("pressed", callable_bind(callable_mp(this, &EditorToaster::close), panel)); - close_button->connect("theme_changed", callable_bind(callable_mp(this, &EditorToaster::_close_button_theme_changed), close_button)); + close_button->connect("pressed", callable_mp(this, &EditorToaster::close).bind(panel)); + close_button->connect("theme_changed", callable_mp(this, &EditorToaster::_close_button_theme_changed).bind(close_button)); hbox_container->add_child(close_button); } @@ -522,7 +522,7 @@ EditorToaster::EditorToaster() { main_button->set_modulate(Color(0.5, 0.5, 0.5)); main_button->set_disabled(true); main_button->set_flat(true); - main_button->connect("pressed", callable_mp(this, &EditorToaster::_set_notifications_enabled), varray(true)); + main_button->connect("pressed", callable_mp(this, &EditorToaster::_set_notifications_enabled).bind(true)); main_button->connect("pressed", callable_mp(this, &EditorToaster::_repop_old)); main_button->connect("draw", callable_mp(this, &EditorToaster::_draw_button)); add_child(main_button); @@ -536,7 +536,7 @@ EditorToaster::EditorToaster() { disable_notifications_button = memnew(Button); disable_notifications_button->set_tooltip(TTR("Silence the notifications.")); disable_notifications_button->set_flat(true); - disable_notifications_button->connect("pressed", callable_mp(this, &EditorToaster::_set_notifications_enabled), varray(false)); + disable_notifications_button->connect("pressed", callable_mp(this, &EditorToaster::_set_notifications_enabled).bind(false)); disable_notifications_panel->add_child(disable_notifications_button); // Other diff --git a/editor/export/SCsub b/editor/export/SCsub new file mode 100644 index 0000000000..359d04e5df --- /dev/null +++ b/editor/export/SCsub @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +Import("env") + +env.add_source_files(env.editor_sources, "*.cpp") diff --git a/editor/export/editor_export.cpp b/editor/export/editor_export.cpp new file mode 100644 index 0000000000..31f408eedb --- /dev/null +++ b/editor/export/editor_export.cpp @@ -0,0 +1,355 @@ +/*************************************************************************/ +/* editor_export.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_export.h" + +#include "core/config/project_settings.h" +#include "core/io/config_file.h" + +EditorExport *EditorExport::singleton = nullptr; + +void EditorExport::_save() { + Ref<ConfigFile> config; + config.instantiate(); + for (int i = 0; i < export_presets.size(); i++) { + Ref<EditorExportPreset> preset = export_presets[i]; + String section = "preset." + itos(i); + + config->set_value(section, "name", preset->get_name()); + config->set_value(section, "platform", preset->get_platform()->get_name()); + config->set_value(section, "runnable", preset->is_runnable()); + config->set_value(section, "custom_features", preset->get_custom_features()); + + bool save_files = false; + switch (preset->get_export_filter()) { + case EditorExportPreset::EXPORT_ALL_RESOURCES: { + config->set_value(section, "export_filter", "all_resources"); + } break; + case EditorExportPreset::EXPORT_SELECTED_SCENES: { + config->set_value(section, "export_filter", "scenes"); + save_files = true; + } break; + case EditorExportPreset::EXPORT_SELECTED_RESOURCES: { + config->set_value(section, "export_filter", "resources"); + save_files = true; + } break; + case EditorExportPreset::EXCLUDE_SELECTED_RESOURCES: { + config->set_value(section, "export_filter", "exclude"); + save_files = true; + } break; + } + + if (save_files) { + Vector<String> export_files = preset->get_files_to_export(); + config->set_value(section, "export_files", export_files); + } + config->set_value(section, "include_filter", preset->get_include_filter()); + config->set_value(section, "exclude_filter", preset->get_exclude_filter()); + config->set_value(section, "export_path", preset->get_export_path()); + config->set_value(section, "encryption_include_filters", preset->get_enc_in_filter()); + config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter()); + config->set_value(section, "encrypt_pck", preset->get_enc_pck()); + config->set_value(section, "encrypt_directory", preset->get_enc_directory()); + config->set_value(section, "script_export_mode", preset->get_script_export_mode()); + config->set_value(section, "script_encryption_key", preset->get_script_encryption_key()); + + String option_section = "preset." + itos(i) + ".options"; + + for (const PropertyInfo &E : preset->get_properties()) { + config->set_value(option_section, E.name, preset->get(E.name)); + } + } + + config->save("res://export_presets.cfg"); +} + +void EditorExport::save_presets() { + if (block_save) { + return; + } + save_timer->start(); +} + +void EditorExport::_bind_methods() { + ADD_SIGNAL(MethodInfo("export_presets_updated")); +} + +void EditorExport::add_export_platform(const Ref<EditorExportPlatform> &p_platform) { + export_platforms.push_back(p_platform); +} + +int EditorExport::get_export_platform_count() { + return export_platforms.size(); +} + +Ref<EditorExportPlatform> EditorExport::get_export_platform(int p_idx) { + ERR_FAIL_INDEX_V(p_idx, export_platforms.size(), Ref<EditorExportPlatform>()); + + return export_platforms[p_idx]; +} + +void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, int p_at_pos) { + if (p_at_pos < 0) { + export_presets.push_back(p_preset); + } else { + export_presets.insert(p_at_pos, p_preset); + } +} + +String EditorExportPlatform::test_etc2() const { + const bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2"); + + if (!etc2_supported) { + return TTR("Target platform requires 'ETC2' texture compression. Enable 'Import Etc 2' in Project Settings."); + } + + return String(); +} + +int EditorExport::get_export_preset_count() const { + return export_presets.size(); +} + +Ref<EditorExportPreset> EditorExport::get_export_preset(int p_idx) { + ERR_FAIL_INDEX_V(p_idx, export_presets.size(), Ref<EditorExportPreset>()); + return export_presets[p_idx]; +} + +void EditorExport::remove_export_preset(int p_idx) { + export_presets.remove_at(p_idx); + save_presets(); +} + +void EditorExport::add_export_plugin(const Ref<EditorExportPlugin> &p_plugin) { + if (!export_plugins.has(p_plugin)) { + export_plugins.push_back(p_plugin); + } +} + +void EditorExport::remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin) { + export_plugins.erase(p_plugin); +} + +Vector<Ref<EditorExportPlugin>> EditorExport::get_export_plugins() { + return export_plugins; +} + +void EditorExport::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + load_config(); + } break; + + case NOTIFICATION_PROCESS: { + update_export_presets(); + } break; + } +} + +void EditorExport::load_config() { + Ref<ConfigFile> config; + config.instantiate(); + Error err = config->load("res://export_presets.cfg"); + if (err != OK) { + return; + } + + block_save = true; + + int index = 0; + while (true) { + String section = "preset." + itos(index); + if (!config->has_section(section)) { + break; + } + + String platform = config->get_value(section, "platform"); + + Ref<EditorExportPreset> preset; + + for (int i = 0; i < export_platforms.size(); i++) { + if (export_platforms[i]->get_name() == platform) { + preset = export_platforms.write[i]->create_preset(); + break; + } + } + + if (!preset.is_valid()) { + index++; + ERR_CONTINUE(!preset.is_valid()); + } + + preset->set_name(config->get_value(section, "name")); + preset->set_runnable(config->get_value(section, "runnable")); + + if (config->has_section_key(section, "custom_features")) { + preset->set_custom_features(config->get_value(section, "custom_features")); + } + + String export_filter = config->get_value(section, "export_filter"); + + bool get_files = false; + + if (export_filter == "all_resources") { + preset->set_export_filter(EditorExportPreset::EXPORT_ALL_RESOURCES); + } else if (export_filter == "scenes") { + preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_SCENES); + get_files = true; + } else if (export_filter == "resources") { + preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_RESOURCES); + get_files = true; + } else if (export_filter == "exclude") { + preset->set_export_filter(EditorExportPreset::EXCLUDE_SELECTED_RESOURCES); + get_files = true; + } + + if (get_files) { + Vector<String> files = config->get_value(section, "export_files"); + + for (int i = 0; i < files.size(); i++) { + if (!FileAccess::exists(files[i])) { + preset->remove_export_file(files[i]); + } else { + preset->add_export_file(files[i]); + } + } + } + + preset->set_include_filter(config->get_value(section, "include_filter")); + preset->set_exclude_filter(config->get_value(section, "exclude_filter")); + preset->set_export_path(config->get_value(section, "export_path", "")); + + if (config->has_section_key(section, "encrypt_pck")) { + preset->set_enc_pck(config->get_value(section, "encrypt_pck")); + } + if (config->has_section_key(section, "encrypt_directory")) { + preset->set_enc_directory(config->get_value(section, "encrypt_directory")); + } + if (config->has_section_key(section, "encryption_include_filters")) { + preset->set_enc_in_filter(config->get_value(section, "encryption_include_filters")); + } + if (config->has_section_key(section, "encryption_exclude_filters")) { + preset->set_enc_ex_filter(config->get_value(section, "encryption_exclude_filters")); + } + if (config->has_section_key(section, "script_export_mode")) { + preset->set_script_export_mode(config->get_value(section, "script_export_mode")); + } + if (config->has_section_key(section, "script_encryption_key")) { + preset->set_script_encryption_key(config->get_value(section, "script_encryption_key")); + } + + String option_section = "preset." + itos(index) + ".options"; + + List<String> options; + + config->get_section_keys(option_section, &options); + + for (const String &E : options) { + Variant value = config->get_value(option_section, E); + + preset->set(E, value); + } + + add_export_preset(preset); + index++; + } + + block_save = false; +} + +void EditorExport::update_export_presets() { + HashMap<StringName, List<EditorExportPlatform::ExportOption>> platform_options; + + for (int i = 0; i < export_platforms.size(); i++) { + Ref<EditorExportPlatform> platform = export_platforms[i]; + + if (platform->should_update_export_options()) { + List<EditorExportPlatform::ExportOption> options; + platform->get_export_options(&options); + + platform_options[platform->get_name()] = options; + } + } + + bool export_presets_updated = false; + for (int i = 0; i < export_presets.size(); i++) { + Ref<EditorExportPreset> preset = export_presets[i]; + if (platform_options.has(preset->get_platform()->get_name())) { + export_presets_updated = true; + + List<EditorExportPlatform::ExportOption> options = platform_options[preset->get_platform()->get_name()]; + + // Copy the previous preset values + HashMap<StringName, Variant> previous_values = preset->values; + + // Clear the preset properties and values prior to reloading + preset->properties.clear(); + preset->values.clear(); + + for (const EditorExportPlatform::ExportOption &E : options) { + preset->properties.push_back(E.option); + + StringName option_name = E.option.name; + preset->values[option_name] = previous_values.has(option_name) ? previous_values[option_name] : E.default_value; + } + } + } + + if (export_presets_updated) { + emit_signal(_export_presets_updated); + } +} + +bool EditorExport::poll_export_platforms() { + bool changed = false; + for (int i = 0; i < export_platforms.size(); i++) { + if (export_platforms.write[i]->poll_export()) { + changed = true; + } + } + + return changed; +} + +EditorExport::EditorExport() { + save_timer = memnew(Timer); + add_child(save_timer); + save_timer->set_wait_time(0.8); + save_timer->set_one_shot(true); + save_timer->connect("timeout", callable_mp(this, &EditorExport::_save)); + + _export_presets_updated = "export_presets_updated"; + + singleton = this; + set_process(true); +} + +EditorExport::~EditorExport() { +} diff --git a/editor/export/editor_export.h b/editor/export/editor_export.h new file mode 100644 index 0000000000..13c3c34cea --- /dev/null +++ b/editor/export/editor_export.h @@ -0,0 +1,84 @@ +/*************************************************************************/ +/* editor_export.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_EXPORT_H +#define EDITOR_EXPORT_H + +#include "editor_export_platform.h" +#include "editor_export_plugin.h" + +class EditorExport : public Node { + GDCLASS(EditorExport, Node); + + Vector<Ref<EditorExportPlatform>> export_platforms; + Vector<Ref<EditorExportPreset>> export_presets; + Vector<Ref<EditorExportPlugin>> export_plugins; + + StringName _export_presets_updated; + + Timer *save_timer = nullptr; + bool block_save = false; + + static EditorExport *singleton; + + void _save(); + +protected: + friend class EditorExportPreset; + void save_presets(); + + void _notification(int p_what); + static void _bind_methods(); + +public: + static EditorExport *get_singleton() { return singleton; } + + void add_export_platform(const Ref<EditorExportPlatform> &p_platform); + int get_export_platform_count(); + Ref<EditorExportPlatform> get_export_platform(int p_idx); + + void add_export_preset(const Ref<EditorExportPreset> &p_preset, int p_at_pos = -1); + int get_export_preset_count() const; + Ref<EditorExportPreset> get_export_preset(int p_idx); + void remove_export_preset(int p_idx); + + void add_export_plugin(const Ref<EditorExportPlugin> &p_plugin); + void remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin); + Vector<Ref<EditorExportPlugin>> get_export_plugins(); + + void load_config(); + void update_export_presets(); + bool poll_export_platforms(); + + EditorExport(); + ~EditorExport(); +}; + +#endif // EDITOR_EXPORT_H diff --git a/editor/editor_export.cpp b/editor/export/editor_export_platform.cpp index b09339ce3a..34b407779e 100644 --- a/editor/editor_export.cpp +++ b/editor/export/editor_export_platform.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* editor_export.cpp */ +/* editor_export_platform.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,20 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "editor_export.h" +#include "editor_export_platform.h" #include "core/config/project_settings.h" #include "core/crypto/crypto_core.h" #include "core/extension/native_extension.h" -#include "core/io/config_file.h" -#include "core/io/dir_access.h" -#include "core/io/file_access.h" #include "core/io/file_access_encrypted.h" #include "core/io/file_access_pack.h" // PACK_HEADER_MAGIC, PACK_FORMAT_VERSION -#include "core/io/resource_loader.h" -#include "core/io/resource_saver.h" #include "core/io/zip_io.h" -#include "core/object/script_language.h" #include "core/version.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" @@ -49,7 +43,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/plugins/script_editor_plugin.h" -#include "scene/resources/resource_format_text.h" +#include "editor_export_plugin.h" static int _get_pad(int p_alignment, int p_n) { int rest = p_n % p_alignment; @@ -63,196 +57,6 @@ static int _get_pad(int p_alignment, int p_n) { #define PCK_PADDING 16 -bool EditorExportPreset::_set(const StringName &p_name, const Variant &p_value) { - if (values.has(p_name)) { - values[p_name] = p_value; - EditorExport::singleton->save_presets(); - return true; - } - - return false; -} - -bool EditorExportPreset::_get(const StringName &p_name, Variant &r_ret) const { - if (values.has(p_name)) { - r_ret = values[p_name]; - return true; - } - - return false; -} - -void EditorExportPreset::_get_property_list(List<PropertyInfo> *p_list) const { - for (const PropertyInfo &E : properties) { - if (platform->get_export_option_visibility(E.name, values)) { - p_list->push_back(E); - } - } -} - -Ref<EditorExportPlatform> EditorExportPreset::get_platform() const { - return platform; -} - -void EditorExportPreset::update_files_to_export() { - Vector<String> to_remove; - for (const String &E : selected_files) { - if (!FileAccess::exists(E)) { - to_remove.push_back(E); - } - } - for (int i = 0; i < to_remove.size(); ++i) { - selected_files.erase(to_remove[i]); - } -} - -Vector<String> EditorExportPreset::get_files_to_export() const { - Vector<String> files; - for (const String &E : selected_files) { - files.push_back(E); - } - return files; -} - -void EditorExportPreset::set_name(const String &p_name) { - name = p_name; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_name() const { - return name; -} - -void EditorExportPreset::set_runnable(bool p_enable) { - runnable = p_enable; - EditorExport::singleton->save_presets(); -} - -bool EditorExportPreset::is_runnable() const { - return runnable; -} - -void EditorExportPreset::set_export_filter(ExportFilter p_filter) { - export_filter = p_filter; - EditorExport::singleton->save_presets(); -} - -EditorExportPreset::ExportFilter EditorExportPreset::get_export_filter() const { - return export_filter; -} - -void EditorExportPreset::set_include_filter(const String &p_include) { - include_filter = p_include; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_include_filter() const { - return include_filter; -} - -void EditorExportPreset::set_export_path(const String &p_path) { - export_path = p_path; - /* NOTE(SonerSound): if there is a need to implement a PropertyHint that specifically indicates a relative path, - * this should be removed. */ - if (export_path.is_absolute_path()) { - String res_path = OS::get_singleton()->get_resource_dir(); - export_path = res_path.path_to_file(export_path); - } - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_export_path() const { - return export_path; -} - -void EditorExportPreset::set_exclude_filter(const String &p_exclude) { - exclude_filter = p_exclude; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_exclude_filter() const { - return exclude_filter; -} - -void EditorExportPreset::add_export_file(const String &p_path) { - selected_files.insert(p_path); - EditorExport::singleton->save_presets(); -} - -void EditorExportPreset::remove_export_file(const String &p_path) { - selected_files.erase(p_path); - EditorExport::singleton->save_presets(); -} - -bool EditorExportPreset::has_export_file(const String &p_path) { - return selected_files.has(p_path); -} - -void EditorExportPreset::set_custom_features(const String &p_custom_features) { - custom_features = p_custom_features; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_custom_features() const { - return custom_features; -} - -void EditorExportPreset::set_enc_in_filter(const String &p_filter) { - enc_in_filters = p_filter; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_enc_in_filter() const { - return enc_in_filters; -} - -void EditorExportPreset::set_enc_ex_filter(const String &p_filter) { - enc_ex_filters = p_filter; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_enc_ex_filter() const { - return enc_ex_filters; -} - -void EditorExportPreset::set_enc_pck(bool p_enabled) { - enc_pck = p_enabled; - EditorExport::singleton->save_presets(); -} - -bool EditorExportPreset::get_enc_pck() const { - return enc_pck; -} - -void EditorExportPreset::set_enc_directory(bool p_enabled) { - enc_directory = p_enabled; - EditorExport::singleton->save_presets(); -} - -bool EditorExportPreset::get_enc_directory() const { - return enc_directory; -} - -void EditorExportPreset::set_script_export_mode(int p_mode) { - script_mode = p_mode; - EditorExport::singleton->save_presets(); -} - -int EditorExportPreset::get_script_export_mode() const { - return script_mode; -} - -void EditorExportPreset::set_script_encryption_key(const String &p_key) { - script_key = p_key; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_script_encryption_key() const { - return script_key; -} - -/////////////////////////////////// - bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err) { bool has_messages = false; @@ -267,12 +71,12 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err) if (get_worst_message_type() >= EditorExportPlatform::EXPORT_MESSAGE_WARNING) { p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER); p_log->add_text(" "); - p_log->add_text(TTR("Completed with errors.")); + p_log->add_text(TTR("Completed with warnings.")); has_messages = true; } else { p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER); p_log->add_text(" "); - p_log->add_text(TTR("Completed successfully.")); + p_log->add_text(TTR("Completed sucessfully.")); if (msg_count > 0) { has_messages = true; } @@ -491,7 +295,7 @@ Ref<ImageTexture> EditorExportPlatform::get_option_icon(int p_index) const { String EditorExportPlatform::find_export_template(String template_file_name, String *err) const { String current_version = VERSION_FULL_CONFIG; - String template_path = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(current_version).plus_file(template_file_name); + String template_path = EditorPaths::get_singleton()->get_export_templates_dir().plus_file(current_version).plus_file(template_file_name); if (FileAccess::exists(template_path)) { return template_path; @@ -625,139 +429,7 @@ void EditorExportPlatform::_edit_filter_list(HashSet<String> &r_list, const Stri _edit_files_with_filter(da, filters, r_list, exclude); } -void EditorExportPlugin::set_export_preset(const Ref<EditorExportPreset> &p_preset) { - if (p_preset.is_valid()) { - export_preset = p_preset; - } -} - -Ref<EditorExportPreset> EditorExportPlugin::get_export_preset() const { - return export_preset; -} - -void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap) { - ExtraFile ef; - ef.data = p_file; - ef.path = p_path; - ef.remap = p_remap; - extra_files.push_back(ef); -} - -void EditorExportPlugin::add_shared_object(const String &p_path, const Vector<String> &p_tags, const String &p_target) { - shared_objects.push_back(SharedObject(p_path, p_tags, p_target)); -} - -void EditorExportPlugin::add_ios_framework(const String &p_path) { - ios_frameworks.push_back(p_path); -} - -void EditorExportPlugin::add_ios_embedded_framework(const String &p_path) { - ios_embedded_frameworks.push_back(p_path); -} - -Vector<String> EditorExportPlugin::get_ios_frameworks() const { - return ios_frameworks; -} - -Vector<String> EditorExportPlugin::get_ios_embedded_frameworks() const { - return ios_embedded_frameworks; -} - -void EditorExportPlugin::add_ios_plist_content(const String &p_plist_content) { - ios_plist_content += p_plist_content + "\n"; -} - -String EditorExportPlugin::get_ios_plist_content() const { - return ios_plist_content; -} - -void EditorExportPlugin::add_ios_linker_flags(const String &p_flags) { - if (ios_linker_flags.length() > 0) { - ios_linker_flags += ' '; - } - ios_linker_flags += p_flags; -} - -String EditorExportPlugin::get_ios_linker_flags() const { - return ios_linker_flags; -} - -void EditorExportPlugin::add_ios_bundle_file(const String &p_path) { - ios_bundle_files.push_back(p_path); -} - -Vector<String> EditorExportPlugin::get_ios_bundle_files() const { - return ios_bundle_files; -} - -void EditorExportPlugin::add_ios_cpp_code(const String &p_code) { - ios_cpp_code += p_code; -} - -String EditorExportPlugin::get_ios_cpp_code() const { - return ios_cpp_code; -} - -void EditorExportPlugin::add_macos_plugin_file(const String &p_path) { - macos_plugin_files.push_back(p_path); -} - -const Vector<String> &EditorExportPlugin::get_macos_plugin_files() const { - return macos_plugin_files; -} - -void EditorExportPlugin::add_ios_project_static_lib(const String &p_path) { - ios_project_static_libs.push_back(p_path); -} - -Vector<String> EditorExportPlugin::get_ios_project_static_libs() const { - return ios_project_static_libs; -} - -void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features) { - GDVIRTUAL_CALL(_export_file, p_path, p_type, p_features); -} - -void EditorExportPlugin::_export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags) { - GDVIRTUAL_CALL(_export_begin, p_features, p_debug, p_path, p_flags); -} - -void EditorExportPlugin::_export_end_script() { - GDVIRTUAL_CALL(_export_end); -} - -void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { -} - -void EditorExportPlugin::_export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags) { -} - -void EditorExportPlugin::skip() { - skipped = true; -} - -void EditorExportPlugin::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags", "target"), &EditorExportPlugin::add_shared_object); - ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_ios_project_static_lib); - ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file); - ClassDB::bind_method(D_METHOD("add_ios_framework", "path"), &EditorExportPlugin::add_ios_framework); - ClassDB::bind_method(D_METHOD("add_ios_embedded_framework", "path"), &EditorExportPlugin::add_ios_embedded_framework); - ClassDB::bind_method(D_METHOD("add_ios_plist_content", "plist_content"), &EditorExportPlugin::add_ios_plist_content); - ClassDB::bind_method(D_METHOD("add_ios_linker_flags", "flags"), &EditorExportPlugin::add_ios_linker_flags); - ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_ios_bundle_file); - ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code); - ClassDB::bind_method(D_METHOD("add_macos_plugin_file", "path"), &EditorExportPlugin::add_macos_plugin_file); - ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip); - - GDVIRTUAL_BIND(_export_file, "path", "type", "features"); - GDVIRTUAL_BIND(_export_begin, "features", "is_debug", "path", "flags"); - GDVIRTUAL_BIND(_export_end); -} - -EditorExportPlugin::EditorExportPlugin() { -} - -EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug) { +EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug) const { Ref<EditorExportPlatform> platform = p_preset->get_platform(); List<String> feature_list; platform->get_platform_features(&feature_list); @@ -1504,573 +1176,3 @@ void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags EditorExportPlatform::EditorExportPlatform() { } - -//// - -EditorExport *EditorExport::singleton = nullptr; - -void EditorExport::_save() { - Ref<ConfigFile> config; - config.instantiate(); - for (int i = 0; i < export_presets.size(); i++) { - Ref<EditorExportPreset> preset = export_presets[i]; - String section = "preset." + itos(i); - - config->set_value(section, "name", preset->get_name()); - config->set_value(section, "platform", preset->get_platform()->get_name()); - config->set_value(section, "runnable", preset->is_runnable()); - config->set_value(section, "custom_features", preset->get_custom_features()); - - bool save_files = false; - switch (preset->get_export_filter()) { - case EditorExportPreset::EXPORT_ALL_RESOURCES: { - config->set_value(section, "export_filter", "all_resources"); - } break; - case EditorExportPreset::EXPORT_SELECTED_SCENES: { - config->set_value(section, "export_filter", "scenes"); - save_files = true; - } break; - case EditorExportPreset::EXPORT_SELECTED_RESOURCES: { - config->set_value(section, "export_filter", "resources"); - save_files = true; - } break; - case EditorExportPreset::EXCLUDE_SELECTED_RESOURCES: { - config->set_value(section, "export_filter", "exclude"); - save_files = true; - } break; - } - - if (save_files) { - Vector<String> export_files = preset->get_files_to_export(); - config->set_value(section, "export_files", export_files); - } - config->set_value(section, "include_filter", preset->get_include_filter()); - config->set_value(section, "exclude_filter", preset->get_exclude_filter()); - config->set_value(section, "export_path", preset->get_export_path()); - config->set_value(section, "encryption_include_filters", preset->get_enc_in_filter()); - config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter()); - config->set_value(section, "encrypt_pck", preset->get_enc_pck()); - config->set_value(section, "encrypt_directory", preset->get_enc_directory()); - config->set_value(section, "script_export_mode", preset->get_script_export_mode()); - config->set_value(section, "script_encryption_key", preset->get_script_encryption_key()); - - String option_section = "preset." + itos(i) + ".options"; - - for (const PropertyInfo &E : preset->get_properties()) { - config->set_value(option_section, E.name, preset->get(E.name)); - } - } - - config->save("res://export_presets.cfg"); -} - -void EditorExport::save_presets() { - if (block_save) { - return; - } - save_timer->start(); -} - -void EditorExport::_bind_methods() { - ADD_SIGNAL(MethodInfo("export_presets_updated")); -} - -void EditorExport::add_export_platform(const Ref<EditorExportPlatform> &p_platform) { - export_platforms.push_back(p_platform); -} - -int EditorExport::get_export_platform_count() { - return export_platforms.size(); -} - -Ref<EditorExportPlatform> EditorExport::get_export_platform(int p_idx) { - ERR_FAIL_INDEX_V(p_idx, export_platforms.size(), Ref<EditorExportPlatform>()); - - return export_platforms[p_idx]; -} - -void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, int p_at_pos) { - if (p_at_pos < 0) { - export_presets.push_back(p_preset); - } else { - export_presets.insert(p_at_pos, p_preset); - } -} - -String EditorExportPlatform::test_etc2() const { - const bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2"); - - if (!etc2_supported) { - return TTR("Target platform requires 'ETC2' texture compression. Enable 'Import Etc 2' in Project Settings."); - } - - return String(); -} - -int EditorExport::get_export_preset_count() const { - return export_presets.size(); -} - -Ref<EditorExportPreset> EditorExport::get_export_preset(int p_idx) { - ERR_FAIL_INDEX_V(p_idx, export_presets.size(), Ref<EditorExportPreset>()); - return export_presets[p_idx]; -} - -void EditorExport::remove_export_preset(int p_idx) { - export_presets.remove_at(p_idx); - save_presets(); -} - -void EditorExport::add_export_plugin(const Ref<EditorExportPlugin> &p_plugin) { - if (!export_plugins.has(p_plugin)) { - export_plugins.push_back(p_plugin); - } -} - -void EditorExport::remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin) { - export_plugins.erase(p_plugin); -} - -Vector<Ref<EditorExportPlugin>> EditorExport::get_export_plugins() { - return export_plugins; -} - -void EditorExport::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - load_config(); - } break; - - case NOTIFICATION_PROCESS: { - update_export_presets(); - } break; - } -} - -void EditorExport::load_config() { - Ref<ConfigFile> config; - config.instantiate(); - Error err = config->load("res://export_presets.cfg"); - if (err != OK) { - return; - } - - block_save = true; - - int index = 0; - while (true) { - String section = "preset." + itos(index); - if (!config->has_section(section)) { - break; - } - - String platform = config->get_value(section, "platform"); - - Ref<EditorExportPreset> preset; - - for (int i = 0; i < export_platforms.size(); i++) { - if (export_platforms[i]->get_name() == platform) { - preset = export_platforms.write[i]->create_preset(); - break; - } - } - - if (!preset.is_valid()) { - index++; - ERR_CONTINUE(!preset.is_valid()); - } - - preset->set_name(config->get_value(section, "name")); - preset->set_runnable(config->get_value(section, "runnable")); - - if (config->has_section_key(section, "custom_features")) { - preset->set_custom_features(config->get_value(section, "custom_features")); - } - - String export_filter = config->get_value(section, "export_filter"); - - bool get_files = false; - - if (export_filter == "all_resources") { - preset->set_export_filter(EditorExportPreset::EXPORT_ALL_RESOURCES); - } else if (export_filter == "scenes") { - preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_SCENES); - get_files = true; - } else if (export_filter == "resources") { - preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_RESOURCES); - get_files = true; - } else if (export_filter == "exclude") { - preset->set_export_filter(EditorExportPreset::EXCLUDE_SELECTED_RESOURCES); - get_files = true; - } - - if (get_files) { - Vector<String> files = config->get_value(section, "export_files"); - - for (int i = 0; i < files.size(); i++) { - if (!FileAccess::exists(files[i])) { - preset->remove_export_file(files[i]); - } else { - preset->add_export_file(files[i]); - } - } - } - - preset->set_include_filter(config->get_value(section, "include_filter")); - preset->set_exclude_filter(config->get_value(section, "exclude_filter")); - preset->set_export_path(config->get_value(section, "export_path", "")); - - if (config->has_section_key(section, "encrypt_pck")) { - preset->set_enc_pck(config->get_value(section, "encrypt_pck")); - } - if (config->has_section_key(section, "encrypt_directory")) { - preset->set_enc_directory(config->get_value(section, "encrypt_directory")); - } - if (config->has_section_key(section, "encryption_include_filters")) { - preset->set_enc_in_filter(config->get_value(section, "encryption_include_filters")); - } - if (config->has_section_key(section, "encryption_exclude_filters")) { - preset->set_enc_ex_filter(config->get_value(section, "encryption_exclude_filters")); - } - if (config->has_section_key(section, "script_export_mode")) { - preset->set_script_export_mode(config->get_value(section, "script_export_mode")); - } - if (config->has_section_key(section, "script_encryption_key")) { - preset->set_script_encryption_key(config->get_value(section, "script_encryption_key")); - } - - String option_section = "preset." + itos(index) + ".options"; - - List<String> options; - - config->get_section_keys(option_section, &options); - - for (const String &E : options) { - Variant value = config->get_value(option_section, E); - - preset->set(E, value); - } - - add_export_preset(preset); - index++; - } - - block_save = false; -} - -void EditorExport::update_export_presets() { - HashMap<StringName, List<EditorExportPlatform::ExportOption>> platform_options; - - for (int i = 0; i < export_platforms.size(); i++) { - Ref<EditorExportPlatform> platform = export_platforms[i]; - - if (platform->should_update_export_options()) { - List<EditorExportPlatform::ExportOption> options; - platform->get_export_options(&options); - - platform_options[platform->get_name()] = options; - } - } - - bool export_presets_updated = false; - for (int i = 0; i < export_presets.size(); i++) { - Ref<EditorExportPreset> preset = export_presets[i]; - if (platform_options.has(preset->get_platform()->get_name())) { - export_presets_updated = true; - - List<EditorExportPlatform::ExportOption> options = platform_options[preset->get_platform()->get_name()]; - - // Copy the previous preset values - HashMap<StringName, Variant> previous_values = preset->values; - - // Clear the preset properties and values prior to reloading - preset->properties.clear(); - preset->values.clear(); - - for (const EditorExportPlatform::ExportOption &E : options) { - preset->properties.push_back(E.option); - - StringName option_name = E.option.name; - preset->values[option_name] = previous_values.has(option_name) ? previous_values[option_name] : E.default_value; - } - } - } - - if (export_presets_updated) { - emit_signal(_export_presets_updated); - } -} - -bool EditorExport::poll_export_platforms() { - bool changed = false; - for (int i = 0; i < export_platforms.size(); i++) { - if (export_platforms.write[i]->poll_export()) { - changed = true; - } - } - - return changed; -} - -EditorExport::EditorExport() { - save_timer = memnew(Timer); - add_child(save_timer); - save_timer->set_wait_time(0.8); - save_timer->set_one_shot(true); - save_timer->connect("timeout", callable_mp(this, &EditorExport::_save)); - - _export_presets_updated = "export_presets_updated"; - - singleton = this; - set_process(true); -} - -EditorExport::~EditorExport() { -} - -////////// - -void EditorExportPlatformPC::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { - if (p_preset->get("texture_format/s3tc")) { - r_features->push_back("s3tc"); - } - if (p_preset->get("texture_format/etc")) { - r_features->push_back("etc"); - } - if (p_preset->get("texture_format/etc2")) { - r_features->push_back("etc2"); - } - - if (p_preset->get("binary_format/64_bits")) { - r_features->push_back("64"); - } else { - r_features->push_back("32"); - } -} - -void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) { - String ext_filter = (get_os_name() == "Windows") ? "*.exe" : ""; - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, ext_filter), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, ext_filter), "")); - - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "debug/export_console_script", PROPERTY_HINT_ENUM, "No,Debug Only,Debug and Release"), 1)); - - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/64_bits"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/embed_pck"), false)); - - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/bptc"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/no_bptc_fallbacks"), true)); -} - -String EditorExportPlatformPC::get_name() const { - return name; -} - -String EditorExportPlatformPC::get_os_name() const { - return os_name; -} - -Ref<Texture2D> EditorExportPlatformPC::get_logo() const { - return logo; -} - -bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { - String err; - bool valid = false; - - // Look for export templates (first official, and if defined custom templates). - - bool use64 = p_preset->get("binary_format/64_bits"); - bool dvalid = exists_export_template(get_template_file_name("debug", use64 ? "x86_64" : "x86_32"), &err); - bool rvalid = exists_export_template(get_template_file_name("release", use64 ? "x86_64" : "x86_32"), &err); - - if (p_preset->get("custom_template/debug") != "") { - dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); - if (!dvalid) { - err += TTR("Custom debug template not found.") + "\n"; - } - } - if (p_preset->get("custom_template/release") != "") { - rvalid = FileAccess::exists(p_preset->get("custom_template/release")); - if (!rvalid) { - err += TTR("Custom release template not found.") + "\n"; - } - } - - valid = dvalid || rvalid; - r_missing_templates = !valid; - - if (!err.is_empty()) { - r_error = err; - } - return valid; -} - -Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { - ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags); - - Error err = prepare_template(p_preset, p_debug, p_path, p_flags); - if (err == OK) { - err = modify_template(p_preset, p_debug, p_path, p_flags); - } - if (err == OK) { - err = export_project_data(p_preset, p_debug, p_path, p_flags); - } - - return err; -} - -Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { - if (!DirAccess::exists(p_path.get_base_dir())) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("The given export path doesn't exist.")); - return ERR_FILE_BAD_PATH; - } - - String custom_debug = p_preset->get("custom_template/debug"); - String custom_release = p_preset->get("custom_template/release"); - - String template_path = p_debug ? custom_debug : custom_release; - - template_path = template_path.strip_edges(); - - if (template_path.is_empty()) { - template_path = find_export_template(get_template_file_name(p_debug ? "debug" : "release", p_preset->get("binary_format/64_bits") ? "64" : "32")); - } - - if (!template_path.is_empty() && !FileAccess::exists(template_path)) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), vformat(TTR("Template file not found: \"%s\"."), template_path)); - return ERR_FILE_NOT_FOUND; - } - - Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - da->make_dir_recursive(p_path.get_base_dir()); - Error err = da->copy(template_path, p_path, get_chmod_flags()); - if (err != OK) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("Failed to copy export template.")); - } - - return err; -} - -Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { - String pck_path; - if (p_preset->get("binary_format/embed_pck")) { - pck_path = p_path; - } else { - pck_path = p_path.get_basename() + ".pck"; - } - - Vector<SharedObject> so_files; - - int64_t embedded_pos; - int64_t embedded_size; - Error err = save_pack(p_preset, p_debug, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size); - if (err == OK && p_preset->get("binary_format/embed_pck")) { - if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) { - add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB.")); - return ERR_INVALID_PARAMETER; - } - - err = fixup_embedded_pck(p_path, embedded_pos, embedded_size); - } - - if (err == OK && !so_files.is_empty()) { - // If shared object files, copy them. - Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - for (int i = 0; i < so_files.size() && err == OK; i++) { - String src_path = ProjectSettings::get_singleton()->globalize_path(so_files[i].path); - String target_path; - if (so_files[i].target.is_empty()) { - target_path = p_path.get_base_dir().plus_file(src_path.get_file()); - } else { - target_path = p_path.get_base_dir().plus_file(so_files[i].target).plus_file(src_path.get_file()); - } - - if (da->dir_exists(src_path)) { - err = da->make_dir_recursive(target_path); - if (err == OK) { - err = da->copy_dir(src_path, target_path, -1, true); - } - } else { - err = da->copy(src_path, target_path); - if (err == OK) { - err = sign_shared_object(p_preset, p_debug, target_path); - } - } - } - } - - return err; -} - -Error EditorExportPlatformPC::sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) { - return OK; -} - -void EditorExportPlatformPC::set_name(const String &p_name) { - name = p_name; -} - -void EditorExportPlatformPC::set_os_name(const String &p_name) { - os_name = p_name; -} - -void EditorExportPlatformPC::set_logo(const Ref<Texture2D> &p_logo) { - logo = p_logo; -} - -void EditorExportPlatformPC::get_platform_features(List<String> *r_features) { - r_features->push_back("pc"); //all pcs support "pc" - r_features->push_back("s3tc"); //all pcs support "s3tc" compression - r_features->push_back(get_os_name().to_lower()); //OS name is a feature -} - -void EditorExportPlatformPC::resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) { - if (p_features.has("bptc")) { - if (p_preset->has("texture_format/no_bptc_fallbacks")) { - p_features.erase("s3tc"); - } - } -} - -int EditorExportPlatformPC::get_chmod_flags() const { - return chmod_flags; -} - -void EditorExportPlatformPC::set_chmod_flags(int p_flags) { - chmod_flags = p_flags; -} - -/////////////////////// - -void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { - String extension = p_path.get_extension().to_lower(); - if (extension != "tres" && extension != "tscn") { - return; - } - - bool convert = GLOBAL_GET("editor/export/convert_text_resources_to_binary"); - if (!convert) { - return; - } - String tmp_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmpfile.res"); - Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path); - if (err != OK) { - DirAccess::remove_file_or_error(tmp_path); - ERR_FAIL(); - } - Vector<uint8_t> data = FileAccess::get_file_as_array(tmp_path); - if (data.size() == 0) { - DirAccess::remove_file_or_error(tmp_path); - ERR_FAIL(); - } - DirAccess::remove_file_or_error(tmp_path); - add_file(p_path + ".converted.res", data, true); -} - -EditorExportTextSceneToBinaryPlugin::EditorExportTextSceneToBinaryPlugin() { - GLOBAL_DEF("editor/export/convert_text_resources_to_binary", false); -} diff --git a/editor/export/editor_export_platform.h b/editor/export/editor_export_platform.h new file mode 100644 index 0000000000..832a0cf846 --- /dev/null +++ b/editor/export/editor_export_platform.h @@ -0,0 +1,221 @@ +/*************************************************************************/ +/* editor_export_platform.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_EXPORT_PLATFORM_H +#define EDITOR_EXPORT_PLATFORM_H + +class EditorFileSystemDirectory; +struct EditorProgress; + +#include "core/io/dir_access.h" +#include "editor_export_preset.h" +#include "editor_export_shared_object.h" +#include "scene/gui/rich_text_label.h" +#include "scene/main/node.h" + +class EditorExportPlatform : public RefCounted { + GDCLASS(EditorExportPlatform, RefCounted); + +public: + typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so); + + enum ExportMessageType { + EXPORT_MESSAGE_NONE, + EXPORT_MESSAGE_INFO, + EXPORT_MESSAGE_WARNING, + EXPORT_MESSAGE_ERROR, + }; + + struct ExportMessage { + ExportMessageType msg_type; + String category; + String text; + }; + +private: + struct SavedData { + uint64_t ofs = 0; + uint64_t size = 0; + bool encrypted = false; + Vector<uint8_t> md5; + CharString path_utf8; + + bool operator<(const SavedData &p_data) const { + return path_utf8 < p_data.path_utf8; + } + }; + + struct PackData { + Ref<FileAccess> f; + Vector<SavedData> file_ofs; + EditorProgress *ep = nullptr; + Vector<SharedObject> *so_files = nullptr; + }; + + struct ZipData { + void *zip = nullptr; + EditorProgress *ep = nullptr; + }; + + struct FeatureContainers { + HashSet<String> features; + Vector<String> features_pv; + }; + + Vector<ExportMessage> messages; + + void _export_find_resources(EditorFileSystemDirectory *p_dir, HashSet<String> &p_paths); + void _export_find_dependencies(const String &p_path, HashSet<String> &p_paths); + + void gen_debug_flags(Vector<String> &r_flags, int p_flags); + static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + + void _edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, HashSet<String> &r_list, bool exclude); + void _edit_filter_list(HashSet<String> &r_list, const String &p_filter, bool exclude); + + static Error _add_shared_object(void *p_userdata, const SharedObject &p_so); + +protected: + struct ExportNotifier { + ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); + ~ExportNotifier(); + }; + + FeatureContainers get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug) const; + + bool exists_export_template(String template_file_name, String *err) const; + String find_export_template(String template_file_name, String *err = nullptr) const; + void gen_export_flags(Vector<String> &r_flags, int p_flags); + +public: + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const = 0; + + struct ExportOption { + PropertyInfo option; + Variant default_value; + + ExportOption(const PropertyInfo &p_info, const Variant &p_default) : + option(p_info), + default_value(p_default) { + } + ExportOption() {} + }; + + virtual Ref<EditorExportPreset> create_preset(); + + virtual void clear_messages() { messages.clear(); } + virtual void add_message(ExportMessageType p_type, const String &p_category, const String &p_message) { + ExportMessage msg; + msg.category = p_category; + msg.text = p_message; + msg.msg_type = p_type; + messages.push_back(msg); + switch (p_type) { + case EXPORT_MESSAGE_INFO: { + print_line(vformat("%s: %s\n", msg.category, msg.text)); + } break; + case EXPORT_MESSAGE_WARNING: { + WARN_PRINT(vformat("%s: %s\n", msg.category, msg.text)); + } break; + case EXPORT_MESSAGE_ERROR: { + ERR_PRINT(vformat("%s: %s\n", msg.category, msg.text)); + } break; + default: + break; + } + } + + virtual int get_message_count() const { + return messages.size(); + } + + virtual ExportMessage get_message(int p_index) const { + ERR_FAIL_INDEX_V(p_index, messages.size(), ExportMessage()); + return messages[p_index]; + } + + virtual ExportMessageType get_worst_message_type() const { + ExportMessageType worst_type = EXPORT_MESSAGE_NONE; + for (int i = 0; i < messages.size(); i++) { + worst_type = MAX(worst_type, messages[i].msg_type); + } + return worst_type; + } + + virtual bool fill_log_messages(RichTextLabel *p_log, Error p_err); + + virtual void get_export_options(List<ExportOption> *r_options) = 0; + virtual bool should_update_export_options() { return false; } + virtual bool get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const { return true; } + + virtual String get_os_name() const = 0; + virtual String get_name() const = 0; + virtual Ref<Texture2D> get_logo() const = 0; + + Error export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr); + + Error save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr); + Error save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); + + virtual bool poll_export() { return false; } + virtual int get_options_count() const { return 0; } + virtual String get_options_tooltip() const { return ""; } + virtual Ref<ImageTexture> get_option_icon(int p_index) const; + virtual String get_option_label(int p_device) const { return ""; } + virtual String get_option_tooltip(int p_device) const { return ""; } + + enum DebugFlags { + DEBUG_FLAG_DUMB_CLIENT = 1, + DEBUG_FLAG_REMOTE_DEBUG = 2, + DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST = 4, + DEBUG_FLAG_VIEW_COLLISONS = 8, + DEBUG_FLAG_VIEW_NAVIGATION = 16, + }; + + virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { return OK; } + virtual Ref<Texture2D> get_run_icon() const { return get_logo(); } + + String test_etc2() const; + virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const = 0; + + virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const = 0; + virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) = 0; + virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); + virtual Error export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); + virtual void get_platform_features(List<String> *r_features) const = 0; + virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) = 0; + virtual String get_debug_protocol() const { return "tcp://"; } + + EditorExportPlatform(); +}; + +#endif // EDITOR_EXPORT_PLATFORM_H diff --git a/editor/export/editor_export_platform_pc.cpp b/editor/export/editor_export_platform_pc.cpp new file mode 100644 index 0000000000..5e0044f2ae --- /dev/null +++ b/editor/export/editor_export_platform_pc.cpp @@ -0,0 +1,242 @@ +/*************************************************************************/ +/* editor_export_platform_pc.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_export_platform_pc.h" + +#include "core/config/project_settings.h" + +void EditorExportPlatformPC::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { + if (p_preset->get("texture_format/s3tc")) { + r_features->push_back("s3tc"); + } + if (p_preset->get("texture_format/etc")) { + r_features->push_back("etc"); + } + if (p_preset->get("texture_format/etc2")) { + r_features->push_back("etc2"); + } + // PC platforms only have one architecture per export, since + // we export a single executable instead of a bundle. + r_features->push_back(p_preset->get("binary_format/architecture")); +} + +void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) { + String ext_filter = (get_os_name() == "Windows") ? "*.exe" : ""; + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, ext_filter), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, ext_filter), "")); + + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "debug/export_console_script", PROPERTY_HINT_ENUM, "No,Debug Only,Debug and Release"), 1)); + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/embed_pck"), false)); + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/bptc"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/no_bptc_fallbacks"), true)); +} + +String EditorExportPlatformPC::get_name() const { + return name; +} + +String EditorExportPlatformPC::get_os_name() const { + return os_name; +} + +Ref<Texture2D> EditorExportPlatformPC::get_logo() const { + return logo; +} + +bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { + String err; + bool valid = false; + + // Look for export templates (first official, and if defined custom templates). + String arch = p_preset->get("binary_format/architecture"); + bool dvalid = exists_export_template(get_template_file_name("debug", arch), &err); + bool rvalid = exists_export_template(get_template_file_name("release", arch), &err); + + if (p_preset->get("custom_template/debug") != "") { + dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); + if (!dvalid) { + err += TTR("Custom debug template not found.") + "\n"; + } + } + if (p_preset->get("custom_template/release") != "") { + rvalid = FileAccess::exists(p_preset->get("custom_template/release")); + if (!rvalid) { + err += TTR("Custom release template not found.") + "\n"; + } + } + + valid = dvalid || rvalid; + r_missing_templates = !valid; + + if (!err.is_empty()) { + r_error = err; + } + return valid; +} + +Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { + ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags); + + Error err = prepare_template(p_preset, p_debug, p_path, p_flags); + if (err == OK) { + err = modify_template(p_preset, p_debug, p_path, p_flags); + } + if (err == OK) { + err = export_project_data(p_preset, p_debug, p_path, p_flags); + } + + return err; +} + +Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { + if (!DirAccess::exists(p_path.get_base_dir())) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("The given export path doesn't exist.")); + return ERR_FILE_BAD_PATH; + } + + String custom_debug = p_preset->get("custom_template/debug"); + String custom_release = p_preset->get("custom_template/release"); + + String template_path = p_debug ? custom_debug : custom_release; + + template_path = template_path.strip_edges(); + + if (template_path.is_empty()) { + template_path = find_export_template(get_template_file_name(p_debug ? "debug" : "release", p_preset->get("binary_format/architecture"))); + } + + if (!template_path.is_empty() && !FileAccess::exists(template_path)) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), vformat(TTR("Template file not found: \"%s\"."), template_path)); + return ERR_FILE_NOT_FOUND; + } + + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + da->make_dir_recursive(p_path.get_base_dir()); + Error err = da->copy(template_path, p_path, get_chmod_flags()); + if (err != OK) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("Failed to copy export template.")); + } + + return err; +} + +Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { + String pck_path; + if (p_preset->get("binary_format/embed_pck")) { + pck_path = p_path; + } else { + pck_path = p_path.get_basename() + ".pck"; + } + + Vector<SharedObject> so_files; + + int64_t embedded_pos; + int64_t embedded_size; + Error err = save_pack(p_preset, p_debug, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size); + if (err == OK && p_preset->get("binary_format/embed_pck")) { + if (embedded_size >= 0x100000000 && String(p_preset->get("binary_format/architecture")).contains("32")) { + add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB.")); + return ERR_INVALID_PARAMETER; + } + + err = fixup_embedded_pck(p_path, embedded_pos, embedded_size); + } + + if (err == OK && !so_files.is_empty()) { + // If shared object files, copy them. + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + for (int i = 0; i < so_files.size() && err == OK; i++) { + String src_path = ProjectSettings::get_singleton()->globalize_path(so_files[i].path); + String target_path; + if (so_files[i].target.is_empty()) { + target_path = p_path.get_base_dir().plus_file(src_path.get_file()); + } else { + target_path = p_path.get_base_dir().plus_file(so_files[i].target).plus_file(src_path.get_file()); + } + + if (da->dir_exists(src_path)) { + err = da->make_dir_recursive(target_path); + if (err == OK) { + err = da->copy_dir(src_path, target_path, -1, true); + } + } else { + err = da->copy(src_path, target_path); + if (err == OK) { + err = sign_shared_object(p_preset, p_debug, target_path); + } + } + } + } + + return err; +} + +Error EditorExportPlatformPC::sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) { + return OK; +} + +void EditorExportPlatformPC::set_name(const String &p_name) { + name = p_name; +} + +void EditorExportPlatformPC::set_os_name(const String &p_name) { + os_name = p_name; +} + +void EditorExportPlatformPC::set_logo(const Ref<Texture2D> &p_logo) { + logo = p_logo; +} + +void EditorExportPlatformPC::get_platform_features(List<String> *r_features) const { + r_features->push_back("pc"); //all pcs support "pc" + r_features->push_back("s3tc"); //all pcs support "s3tc" compression + r_features->push_back(get_os_name().to_lower()); //OS name is a feature +} + +void EditorExportPlatformPC::resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) { + if (p_features.has("bptc")) { + if (p_preset->has("texture_format/no_bptc_fallbacks")) { + p_features.erase("s3tc"); + } + } +} + +int EditorExportPlatformPC::get_chmod_flags() const { + return chmod_flags; +} + +void EditorExportPlatformPC::set_chmod_flags(int p_flags) { + chmod_flags = p_flags; +} diff --git a/editor/export/editor_export_platform_pc.h b/editor/export/editor_export_platform_pc.h new file mode 100644 index 0000000000..bdb86e924a --- /dev/null +++ b/editor/export/editor_export_platform_pc.h @@ -0,0 +1,82 @@ +/*************************************************************************/ +/* editor_export_platform_pc.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_EXPORT_PLATFORM_PC_H +#define EDITOR_EXPORT_PLATFORM_PC_H + +#include "editor_export_platform.h" + +class EditorExportPlatformPC : public EditorExportPlatform { + GDCLASS(EditorExportPlatformPC, EditorExportPlatform); + +private: + Ref<ImageTexture> logo; + String name; + String os_name; + + int chmod_flags = -1; + +public: + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; + + virtual void get_export_options(List<ExportOption> *r_options) override; + + virtual String get_name() const override; + virtual String get_os_name() const override; + virtual Ref<Texture2D> get_logo() const override; + + virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; + virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; + virtual Error sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); + virtual String get_template_file_name(const String &p_target, const String &p_arch) const = 0; + + virtual Error prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); + virtual Error modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { return OK; }; + virtual Error export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); + + void set_extension(const String &p_extension, const String &p_feature_key = "default"); + void set_name(const String &p_name); + void set_os_name(const String &p_name); + + void set_logo(const Ref<Texture2D> &p_logo); + + void add_platform_feature(const String &p_feature); + virtual void get_platform_features(List<String> *r_features) const override; + virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override; + + int get_chmod_flags() const; + void set_chmod_flags(int p_flags); + + virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { + return Error::OK; + } +}; + +#endif // EDITOR_EXPORT_PLATFORM_PC_H diff --git a/editor/export/editor_export_plugin.cpp b/editor/export/editor_export_plugin.cpp new file mode 100644 index 0000000000..cf3a9b0810 --- /dev/null +++ b/editor/export/editor_export_plugin.cpp @@ -0,0 +1,201 @@ +/*************************************************************************/ +/* editor_export_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_export_plugin.h" + +#include "core/config/project_settings.h" +#include "core/io/dir_access.h" +#include "core/io/file_access.h" +#include "editor/editor_paths.h" +#include "editor/export/editor_export_platform.h" +#include "scene/resources/resource_format_text.h" + +void EditorExportPlugin::set_export_preset(const Ref<EditorExportPreset> &p_preset) { + if (p_preset.is_valid()) { + export_preset = p_preset; + } +} + +Ref<EditorExportPreset> EditorExportPlugin::get_export_preset() const { + return export_preset; +} + +void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap) { + ExtraFile ef; + ef.data = p_file; + ef.path = p_path; + ef.remap = p_remap; + extra_files.push_back(ef); +} + +void EditorExportPlugin::add_shared_object(const String &p_path, const Vector<String> &p_tags, const String &p_target) { + shared_objects.push_back(SharedObject(p_path, p_tags, p_target)); +} + +void EditorExportPlugin::add_ios_framework(const String &p_path) { + ios_frameworks.push_back(p_path); +} + +void EditorExportPlugin::add_ios_embedded_framework(const String &p_path) { + ios_embedded_frameworks.push_back(p_path); +} + +Vector<String> EditorExportPlugin::get_ios_frameworks() const { + return ios_frameworks; +} + +Vector<String> EditorExportPlugin::get_ios_embedded_frameworks() const { + return ios_embedded_frameworks; +} + +void EditorExportPlugin::add_ios_plist_content(const String &p_plist_content) { + ios_plist_content += p_plist_content + "\n"; +} + +String EditorExportPlugin::get_ios_plist_content() const { + return ios_plist_content; +} + +void EditorExportPlugin::add_ios_linker_flags(const String &p_flags) { + if (ios_linker_flags.length() > 0) { + ios_linker_flags += ' '; + } + ios_linker_flags += p_flags; +} + +String EditorExportPlugin::get_ios_linker_flags() const { + return ios_linker_flags; +} + +void EditorExportPlugin::add_ios_bundle_file(const String &p_path) { + ios_bundle_files.push_back(p_path); +} + +Vector<String> EditorExportPlugin::get_ios_bundle_files() const { + return ios_bundle_files; +} + +void EditorExportPlugin::add_ios_cpp_code(const String &p_code) { + ios_cpp_code += p_code; +} + +String EditorExportPlugin::get_ios_cpp_code() const { + return ios_cpp_code; +} + +void EditorExportPlugin::add_macos_plugin_file(const String &p_path) { + macos_plugin_files.push_back(p_path); +} + +const Vector<String> &EditorExportPlugin::get_macos_plugin_files() const { + return macos_plugin_files; +} + +void EditorExportPlugin::add_ios_project_static_lib(const String &p_path) { + ios_project_static_libs.push_back(p_path); +} + +Vector<String> EditorExportPlugin::get_ios_project_static_libs() const { + return ios_project_static_libs; +} + +void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features) { + GDVIRTUAL_CALL(_export_file, p_path, p_type, p_features); +} + +void EditorExportPlugin::_export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags) { + GDVIRTUAL_CALL(_export_begin, p_features, p_debug, p_path, p_flags); +} + +void EditorExportPlugin::_export_end_script() { + GDVIRTUAL_CALL(_export_end); +} + +void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { +} + +void EditorExportPlugin::_export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags) { +} + +void EditorExportPlugin::skip() { + skipped = true; +} + +void EditorExportPlugin::_bind_methods() { + ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags", "target"), &EditorExportPlugin::add_shared_object); + ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_ios_project_static_lib); + ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file); + ClassDB::bind_method(D_METHOD("add_ios_framework", "path"), &EditorExportPlugin::add_ios_framework); + ClassDB::bind_method(D_METHOD("add_ios_embedded_framework", "path"), &EditorExportPlugin::add_ios_embedded_framework); + ClassDB::bind_method(D_METHOD("add_ios_plist_content", "plist_content"), &EditorExportPlugin::add_ios_plist_content); + ClassDB::bind_method(D_METHOD("add_ios_linker_flags", "flags"), &EditorExportPlugin::add_ios_linker_flags); + ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_ios_bundle_file); + ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code); + ClassDB::bind_method(D_METHOD("add_macos_plugin_file", "path"), &EditorExportPlugin::add_macos_plugin_file); + ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip); + + GDVIRTUAL_BIND(_export_file, "path", "type", "features"); + GDVIRTUAL_BIND(_export_begin, "features", "is_debug", "path", "flags"); + GDVIRTUAL_BIND(_export_end); +} + +EditorExportPlugin::EditorExportPlugin() { +} + +/////////////////////// + +void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { + String extension = p_path.get_extension().to_lower(); + if (extension != "tres" && extension != "tscn") { + return; + } + + bool convert = GLOBAL_GET("editor/export/convert_text_resources_to_binary"); + if (!convert) { + return; + } + String tmp_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmpfile.res"); + Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path); + if (err != OK) { + DirAccess::remove_file_or_error(tmp_path); + ERR_FAIL(); + } + Vector<uint8_t> data = FileAccess::get_file_as_array(tmp_path); + if (data.size() == 0) { + DirAccess::remove_file_or_error(tmp_path); + ERR_FAIL(); + } + DirAccess::remove_file_or_error(tmp_path); + add_file(p_path + ".converted.res", data, true); +} + +EditorExportTextSceneToBinaryPlugin::EditorExportTextSceneToBinaryPlugin() { + GLOBAL_DEF("editor/export/convert_text_resources_to_binary", false); +} diff --git a/editor/export/editor_export_plugin.h b/editor/export/editor_export_plugin.h new file mode 100644 index 0000000000..04ebc1dfed --- /dev/null +++ b/editor/export/editor_export_plugin.h @@ -0,0 +1,132 @@ +/*************************************************************************/ +/* editor_export_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_EXPORT_PLUGIN_H +#define EDITOR_EXPORT_PLUGIN_H + +#include "core/extension/native_extension.h" +#include "editor_export_preset.h" +#include "editor_export_shared_object.h" + +class EditorExportPlugin : public RefCounted { + GDCLASS(EditorExportPlugin, RefCounted); + + friend class EditorExportPlatform; + + Ref<EditorExportPreset> export_preset; + + Vector<SharedObject> shared_objects; + struct ExtraFile { + String path; + Vector<uint8_t> data; + bool remap = false; + }; + Vector<ExtraFile> extra_files; + bool skipped = false; + + Vector<String> ios_frameworks; + Vector<String> ios_embedded_frameworks; + Vector<String> ios_project_static_libs; + String ios_plist_content; + String ios_linker_flags; + Vector<String> ios_bundle_files; + String ios_cpp_code; + + Vector<String> macos_plugin_files; + + _FORCE_INLINE_ void _clear() { + shared_objects.clear(); + extra_files.clear(); + skipped = false; + } + + _FORCE_INLINE_ void _export_end() { + ios_frameworks.clear(); + ios_embedded_frameworks.clear(); + ios_bundle_files.clear(); + ios_plist_content = ""; + ios_linker_flags = ""; + ios_cpp_code = ""; + macos_plugin_files.clear(); + } + + void _export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features); + void _export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags); + void _export_end_script(); + +protected: + void set_export_preset(const Ref<EditorExportPreset> &p_preset); + Ref<EditorExportPreset> get_export_preset() const; + + void add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap); + void add_shared_object(const String &p_path, const Vector<String> &tags, const String &p_target = String()); + + void add_ios_framework(const String &p_path); + void add_ios_embedded_framework(const String &p_path); + void add_ios_project_static_lib(const String &p_path); + void add_ios_plist_content(const String &p_plist_content); + void add_ios_linker_flags(const String &p_flags); + void add_ios_bundle_file(const String &p_path); + void add_ios_cpp_code(const String &p_code); + void add_macos_plugin_file(const String &p_path); + + void skip(); + + virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features); + virtual void _export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags); + + static void _bind_methods(); + + GDVIRTUAL3(_export_file, String, String, Vector<String>) + GDVIRTUAL4(_export_begin, Vector<String>, bool, String, uint32_t) + GDVIRTUAL0(_export_end) + +public: + Vector<String> get_ios_frameworks() const; + Vector<String> get_ios_embedded_frameworks() const; + Vector<String> get_ios_project_static_libs() const; + String get_ios_plist_content() const; + String get_ios_linker_flags() const; + Vector<String> get_ios_bundle_files() const; + String get_ios_cpp_code() const; + const Vector<String> &get_macos_plugin_files() const; + + EditorExportPlugin(); +}; + +class EditorExportTextSceneToBinaryPlugin : public EditorExportPlugin { + GDCLASS(EditorExportTextSceneToBinaryPlugin, EditorExportPlugin); + +public: + virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) override; + EditorExportTextSceneToBinaryPlugin(); +}; + +#endif // EDITOR_EXPORT_PLUGIN_H diff --git a/editor/export/editor_export_preset.cpp b/editor/export/editor_export_preset.cpp new file mode 100644 index 0000000000..cdf69e727d --- /dev/null +++ b/editor/export/editor_export_preset.cpp @@ -0,0 +1,221 @@ +/*************************************************************************/ +/* editor_export_preset.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_export.h" + +bool EditorExportPreset::_set(const StringName &p_name, const Variant &p_value) { + if (values.has(p_name)) { + values[p_name] = p_value; + EditorExport::singleton->save_presets(); + return true; + } + + return false; +} + +bool EditorExportPreset::_get(const StringName &p_name, Variant &r_ret) const { + if (values.has(p_name)) { + r_ret = values[p_name]; + return true; + } + + return false; +} + +void EditorExportPreset::_get_property_list(List<PropertyInfo> *p_list) const { + for (const PropertyInfo &E : properties) { + if (platform->get_export_option_visibility(E.name, values)) { + p_list->push_back(E); + } + } +} + +Ref<EditorExportPlatform> EditorExportPreset::get_platform() const { + return platform; +} + +void EditorExportPreset::update_files_to_export() { + Vector<String> to_remove; + for (const String &E : selected_files) { + if (!FileAccess::exists(E)) { + to_remove.push_back(E); + } + } + for (int i = 0; i < to_remove.size(); ++i) { + selected_files.erase(to_remove[i]); + } +} + +Vector<String> EditorExportPreset::get_files_to_export() const { + Vector<String> files; + for (const String &E : selected_files) { + files.push_back(E); + } + return files; +} + +void EditorExportPreset::set_name(const String &p_name) { + name = p_name; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_name() const { + return name; +} + +void EditorExportPreset::set_runnable(bool p_enable) { + runnable = p_enable; + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::is_runnable() const { + return runnable; +} + +void EditorExportPreset::set_export_filter(ExportFilter p_filter) { + export_filter = p_filter; + EditorExport::singleton->save_presets(); +} + +EditorExportPreset::ExportFilter EditorExportPreset::get_export_filter() const { + return export_filter; +} + +void EditorExportPreset::set_include_filter(const String &p_include) { + include_filter = p_include; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_include_filter() const { + return include_filter; +} + +void EditorExportPreset::set_export_path(const String &p_path) { + export_path = p_path; + /* NOTE(SonerSound): if there is a need to implement a PropertyHint that specifically indicates a relative path, + * this should be removed. */ + if (export_path.is_absolute_path()) { + String res_path = OS::get_singleton()->get_resource_dir(); + export_path = res_path.path_to_file(export_path); + } + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_export_path() const { + return export_path; +} + +void EditorExportPreset::set_exclude_filter(const String &p_exclude) { + exclude_filter = p_exclude; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_exclude_filter() const { + return exclude_filter; +} + +void EditorExportPreset::add_export_file(const String &p_path) { + selected_files.insert(p_path); + EditorExport::singleton->save_presets(); +} + +void EditorExportPreset::remove_export_file(const String &p_path) { + selected_files.erase(p_path); + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::has_export_file(const String &p_path) { + return selected_files.has(p_path); +} + +void EditorExportPreset::set_custom_features(const String &p_custom_features) { + custom_features = p_custom_features; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_custom_features() const { + return custom_features; +} + +void EditorExportPreset::set_enc_in_filter(const String &p_filter) { + enc_in_filters = p_filter; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_enc_in_filter() const { + return enc_in_filters; +} + +void EditorExportPreset::set_enc_ex_filter(const String &p_filter) { + enc_ex_filters = p_filter; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_enc_ex_filter() const { + return enc_ex_filters; +} + +void EditorExportPreset::set_enc_pck(bool p_enabled) { + enc_pck = p_enabled; + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::get_enc_pck() const { + return enc_pck; +} + +void EditorExportPreset::set_enc_directory(bool p_enabled) { + enc_directory = p_enabled; + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::get_enc_directory() const { + return enc_directory; +} + +void EditorExportPreset::set_script_export_mode(int p_mode) { + script_mode = p_mode; + EditorExport::singleton->save_presets(); +} + +int EditorExportPreset::get_script_export_mode() const { + return script_mode; +} + +void EditorExportPreset::set_script_encryption_key(const String &p_key) { + script_key = p_key; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_script_encryption_key() const { + return script_key; +} + +EditorExportPreset::EditorExportPreset() {} diff --git a/editor/export/editor_export_preset.h b/editor/export/editor_export_preset.h new file mode 100644 index 0000000000..00109396b0 --- /dev/null +++ b/editor/export/editor_export_preset.h @@ -0,0 +1,145 @@ +/*************************************************************************/ +/* editor_export_preset.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_EXPORT_PRESET_H +#define EDITOR_EXPORT_PRESET_H + +class EditorExportPlatform; + +#include "core/object/ref_counted.h" + +class EditorExportPreset : public RefCounted { + GDCLASS(EditorExportPreset, RefCounted); + +public: + enum ExportFilter { + EXPORT_ALL_RESOURCES, + EXPORT_SELECTED_SCENES, + EXPORT_SELECTED_RESOURCES, + EXCLUDE_SELECTED_RESOURCES, + }; + + enum ScriptExportMode { + MODE_SCRIPT_TEXT, + MODE_SCRIPT_COMPILED, + }; + +private: + Ref<EditorExportPlatform> platform; + ExportFilter export_filter = EXPORT_ALL_RESOURCES; + String include_filter; + String exclude_filter; + String export_path; + + String exporter; + HashSet<String> selected_files; + bool runnable = false; + + friend class EditorExport; + friend class EditorExportPlatform; + + List<PropertyInfo> properties; + HashMap<StringName, Variant> values; + + String name; + + String custom_features; + + String enc_in_filters; + String enc_ex_filters; + bool enc_pck = false; + bool enc_directory = false; + + int script_mode = MODE_SCRIPT_COMPILED; + String script_key; + +protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + +public: + Ref<EditorExportPlatform> get_platform() const; + + bool has(const StringName &p_property) const { return values.has(p_property); } + + void update_files_to_export(); + + Vector<String> get_files_to_export() const; + + void add_export_file(const String &p_path); + void remove_export_file(const String &p_path); + bool has_export_file(const String &p_path); + + void set_name(const String &p_name); + String get_name() const; + + void set_runnable(bool p_enable); + bool is_runnable() const; + + void set_export_filter(ExportFilter p_filter); + ExportFilter get_export_filter() const; + + void set_include_filter(const String &p_include); + String get_include_filter() const; + + void set_exclude_filter(const String &p_exclude); + String get_exclude_filter() const; + + void set_custom_features(const String &p_custom_features); + String get_custom_features() const; + + void set_export_path(const String &p_path); + String get_export_path() const; + + void set_enc_in_filter(const String &p_filter); + String get_enc_in_filter() const; + + void set_enc_ex_filter(const String &p_filter); + String get_enc_ex_filter() const; + + void set_enc_pck(bool p_enabled); + bool get_enc_pck() const; + + void set_enc_directory(bool p_enabled); + bool get_enc_directory() const; + + void set_script_export_mode(int p_mode); + int get_script_export_mode() const; + + void set_script_encryption_key(const String &p_key); + String get_script_encryption_key() const; + + const List<PropertyInfo> &get_properties() const { return properties; } + + EditorExportPreset(); +}; + +#endif // EDITOR_EXPORT_PRESET_H diff --git a/editor/export/editor_export_shared_object.h b/editor/export/editor_export_shared_object.h new file mode 100644 index 0000000000..558f403ca1 --- /dev/null +++ b/editor/export/editor_export_shared_object.h @@ -0,0 +1,51 @@ +/*************************************************************************/ +/* editor_export_shared_object.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_EXPORT_SHARED_OBJECT_H +#define EDITOR_EXPORT_SHARED_OBJECT_H + +#include "core/string/ustring.h" +#include "core/templates/vector.h" + +struct SharedObject { + String path; + Vector<String> tags; + String target; + + SharedObject(const String &p_path, const Vector<String> &p_tags, const String &p_target) : + path(p_path), + tags(p_tags), + target(p_target) { + } + + SharedObject() {} +}; + +#endif // EDITOR_EXPORT_SHARED_OBJECT_H diff --git a/editor/export_template_manager.cpp b/editor/export/export_template_manager.cpp index 9f9b8374ce..a7d9d7f068 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export/export_template_manager.cpp @@ -30,23 +30,24 @@ #include "export_template_manager.h" -#include "core/input/input.h" #include "core/io/dir_access.h" #include "core/io/json.h" #include "core/io/zip_io.h" -#include "core/os/keyboard.h" -#include "core/templates/rb_set.h" #include "core/version.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_scale.h" -#include "progress_dialog.h" -#include "scene/gui/link_button.h" +#include "editor/editor_settings.h" +#include "editor/progress_dialog.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/separator.h" +#include "scene/gui/tree.h" +#include "scene/main/http_request.h" void ExportTemplateManager::_update_template_status() { // Fetch installed templates from the file system. Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - const String &templates_dir = EditorSettings::get_singleton()->get_export_templates_dir(); + const String &templates_dir = EditorPaths::get_singleton()->get_export_templates_dir(); Error err = da->change_dir(templates_dir); ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir + "'."); @@ -439,7 +440,7 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_ } Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - String template_path = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(version); + String template_path = EditorPaths::get_singleton()->get_export_templates_dir().plus_file(version); Error err = d->make_dir_recursive(template_path); if (err != OK) { EditorNode::get_singleton()->show_warning(TTR("Error creating path for extracting templates:") + "\n" + template_path); @@ -538,7 +539,7 @@ void ExportTemplateManager::_uninstall_template(const String &p_version) { void ExportTemplateManager::_uninstall_template_confirmed() { Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - const String &templates_dir = EditorSettings::get_singleton()->get_export_templates_dir(); + const String &templates_dir = EditorPaths::get_singleton()->get_export_templates_dir(); Error err = da->change_dir(templates_dir); ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir + "'."); @@ -616,7 +617,7 @@ void ExportTemplateManager::_installed_table_button_cbk(Object *p_item, int p_co } void ExportTemplateManager::_open_template_folder(const String &p_version) { - const String &templates_dir = EditorSettings::get_singleton()->get_export_templates_dir(); + const String &templates_dir = EditorPaths::get_singleton()->get_export_templates_dir(); OS::get_singleton()->shell_open("file://" + templates_dir.plus_file(p_version)); } @@ -640,12 +641,12 @@ void ExportTemplateManager::_hide_dialog() { } bool ExportTemplateManager::can_install_android_template() { - const String templates_dir = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG); + const String templates_dir = EditorPaths::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG); return FileAccess::exists(templates_dir.plus_file("android_source.zip")); } Error ExportTemplateManager::install_android_template() { - const String &templates_path = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG); + const String &templates_path = EditorPaths::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG); const String &source_zip = templates_path.plus_file("android_source.zip"); ERR_FAIL_COND_V(!FileAccess::exists(source_zip), ERR_CANT_OPEN); return install_android_template_from_file(source_zip); @@ -869,13 +870,13 @@ ExportTemplateManager::ExportTemplateManager() { current_open_button->set_text(TTR("Open Folder")); current_open_button->set_tooltip(TTR("Open the folder containing installed templates for the current version.")); current_installed_hb->add_child(current_open_button); - current_open_button->connect("pressed", callable_mp(this, &ExportTemplateManager::_open_template_folder), varray(VERSION_FULL_CONFIG)); + current_open_button->connect("pressed", callable_mp(this, &ExportTemplateManager::_open_template_folder).bind(VERSION_FULL_CONFIG)); current_uninstall_button = memnew(Button); current_uninstall_button->set_text(TTR("Uninstall")); current_uninstall_button->set_tooltip(TTR("Uninstall templates for the current version.")); current_installed_hb->add_child(current_uninstall_button); - current_uninstall_button->connect("pressed", callable_mp(this, &ExportTemplateManager::_uninstall_template), varray(VERSION_FULL_CONFIG)); + current_uninstall_button->connect("pressed", callable_mp(this, &ExportTemplateManager::_uninstall_template).bind(VERSION_FULL_CONFIG)); main_vb->add_child(memnew(HSeparator)); @@ -991,7 +992,7 @@ ExportTemplateManager::ExportTemplateManager() { install_file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM); install_file_dialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE); install_file_dialog->add_filter("*.tpz", TTR("Godot Export Templates")); - install_file_dialog->connect("file_selected", callable_mp(this, &ExportTemplateManager::_install_file_selected), varray(false)); + install_file_dialog->connect("file_selected", callable_mp(this, &ExportTemplateManager::_install_file_selected).bind(false)); add_child(install_file_dialog); hide_dialog_accept = memnew(AcceptDialog); diff --git a/editor/export_template_manager.h b/editor/export/export_template_manager.h index 3494e11d5e..f01da15832 100644 --- a/editor/export_template_manager.h +++ b/editor/export/export_template_manager.h @@ -31,15 +31,15 @@ #ifndef EXPORT_TEMPLATE_MANAGER_H #define EXPORT_TEMPLATE_MANAGER_H -#include "editor/editor_settings.h" #include "scene/gui/dialogs.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/progress_bar.h" -#include "scene/gui/scroll_container.h" -#include "scene/main/http_request.h" class ExportTemplateVersion; +class FileDialog; +class HTTPRequest; +class MenuButton; +class OptionButton; +class ProgressBar; +class Tree; class ExportTemplateManager : public AcceptDialog { GDCLASS(ExportTemplateManager, AcceptDialog); diff --git a/editor/project_export.cpp b/editor/export/project_export.cpp index 209c997d58..cb82cefbbb 100644 --- a/editor/project_export.cpp +++ b/editor/export/project_export.cpp @@ -31,23 +31,16 @@ #include "project_export.h" #include "core/config/project_settings.h" -#include "core/io/dir_access.h" -#include "core/io/file_access.h" -#include "core/io/image_loader.h" -#include "core/io/resource_loader.h" -#include "core/io/resource_saver.h" -#include "core/os/os.h" -#include "core/string/optimized_translation.h" -#include "core/version_generated.gen.h" +#include "core/version.h" #include "editor/editor_file_dialog.h" +#include "editor/editor_file_system.h" #include "editor/editor_node.h" +#include "editor/editor_properties.h" #include "editor/editor_scale.h" -#include "editor/editor_settings.h" -#include "scene/gui/box_container.h" -#include "scene/gui/margin_container.h" -#include "scene/gui/scroll_container.h" -#include "scene/gui/tab_container.h" -#include "servers/display_server.h" +#include "editor/export/editor_export.h" +#include "scene/gui/check_button.h" +#include "scene/gui/link_button.h" +#include "scene/gui/tree.h" void ProjectExportDialog::_theme_changed() { duplicate_preset->set_icon(presets->get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons"))); diff --git a/editor/project_export.h b/editor/export/project_export.h index 5503d5aa47..96dd765a2c 100644 --- a/editor/project_export.h +++ b/editor/export/project_export.h @@ -31,28 +31,22 @@ #ifndef PROJECT_EXPORT_H #define PROJECT_EXPORT_H -#include "core/io/dir_access.h" -#include "core/os/thread.h" -#include "editor/editor_export.h" -#include "editor/editor_file_system.h" -#include "editor/editor_inspector.h" -#include "editor/editor_properties.h" -#include "scene/gui/button.h" -#include "scene/gui/check_button.h" -#include "scene/gui/control.h" #include "scene/gui/dialogs.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/label.h" -#include "scene/gui/link_button.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/option_button.h" -#include "scene/gui/rich_text_label.h" -#include "scene/gui/slider.h" -#include "scene/gui/tab_container.h" -#include "scene/gui/tree.h" -#include "scene/main/timer.h" +class CheckBox; +class CheckButton; +class EditorExportPreset; class EditorFileDialog; +class EditorFileSystemDirectory; +class EditorInspector; +class EditorPropertyPath; +class ItemList; +class MenuButton; +class OptionButton; +class RichTextLabel; +class TabContainer; +class Tree; +class TreeItem; class ProjectExportDialog : public ConfirmationDialog { GDCLASS(ProjectExportDialog, ConfirmationDialog); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index e025cedf02..b823db68f0 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -381,7 +381,7 @@ void FileSystemDock::_notification(int p_what) { file_list_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_file_list_rmb_option)); tree_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_tree_rmb_option)); - current_path->connect("text_submitted", callable_mp(this, &FileSystemDock::_navigate_to_path), make_binds(false)); + current_path->connect("text_submitted", callable_mp(this, &FileSystemDock::_navigate_to_path).bind(false)); always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); @@ -1531,14 +1531,13 @@ void FileSystemDock::_folder_removed(String p_folder) { void FileSystemDock::_rename_operation_confirm() { String new_name = rename_dialog_text->get_text().strip_edges(); - String old_name = tree->get_selected()->get_text(0); if (new_name.length() == 0) { EditorNode::get_singleton()->show_warning(TTR("No name provided.")); return; } else if (new_name.contains("/") || new_name.contains("\\") || new_name.contains(":")) { EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters.")); return; - } else if (to_rename.is_file && old_name.get_extension() != new_name.get_extension()) { + } else if (to_rename.is_file && to_rename.path.get_extension() != new_name.get_extension()) { if (!EditorFileSystem::get_singleton()->get_valid_extensions().find(new_name.get_extension())) { EditorNode::get_singleton()->show_warning(TTR("This file extension is not recognized by the editor.\nIf you want to rename it anyway, use your operating system's file manager.\nAfter renaming to an unknown extension, the file won't be shown in the editor anymore.")); return; @@ -3079,7 +3078,7 @@ FileSystemDock::FileSystemDock() { tree_search_box = memnew(LineEdit); tree_search_box->set_h_size_flags(SIZE_EXPAND_FILL); tree_search_box->set_placeholder(TTR("Filter Files")); - tree_search_box->connect("text_changed", callable_mp(this, &FileSystemDock::_search_changed), varray(tree_search_box)); + tree_search_box->connect("text_changed", callable_mp(this, &FileSystemDock::_search_changed).bind(tree_search_box)); toolbar2_hbc->add_child(tree_search_box); tree_button_sort = _create_file_menu_button(); @@ -3124,7 +3123,7 @@ FileSystemDock::FileSystemDock() { file_list_search_box = memnew(LineEdit); file_list_search_box->set_h_size_flags(SIZE_EXPAND_FILL); file_list_search_box->set_placeholder(TTR("Filter Files")); - file_list_search_box->connect("text_changed", callable_mp(this, &FileSystemDock::_search_changed), varray(file_list_search_box)); + file_list_search_box->connect("text_changed", callable_mp(this, &FileSystemDock::_search_changed).bind(file_list_search_box)); path_hb->add_child(file_list_search_box); file_list_button_sort = _create_file_menu_button(); @@ -3172,7 +3171,7 @@ FileSystemDock::FileSystemDock() { move_dialog = memnew(EditorDirDialog); move_dialog->set_ok_button_text(TTR("Move")); add_child(move_dialog); - move_dialog->connect("dir_selected", callable_mp(this, &FileSystemDock::_move_operation_confirm), make_binds(false)); + move_dialog->connect("dir_selected", callable_mp(this, &FileSystemDock::_move_operation_confirm).bind(false)); rename_dialog = memnew(ConfirmationDialog); VBoxContainer *rename_dialog_vb = memnew(VBoxContainer); diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index f1d08783ad..f16097f109 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -473,7 +473,7 @@ GroupDialog::GroupDialog() { add_group_button = memnew(Button); add_group_button->set_text(TTR("Add")); chbc->add_child(add_group_button); - add_group_button->connect("pressed", callable_mp(this, &GroupDialog::_add_group_pressed), varray(String())); + add_group_button->connect("pressed", callable_mp(this, &GroupDialog::_add_group_pressed).bind(String())); VBoxContainer *vbc_add = memnew(VBoxContainer); hbc->add_child(vbc_add); @@ -737,7 +737,7 @@ GroupsEditor::GroupsEditor() { add = memnew(Button); add->set_text(TTR("Add")); hbc->add_child(add); - add->connect("pressed", callable_mp(this, &GroupsEditor::_add_group), varray(String())); + add->connect("pressed", callable_mp(this, &GroupsEditor::_add_group).bind(String())); tree = memnew(Tree); tree->set_hide_root(true); diff --git a/editor/icons/AudioStream.svg b/editor/icons/AudioStream.svg new file mode 100644 index 0000000000..5d92dc25a5 --- /dev/null +++ b/editor/icons/AudioStream.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><path d="m12 2a-1 1 0 0 1 1 1-1 1 0 0 1 -1 1c-4.4301 0-8 3.5699-8 8a-1 1 0 0 1 -1 1-1 1 0 0 1 -1-1c0-5.511 4.489-10 10-10zm0 4a-1 1 0 0 1 1 1-1 1 0 0 1 -1 1c-2.221 0-4 1.779-4 4a-1 1 0 0 1 -1 1-1 1 0 0 1 -1-1c0-3.3018 2.6981-6 6-6zm0 4a-2 2 0 0 1 2 2-2 2 0 0 1 -2 2-2 2 0 0 1 -2-2-2 2 0 0 1 2-2z" fill="url(#a)"/></svg> diff --git a/editor/icons/AudioStreamGenerator.svg b/editor/icons/AudioStreamGenerator.svg new file mode 100644 index 0000000000..55b0fb9d92 --- /dev/null +++ b/editor/icons/AudioStreamGenerator.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><path d="m14 9-3 5-3-12-3 7-3-2" fill="none" stroke="url(#a)" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg> diff --git a/editor/icons/AudioStreamMicrophone.svg b/editor/icons/AudioStreamMicrophone.svg new file mode 100644 index 0000000000..51009e9d53 --- /dev/null +++ b/editor/icons/AudioStreamMicrophone.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><path d="m7 1c-1.108 0-2 .892-2 2h2v1h-2v2h2v1h-2c0 1.108.892 2 2 2v4l-2 2h6l-2-2v-4c1.108 0 2-.892 2-2h-2v-1h2v-2h-2v-1h2c0-1.108-.892-2-2-2z" fill="url(#a)"/></svg> diff --git a/editor/icons/AudioStreamOGGVorbis.svg b/editor/icons/AudioStreamOggVorbis.svg index 2e54de9faa..2e54de9faa 100644 --- a/editor/icons/AudioStreamOGGVorbis.svg +++ b/editor/icons/AudioStreamOggVorbis.svg diff --git a/editor/icons/AudioStreamRandomizer.svg b/editor/icons/AudioStreamRandomizer.svg new file mode 100644 index 0000000000..1696dff795 --- /dev/null +++ b/editor/icons/AudioStreamRandomizer.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><path d="m7.9999997 1c6.6837543 0 7.0000003.3165085 7.0000003 7.0057779 0 6.6877711-.286255 6.9755641-6.9367525 6.9938021-3.0191555.008313-4.4456225-.105997-5.1863245-.415726-1.570375-.65669-1.876923-1.727949-1.876923-6.5780761 0-6.6892694.316247-7.0057779 6.9999997-7.0057779zm3.5299143 1.7638478c-1.5662016 0-2.4379256 1.7724432-1.475213 2.9973439.738933.9401693 2.041543 1.025967 2.876923.1899002 1.183646-1.1846229.303279-3.1872441-1.40171-3.1872441zm-3.5760682 3.2710739c-1.5661974 0-2.4379268 1.7707341-1.4752138 2.9956331.7389365.9401892 2.0415435 1.0276772 2.8769233.191611 1.1836457-1.1846231.3032798-3.1872441-1.4017095-3.1872441zm-3.5538458 3.4729499c-.958537.031867-1.875214.7423284-1.875214 1.8493884 0 1.564955 2.248443 2.516522 3.249573 1.375494.7905175-.900982.8551191-1.664857.208547-2.487522-.416627-.5300879-1.007786-.7565128-1.582906-.7373604z" fill="url(#a)"/></svg> diff --git a/editor/icons/AudioStreamSample.svg b/editor/icons/AudioStreamWAV.svg index 2e54de9faa..2e54de9faa 100644 --- a/editor/icons/AudioStreamSample.svg +++ b/editor/icons/AudioStreamWAV.svg diff --git a/editor/icons/FontFile.svg b/editor/icons/FontFile.svg index 4b94fd0d74..c014299783 100644 --- a/editor/icons/FontFile.svg +++ b/editor/icons/FontFile.svg @@ -1 +1 @@ -<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1.5 1v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V3h2a1 1 0 0 1 1 1h1V1h-6Z" fill="#e0e0e0"/><path d="M4.5 5v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V7h2a1 1 0 0 1 1 1h1V5h-6Z" fill="#ff5f5f"/></svg> +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M7.5 7.5h-1a.519.519 0 0 0-.281.084A.491.491 0 0 0 6 8v.5h-.5V9a1 1 0 0 1-1 1v1H8V9.854A1 1 0 0 1 7.5 9V7.5zM1.5 1v3h1a1 1 0 0 1 1-1h2v1.5h2V3h2a1 1 0 0 1 1 1h1V1h-10z" style="fill:#e0e0e0;fill-opacity:1"/><path d="M4.5 5v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V7h2a1 1 0 0 1 1 1h1V5h-6z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/FontVariation.svg b/editor/icons/FontVariation.svg index eaad049fce..39917bcba9 100644 --- a/editor/icons/FontVariation.svg +++ b/editor/icons/FontVariation.svg @@ -1 +1 @@ -<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M2.437 1 1.379 4h1A.84 1.192 50 0 1 3.73 3h2L3.615 9a.84 1.192 50 0 1-1.352 1l-.353 1h4l.353-1a.84 1.192 50 0 1-.648-1l2.116-6h2a.84 1.192 50 0 1 .648 1h1l1.058-3h-6Z" fill="#e0e0e0"/><path d="m4.621 5-.705 2-.353 1h1a.84 1.192 49.998 0 1 1.353-1h2L5.8 13a.84 1.192 49.998 0 1-1.353 1l-.353 1h4l.353-1a.84 1.192 49.998 0 1-.647-1l2.116-6h2a.84 1.192 49.998 0 1 .647 1h1l.353-1 .705-2h-6Z" fill="#ff5f5f"/></svg> +<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M5.975 11 7.21 7.5H5.916a.478.478 0 0 0-.113.016.837.837 0 0 0-.127.043c-.044.018-.089.04-.133.066l-.043.027V9a1 1 0 0 1-1 1v1h1.475zM1.5 1v3h1a1 1 0 0 1 1-1h2v1.5h2V3h2a1 1 0 0 1 1 1h1V1h-10z" style="fill:#e0e0e0;fill-opacity:1"/><path d="m4.621 5-.705 2-.353 1h1a.84 1.192 49.998 0 1 1.353-1h2L5.8 13a.84 1.192 49.998 0 1-1.353 1l-.353 1h4l.353-1a.84 1.192 49.998 0 1-.647-1l2.116-6h2a.84 1.192 49.998 0 1 .647 1h1l.353-1 .705-2h-6z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/NodeWarnings2.svg b/editor/icons/NodeWarnings2.svg new file mode 100644 index 0000000000..e0385c28d1 --- /dev/null +++ b/editor/icons/NodeWarnings2.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8.0292969 2.0019531a1.0001 1.0001 0 0 0 -.8867188.484375l-6 9.9999999a1.0001 1.0001 0 0 0 .8574219 1.513672h12a1.0001 1.0001 0 0 0 .857422-1.513672l-2.326172-3.876953c-.89392-.5083134-1.507327-1.4610509-1.529297-2.5488281l-2.1445311-3.5742188a1.0001 1.0001 0 0 0 -.828125-.484375zm-1.0292969 2.9980469h2v5h-2zm0 6h2v2h-2z" fill="#ffdd65"/><g fill="#f95252"><path d="m14 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z"/><path d="m15.447266 4.6210938c-.430501.2402237-.923653.3789062-1.447266.3789062-.522676 0-1.015355-.1375274-1.445312-.3769531a2 2 0 0 0 -.554688 1.3769531 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.552734-1.3789062z"/></g></svg> diff --git a/editor/icons/NodeWarnings3.svg b/editor/icons/NodeWarnings3.svg new file mode 100644 index 0000000000..53c0e70034 --- /dev/null +++ b/editor/icons/NodeWarnings3.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8.0292969 2.0019531a1.0001 1.0001 0 0 0 -.8867188.484375l-6 9.9999999a1.0001 1.0001 0 0 0 .8574219 1.513672h12a1.0001 1.0001 0 0 0 .982422-1.171875c-.308689.108606-.638692.171875-.982422.171875-1.645008 0-3-1.354992-3-3a1.0001 1.0001 0 0 0 0-.0019531c.002071-.7569921.302544-1.4803618.818359-2.0332031-.464296-.5178712-.798903-1.1662278-.816406-1.9042969l-2.1445311-3.5742188a1.0001 1.0001 0 0 0 -.828125-.484375zm-1.0292969 2.9980469h2v5h-2zm6.095703 4.7636719c-.02286.0837076-.095296.1479891-.095703.2363281v.001953c.001004.551209.418791.97816.964844.996094l-.712891-1.1875001c-.051505-.0169949-.103183-.0337067-.15625-.046875zm-6.095703 1.2363281h2v2h-2z" fill="#ffdd65"/><path d="m14 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm1.447266 4.6210938c-.430501.2402237-.923653.3789062-1.447266.3789062-.522676 0-1.015355-.1375274-1.445312-.3769531a2 2 0 0 0 -.554688 1.3769531 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.552734-1.3789062zm0 4c-.430501.2402236-.923653.3789062-1.447266.3789062-.522676 0-1.015355-.1375274-1.445312-.3769531a2 2 0 0 0 -.554688 1.3769531 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.552734-1.3789062z" fill="#f95252" stroke-dashoffset="16.5" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg> diff --git a/editor/icons/NodeWarnings4Plus.svg b/editor/icons/NodeWarnings4Plus.svg new file mode 100644 index 0000000000..64c0a0671d --- /dev/null +++ b/editor/icons/NodeWarnings4Plus.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8.0292969 2.0019531a1.0001 1.0001 0 0 0 -.8867188.484375l-6 9.9999999a1.0001 1.0001 0 0 0 .8574219 1.513672h9a1.0001 1.0001 0 0 0 0-.001953c.002025-.740254.278882-1.453739.773438-2.001953-.478045-.532242-.773438-1.231924-.773438-1.996094a1.0001 1.0001 0 0 0 0-.0019531c.002071-.7569921.302544-1.4803618.818359-2.0332031-.464296-.5178713-.798903-1.1662278-.816406-1.9042969l-2.1445311-3.5742188a1.0001 1.0001 0 0 0 -.828125-.484375zm-1.0292969 2.9980469h2v5h-2zm6.095703 4.7636719c-.02286.0837076-.095296.1479891-.095703.2363281v.001953c.001004.551209.418791.97816.964844.996094l-.712891-1.1875001c-.051505-.0169949-.103183-.0337067-.15625-.046875zm-6.095703 1.2363281h2v2h-2zm6.095703 2.763672c-.02286.083707-.095296.147988-.095703.236328h1c-.326848 0-.598793-.160518-.904297-.236328z" fill="#ffdd65"/><g fill="#f95252" stroke-dashoffset="16.5" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m14 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z"/><path d="m15.447266 8.6210938c-.430501.2402236-.923653.3789062-1.447266.3789062-.522676 0-1.015355-.1375274-1.445312-.3769531a2 2 0 0 0 -.554688 1.3769531 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.552734-1.3789062z"/><path d="m15.447266 4.6210938c-.430501.2402237-.923653.3789062-1.447266.3789062-.522676 0-1.015355-.1375274-1.445312-.3769531a2 2 0 0 0 -.554688 1.3769531 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.552734-1.3789062z"/><path d="m15.447266 12.621094c-.430501.240224-.923653.378906-1.447266.378906-.522676 0-1.015355-.137527-1.445312-.376953a2 2 0 0 0 -.554688 1.376953 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.552734-1.378906z"/></g></svg> diff --git a/editor/icons/ShapeCast3D.svg b/editor/icons/ShapeCast3D.svg new file mode 100644 index 0000000000..c9f24a59b4 --- /dev/null +++ b/editor/icons/ShapeCast3D.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><path d="m7 1v9h-3l4 5 4-5h-3v-9z"/><circle cx="7.990566" cy="4.8202" r="4.009434"/></g></svg> diff --git a/editor/icons/SystemFont.svg b/editor/icons/SystemFont.svg new file mode 100644 index 0000000000..a6f62d56d3 --- /dev/null +++ b/editor/icons/SystemFont.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path style="fill:#e0e0e0;fill-opacity:1;stroke-width:.714755" d="m5.787 1-.402 1.613c-.352.265-.71.122-1.012-.111l-.904-.541L2.46 2.973l.853 1.425c-.058.438-.412.586-.79.635-.343.065-.674.216-1.024.213V6.72c.367 0 .715.157 1.074.224.371.032.716.243.727.65l-.84 1.4 1.008 1.01c.443-.266.895-.53 1.33-.802.349-.044.675.139.674.506l.314 1.258c.459-.059 1.099.115 1.45-.082.117-.475.242-.954.35-1.428A.67.67 0 0 1 8 9.195V7.5H6.5a.519.519 0 0 0-.281.084A.491.491 0 0 0 6 8v.5H4v-4h5.75c-.005-.22.107-.434.254-.625l.543-.902L9.535 1.96l-1.426.853c-.437-.058-.588-.412-.636-.79L7.217 1h-1.43z"/><path d="M4.5 5v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V7h2a1 1 0 0 1 1 1h1V5h-6z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/TorusMesh.svg b/editor/icons/TorusMesh.svg new file mode 100644 index 0000000000..2ed973d3cf --- /dev/null +++ b/editor/icons/TorusMesh.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="8" cy="7.5" fill="none" rx="6" ry="3.5" stroke="#ffca5f" stroke-linecap="square" stroke-linejoin="round" stroke-width="2"/></svg> diff --git a/editor/import/post_import_plugin_skeleton_renamer.cpp b/editor/import/post_import_plugin_skeleton_renamer.cpp index bf84348ac3..69c0a047e4 100644 --- a/editor/import/post_import_plugin_skeleton_renamer.cpp +++ b/editor/import/post_import_plugin_skeleton_renamer.cpp @@ -154,16 +154,28 @@ void PostImportPluginSkeletonRenamer::internal_process(InternalImportCategory p_ Ref<Animation> anim = ap->get_animation(name); int track_len = anim->get_track_count(); for (int i = 0; i < track_len; i++) { - if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) { - continue; - } String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *orig_node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); - if (node) { + while (node) { Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); if (track_skeleton && track_skeleton == skeleton) { - anim->track_set_path(i, String("%") + unique_name + String(":") + anim->track_get_path(i).get_concatenated_subnames()); + if (node == orig_node) { + if (anim->track_get_path(i).get_subname_count() > 0) { + anim->track_set_path(i, UNIQUE_NODE_PREFIX + unique_name + String(":") + anim->track_get_path(i).get_concatenated_subnames()); + } else { + anim->track_set_path(i, UNIQUE_NODE_PREFIX + unique_name); + } + } else { + if (anim->track_get_path(i).get_subname_count() > 0) { + anim->track_set_path(i, UNIQUE_NODE_PREFIX + unique_name + "/" + node->get_path_to(orig_node) + String(":") + anim->track_get_path(i).get_concatenated_subnames()); + } else { + anim->track_set_path(i, UNIQUE_NODE_PREFIX + unique_name + "/" + node->get_path_to(orig_node)); + } + } + break; } + node = node->get_parent(); } } } diff --git a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp index 01e145e766..4f00bd120a 100644 --- a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp +++ b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp @@ -34,11 +34,11 @@ #include "scene/3d/importer_mesh_instance_3d.h" #include "scene/3d/skeleton_3d.h" #include "scene/animation/animation_player.h" -#include "scene/resources/animation.h" #include "scene/resources/bone_map.h" void PostImportPluginSkeletonRestFixer::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) { if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) { + r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/normalize_position_tracks"), true)); r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/overwrite_axis"), true)); r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/fix_silhouette/enable"), false)); @@ -89,6 +89,53 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory } } + // Set motion scale to Skeleton if normalize position tracks. + if (bool(p_options["retarget/rest_fixer/normalize_position_tracks"])) { + int src_bone_idx = src_skeleton->find_bone(profile->get_scale_base_bone()); + if (src_bone_idx >= 0) { + real_t motion_scale = abs(src_skeleton->get_bone_global_rest(src_bone_idx).origin.y); + if (motion_scale > 0) { + src_skeleton->set_motion_scale(motion_scale); + } + } + + TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); + while (nodes.size()) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); + List<StringName> anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + int track_len = anim->get_track_count(); + for (int i = 0; i < track_len; i++) { + if (anim->track_get_path(i).get_subname_count() != 1 || anim->track_get_type(i) != Animation::TYPE_POSITION_3D) { + continue; + } + + if (anim->track_is_compressed(i)) { + continue; // Shouldn't occur in internal_process(). + } + + String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); + if (node) { + Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); + if (track_skeleton) { + if (track_skeleton && track_skeleton == src_skeleton) { + real_t mlt = 1 / src_skeleton->get_motion_scale(); + int key_len = anim->track_get_key_count(i); + for (int j = 0; j < key_len; j++) { + Vector3 pos = static_cast<Vector3>(anim->track_get_key_value(i, j)); + anim->track_set_key_value(i, j, pos * mlt); + } + } + } + } + } + } + } + } + // Complement Rotation track for compatibility between different rests. { TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); @@ -357,12 +404,12 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory Ref<Animation> anim = ap->get_animation(name); int track_len = anim->get_track_count(); for (int i = 0; i < track_len; i++) { - if (anim->track_get_path(i).get_subname_count() != 1 || anim->track_get_type(i) != Animation::TYPE_ROTATION_3D) { + if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) { continue; } if (anim->track_is_compressed(i)) { - continue; // TODO: Adopt to compressed track. + continue; // Shouldn't occur in internal_process(). } String track_path = String(anim->track_get_path(i).get_concatenated_names()); @@ -374,20 +421,44 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory if (bn) { int bone_idx = src_skeleton->find_bone(bn); - Quaternion old_rest = old_skeleton_rest[bone_idx].basis.get_rotation_quaternion(); - Quaternion new_rest = src_skeleton->get_bone_rest(bone_idx).basis.get_rotation_quaternion(); - Quaternion old_pg; - Quaternion new_pg; + Transform3D old_rest = old_skeleton_rest[bone_idx]; + Transform3D new_rest = src_skeleton->get_bone_rest(bone_idx); + Transform3D old_pg; + Transform3D new_pg; int parent_idx = src_skeleton->get_bone_parent(bone_idx); if (parent_idx >= 0) { - old_pg = old_skeleton_global_rest[parent_idx].basis.get_rotation_quaternion(); - new_pg = src_skeleton->get_bone_global_rest(parent_idx).basis.get_rotation_quaternion(); + old_pg = old_skeleton_global_rest[parent_idx]; + new_pg = src_skeleton->get_bone_global_rest(parent_idx); } int key_len = anim->track_get_key_count(i); - for (int j = 0; j < key_len; j++) { - Quaternion qt = static_cast<Quaternion>(anim->track_get_key_value(i, j)); - anim->track_set_key_value(i, j, new_pg.inverse() * old_pg * qt * old_rest.inverse() * old_pg.inverse() * new_pg * new_rest); + if (anim->track_get_type(i) == Animation::TYPE_ROTATION_3D) { + Quaternion old_rest_q = old_rest.basis.get_rotation_quaternion(); + Quaternion new_rest_q = new_rest.basis.get_rotation_quaternion(); + Quaternion old_pg_q = old_pg.basis.get_rotation_quaternion(); + Quaternion new_pg_q = new_pg.basis.get_rotation_quaternion(); + for (int j = 0; j < key_len; j++) { + Quaternion qt = static_cast<Quaternion>(anim->track_get_key_value(i, j)); + anim->track_set_key_value(i, j, new_pg_q.inverse() * old_pg_q * qt * old_rest_q.inverse() * old_pg_q.inverse() * new_pg_q * new_rest_q); + } + } else if (anim->track_get_type(i) == Animation::TYPE_SCALE_3D) { + Basis old_rest_b = old_rest.basis; + Basis new_rest_b = new_rest.basis; + Basis old_pg_b = old_pg.basis; + Basis new_pg_b = new_pg.basis; + for (int j = 0; j < key_len; j++) { + Basis sc = Basis().scaled(static_cast<Vector3>(anim->track_get_key_value(i, j))); + anim->track_set_key_value(i, j, (new_pg_b.inverse() * old_pg_b * sc * old_rest_b.inverse() * old_pg_b.inverse() * new_pg_b * new_rest_b).get_scale()); + } + } else { + Vector3 old_rest_o = old_rest.origin; + Vector3 new_rest_o = new_rest.origin; + Quaternion old_pg_q = old_pg.basis.get_rotation_quaternion(); + Quaternion new_pg_q = new_pg.basis.get_rotation_quaternion(); + for (int j = 0; j < key_len; j++) { + Vector3 ps = static_cast<Vector3>(anim->track_get_key_value(i, j)); + anim->track_set_key_value(i, j, new_pg_q.xform_inv(old_pg_q.xform(ps - old_rest_o)) + new_rest_o); + } } } } diff --git a/editor/import/post_import_plugin_skeleton_track_organizer.cpp b/editor/import/post_import_plugin_skeleton_track_organizer.cpp new file mode 100644 index 0000000000..01186f47fe --- /dev/null +++ b/editor/import/post_import_plugin_skeleton_track_organizer.cpp @@ -0,0 +1,127 @@ +/*************************************************************************/ +/* post_import_plugin_skeleton_track_organizer.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "post_import_plugin_skeleton_track_organizer.h" + +#include "editor/import/scene_import_settings.h" +#include "scene/3d/skeleton_3d.h" +#include "scene/animation/animation_player.h" +#include "scene/resources/bone_map.h" + +void PostImportPluginSkeletonTrackOrganizer::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) { + if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) { + r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/remove_tracks/except_bone_transform"), false)); + r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/remove_tracks/unimportant_positions"), true)); + r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/remove_tracks/unmapped_bones"), false)); + } +} + +void PostImportPluginSkeletonTrackOrganizer::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) { + if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) { + // Prepare objects. + Object *map = p_options["retarget/bone_map"].get_validated_object(); + if (!map) { + return; + } + BoneMap *bone_map = Object::cast_to<BoneMap>(map); + Ref<SkeletonProfile> profile = bone_map->get_profile(); + if (!profile.is_valid()) { + return; + } + Skeleton3D *src_skeleton = Object::cast_to<Skeleton3D>(p_node); + if (!src_skeleton) { + return; + } + bool remove_except_bone = bool(p_options["retarget/remove_tracks/except_bone_transform"]); + bool remove_positions = bool(p_options["retarget/remove_tracks/unimportant_positions"]); + bool remove_unmapped_bones = bool(p_options["retarget/remove_tracks/unmapped_bones"]); + + if (!remove_positions && !remove_unmapped_bones) { + return; + } + + TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); + while (nodes.size()) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); + List<StringName> anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + int track_len = anim->get_track_count(); + Vector<int> remove_indices; + for (int i = 0; i < track_len; i++) { + String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); + if (!node) { + if (remove_except_bone) { + remove_indices.push_back(i); + } + continue; + } + Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); + if (track_skeleton && track_skeleton == src_skeleton) { + if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) { + if (remove_except_bone) { + remove_indices.push_back(i); + } + continue; + } + StringName bn = anim->track_get_path(i).get_subname(0); + if (bn) { + int prof_idx = profile->find_bone(bone_map->find_profile_bone_name(bn)); + if (remove_unmapped_bones && prof_idx < 0) { + remove_indices.push_back(i); + continue; + } + if (remove_positions && anim->track_get_type(i) == Animation::TYPE_POSITION_3D && prof_idx >= 0) { + StringName prof_bn = profile->get_bone_name(prof_idx); + if (prof_bn == profile->get_root_bone() || prof_bn == profile->get_scale_base_bone()) { + continue; + } + remove_indices.push_back(i); + } + } + } + if (remove_except_bone) { + remove_indices.push_back(i); + } + } + + remove_indices.reverse(); + for (int i = 0; i < remove_indices.size(); i++) { + anim->remove_track(remove_indices[i]); + } + } + } + } +} + +PostImportPluginSkeletonTrackOrganizer::PostImportPluginSkeletonTrackOrganizer() { +} diff --git a/editor/import/post_import_plugin_skeleton_track_organizer.h b/editor/import/post_import_plugin_skeleton_track_organizer.h new file mode 100644 index 0000000000..1830861430 --- /dev/null +++ b/editor/import/post_import_plugin_skeleton_track_organizer.h @@ -0,0 +1,46 @@ +/*************************************************************************/ +/* post_import_plugin_skeleton_track_organizer.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef POST_IMPORT_PLUGIN_SKELETON_TRACK_ORGANIZER_H +#define POST_IMPORT_PLUGIN_SKELETON_TRACK_ORGANIZER_H + +#include "resource_importer_scene.h" + +class PostImportPluginSkeletonTrackOrganizer : public EditorScenePostImportPlugin { + GDCLASS(PostImportPluginSkeletonTrackOrganizer, EditorScenePostImportPlugin); + +public: + virtual void get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) override; + virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) override; + + PostImportPluginSkeletonTrackOrganizer(); +}; + +#endif // POST_IMPORT_PLUGIN_SKELETON_TRACK_ORGANIZER_H diff --git a/editor/import/resource_importer_bitmask.cpp b/editor/import/resource_importer_bitmask.cpp index 966719dc48..c03962b8a4 100644 --- a/editor/import/resource_importer_bitmask.cpp +++ b/editor/import/resource_importer_bitmask.cpp @@ -103,7 +103,7 @@ Error ResourceImporterBitMap::import(const String &p_source_file, const String & } } - return ResourceSaver::save(p_save_path + ".res", bitmap); + return ResourceSaver::save(bitmap, p_save_path + ".res"); } ResourceImporterBitMap::ResourceImporterBitMap() { diff --git a/editor/import/resource_importer_bmfont.cpp b/editor/import/resource_importer_bmfont.cpp index 987ca4b911..14b5638755 100644 --- a/editor/import/resource_importer_bmfont.cpp +++ b/editor/import/resource_importer_bmfont.cpp @@ -84,7 +84,7 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String & } print_verbose("Saving to: " + p_save_path + ".fontdata"); - err = ResourceSaver::save(p_save_path + ".fontdata", font, flg); + err = ResourceSaver::save(font, p_save_path + ".fontdata", flg); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save font to file \"" + p_save_path + ".res\"."); print_verbose("Done saving to: " + p_save_path + ".fontdata"); return OK; diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp index 0b3622e3c0..8b429e74d1 100644 --- a/editor/import/resource_importer_csv_translation.cpp +++ b/editor/import/resource_importer_csv_translation.cpp @@ -131,7 +131,7 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const String save_path = p_source_file.get_basename() + "." + translations[i]->get_locale() + ".translation"; - ResourceSaver::save(save_path, xlt); + ResourceSaver::save(xlt, save_path); if (r_gen_files) { r_gen_files->push_back(save_path); } diff --git a/editor/import/resource_importer_dynamic_font.cpp b/editor/import/resource_importer_dynamic_font.cpp index f1a70ff30a..32fd94b093 100644 --- a/editor/import/resource_importer_dynamic_font.cpp +++ b/editor/import/resource_importer_dynamic_font.cpp @@ -219,7 +219,7 @@ Error ResourceImporterDynamicFont::import(const String &p_source_file, const Str } print_verbose("Saving to: " + p_save_path + ".fontdata"); - Error err = ResourceSaver::save(p_save_path + ".fontdata", font, flg); + Error err = ResourceSaver::save(font, p_save_path + ".fontdata", flg); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save font to file \"" + p_save_path + ".res\"."); print_verbose("Done saving to: " + p_save_path + ".fontdata"); return OK; diff --git a/editor/import/resource_importer_imagefont.cpp b/editor/import/resource_importer_imagefont.cpp index ea84d4c883..374cbe7ce2 100644 --- a/editor/import/resource_importer_imagefont.cpp +++ b/editor/import/resource_importer_imagefont.cpp @@ -159,7 +159,7 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin } print_verbose("Saving to: " + p_save_path + ".fontdata"); - err = ResourceSaver::save(p_save_path + ".fontdata", font, flg); + err = ResourceSaver::save(font, p_save_path + ".fontdata", flg); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save font to file \"" + p_save_path + ".res\"."); print_verbose("Done saving to: " + p_save_path + ".fontdata"); return OK; diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index a5dfd67d18..2e6de95a46 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -391,7 +391,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const texture_import->bptc_ldr = bptc_ldr; texture_import->mipmaps = mipmaps; texture_import->used_channels = used_channels; - _check_compress_ctex(texture_import); + _check_compress_ctex(p_source_file, texture_import); if (r_metadata) { Dictionary metadata; metadata["vram_texture"] = compress_mode == COMPRESS_VRAM_COMPRESSED; @@ -472,7 +472,7 @@ ResourceImporterLayeredTexture::ResourceImporterLayeredTexture() { ResourceImporterLayeredTexture::~ResourceImporterLayeredTexture() { } -void ResourceImporterLayeredTexture::_check_compress_ctex(Ref<LayeredTextureImport> r_texture_import) { +void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source_file, Ref<LayeredTextureImport> r_texture_import) { String extension = get_save_extension(); ERR_FAIL_NULL(r_texture_import->csource); if (r_texture_import->compress_mode != COMPRESS_VRAM_COMPRESSED) { @@ -542,5 +542,5 @@ void ResourceImporterLayeredTexture::_check_compress_ctex(Ref<LayeredTextureImpo } return; } - EditorNode::add_io_error(TTR("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correctly on PC.")); + EditorNode::add_io_error(vformat(TTR("%s: No suitable PC VRAM compression algorithm enabled in Project Settings (S3TC or BPTC). This texture may not display correctly on desktop platforms."), p_source_file)); } diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index 5a29010c3b..e292390fb3 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -87,7 +87,7 @@ protected: static ResourceImporterLayeredTexture *singleton; public: - void _check_compress_ctex(Ref<LayeredTextureImport> r_texture_import); + void _check_compress_ctex(const String &p_source_file, Ref<LayeredTextureImport> r_texture_import); static ResourceImporterLayeredTexture *get_singleton() { return singleton; } virtual String get_importer_name() const override; diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 6fbfecfdfa..d1c4e1f8dd 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -519,7 +519,7 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s String save_path = p_save_path + ".mesh"; - err = ResourceSaver::save(save_path, meshes.front()->get()); + err = ResourceSaver::save(meshes.front()->get(), save_path); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save Mesh to file '" + save_path + "'."); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 860269bfcb..3c0de61d24 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -743,6 +743,163 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, HashMap<R return p_node; } +Node *ResourceImporterScene::_pre_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps) { + // children first + for (int i = 0; i < p_node->get_child_count(); i++) { + Node *r = _pre_fix_animations(p_node->get_child(i), p_root, p_node_data, p_animation_data, p_animation_fps); + if (!r) { + i--; //was erased + } + } + + String import_id = p_node->get_meta("import_id", "PATH:" + p_root->get_path_to(p_node)); + + Dictionary node_settings; + if (p_node_data.has(import_id)) { + node_settings = p_node_data[import_id]; + } + + { + //make sure this is unique + node_settings = node_settings.duplicate(true); + //fill node settings for this node with default values + List<ImportOption> iopts; + get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts); + for (const ImportOption &E : iopts) { + if (!node_settings.has(E.option.name)) { + node_settings[E.option.name] = E.default_value; + } + } + } + + if (Object::cast_to<AnimationPlayer>(p_node)) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); + + Array animation_clips; + { + int clip_count = node_settings["clips/amount"]; + + for (int i = 0; i < clip_count; i++) { + String name = node_settings["clip_" + itos(i + 1) + "/name"]; + int from_frame = node_settings["clip_" + itos(i + 1) + "/start_frame"]; + int end_frame = node_settings["clip_" + itos(i + 1) + "/end_frame"]; + Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)node_settings["clip_" + itos(i + 1) + "/loop_mode"]); + bool save_to_file = node_settings["clip_" + itos(i + 1) + "/save_to_file/enabled"]; + bool save_to_path = node_settings["clip_" + itos(i + 1) + "/save_to_file/path"]; + bool save_to_file_keep_custom = node_settings["clip_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"]; + + animation_clips.push_back(name); + animation_clips.push_back(from_frame / p_animation_fps); + animation_clips.push_back(end_frame / p_animation_fps); + animation_clips.push_back(loop_mode); + animation_clips.push_back(save_to_file); + animation_clips.push_back(save_to_path); + animation_clips.push_back(save_to_file_keep_custom); + } + } + + if (animation_clips.size()) { + _create_clips(ap, animation_clips, true); + } else { + List<StringName> anims; + ap->get_animation_list(&anims); + AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = { + AnimationImportTracks(int(node_settings["import_tracks/position"])), + AnimationImportTracks(int(node_settings["import_tracks/rotation"])), + AnimationImportTracks(int(node_settings["import_tracks/scale"])) + }; + if (anims.size() > 1 && (import_tracks_mode[0] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[1] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[2] != ANIMATION_IMPORT_TRACKS_IF_PRESENT)) { + _optimize_track_usage(ap, import_tracks_mode); + } + } + } + + return p_node; +} + +Node *ResourceImporterScene::_post_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps) { + // children first + for (int i = 0; i < p_node->get_child_count(); i++) { + Node *r = _post_fix_animations(p_node->get_child(i), p_root, p_node_data, p_animation_data, p_animation_fps); + if (!r) { + i--; //was erased + } + } + + String import_id = p_node->get_meta("import_id", "PATH:" + p_root->get_path_to(p_node)); + + Dictionary node_settings; + if (p_node_data.has(import_id)) { + node_settings = p_node_data[import_id]; + } + + { + //make sure this is unique + node_settings = node_settings.duplicate(true); + //fill node settings for this node with default values + List<ImportOption> iopts; + get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts); + for (const ImportOption &E : iopts) { + if (!node_settings.has(E.option.name)) { + node_settings[E.option.name] = E.default_value; + } + } + } + + if (Object::cast_to<AnimationPlayer>(p_node)) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); + + bool use_optimizer = node_settings["optimizer/enabled"]; + float anim_optimizer_linerr = node_settings["optimizer/max_linear_error"]; + float anim_optimizer_angerr = node_settings["optimizer/max_angular_error"]; + float anim_optimizer_maxang = node_settings["optimizer/max_angle"]; + + if (use_optimizer) { + _optimize_animations(ap, anim_optimizer_linerr, anim_optimizer_angerr, anim_optimizer_maxang); + } + + bool use_compression = node_settings["compression/enabled"]; + int anim_compression_page_size = node_settings["compression/page_size"]; + + if (use_compression) { + _compress_animations(ap, anim_compression_page_size); + } + + List<StringName> anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + if (p_animation_data.has(name)) { + Dictionary anim_settings = p_animation_data[name]; + { + //fill with default values + List<ImportOption> iopts; + get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts); + for (const ImportOption &F : iopts) { + if (!anim_settings.has(F.option.name)) { + anim_settings[F.option.name] = F.default_value; + } + } + } + + anim->set_loop_mode(static_cast<Animation::LoopMode>((int)anim_settings["settings/loop_mode"])); + bool save = anim_settings["save_to_file/enabled"]; + String path = anim_settings["save_to_file/path"]; + bool keep_custom = anim_settings["save_to_file/keep_custom_tracks"]; + + Ref<Animation> saved_anim = _save_animation_to_file(anim, save, path, keep_custom); + + if (saved_anim != anim) { + Ref<AnimationLibrary> al = ap->get_animation_library(ap->find_animation_library(anim)); + al->add_animation(name, saved_anim); //replace + } + } + } + } + + return p_node; +} + Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) { // children first for (int i = 0; i < p_node->get_child_count(); i++) { @@ -1012,83 +1169,6 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap< post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, p_root, p_node, Ref<Resource>(), node_settings); } - bool use_optimizer = node_settings["optimizer/enabled"]; - float anim_optimizer_linerr = node_settings["optimizer/max_linear_error"]; - float anim_optimizer_angerr = node_settings["optimizer/max_angular_error"]; - float anim_optimizer_maxang = node_settings["optimizer/max_angle"]; - - if (use_optimizer) { - _optimize_animations(ap, anim_optimizer_linerr, anim_optimizer_angerr, anim_optimizer_maxang); - } - - Array animation_clips; - { - int clip_count = node_settings["clips/amount"]; - - for (int i = 0; i < clip_count; i++) { - String name = node_settings["clip_" + itos(i + 1) + "/name"]; - int from_frame = node_settings["clip_" + itos(i + 1) + "/start_frame"]; - int end_frame = node_settings["clip_" + itos(i + 1) + "/end_frame"]; - Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)node_settings["clip_" + itos(i + 1) + "/loop_mode"]); - bool save_to_file = node_settings["clip_" + itos(i + 1) + "/save_to_file/enabled"]; - bool save_to_path = node_settings["clip_" + itos(i + 1) + "/save_to_file/path"]; - bool save_to_file_keep_custom = node_settings["clip_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"]; - - animation_clips.push_back(name); - animation_clips.push_back(from_frame / p_animation_fps); - animation_clips.push_back(end_frame / p_animation_fps); - animation_clips.push_back(loop_mode); - animation_clips.push_back(save_to_file); - animation_clips.push_back(save_to_path); - animation_clips.push_back(save_to_file_keep_custom); - } - } - - if (animation_clips.size()) { - _create_clips(ap, animation_clips, true); - } else { - List<StringName> anims; - ap->get_animation_list(&anims); - for (const StringName &name : anims) { - Ref<Animation> anim = ap->get_animation(name); - if (p_animation_data.has(name)) { - Dictionary anim_settings = p_animation_data[name]; - { - //fill with default values - List<ImportOption> iopts; - get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts); - for (const ImportOption &F : iopts) { - if (!anim_settings.has(F.option.name)) { - anim_settings[F.option.name] = F.default_value; - } - } - } - - anim->set_loop_mode(static_cast<Animation::LoopMode>((int)anim_settings["settings/loop_mode"])); - bool save = anim_settings["save_to_file/enabled"]; - String path = anim_settings["save_to_file/path"]; - bool keep_custom = anim_settings["save_to_file/keep_custom_tracks"]; - - Ref<Animation> saved_anim = _save_animation_to_file(anim, save, path, keep_custom); - - if (saved_anim != anim) { - Ref<AnimationLibrary> al = ap->get_animation_library(ap->find_animation_library(anim)); - al->add_animation(name, saved_anim); //replace - } - } - } - - AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = { - AnimationImportTracks(int(node_settings["import_tracks/position"])), - AnimationImportTracks(int(node_settings["import_tracks/rotation"])), - AnimationImportTracks(int(node_settings["import_tracks/scale"])) - }; - - if (anims.size() > 1 && (import_tracks_mode[0] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[1] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[2] != ANIMATION_IMPORT_TRACKS_IF_PRESENT)) { - _optimize_track_usage(ap, import_tracks_mode); - } - } - if (post_importer_plugins.size()) { List<StringName> anims; ap->get_animation_list(&anims); @@ -1113,13 +1193,6 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap< } } } - - bool use_compression = node_settings["compression/enabled"]; - int anim_compression_page_size = node_settings["compression/page_size"]; - - if (use_compression) { - _compress_animations(ap, anim_compression_page_size); - } } return p_node; @@ -1151,7 +1224,7 @@ Ref<Animation> ResourceImporterScene::_save_animation_to_file(Ref<Animation> ani } } anim->set_path(p_save_to_path, true); // Set path to save externally. - Error err = ResourceSaver::save(p_save_to_path, anim, ResourceSaver::FLAG_CHANGE_PATH); + Error err = ResourceSaver::save(anim, p_save_to_path, ResourceSaver::FLAG_CHANGE_PATH); ERR_FAIL_COND_V_MSG(err != OK, anim, "Saving of animation failed: " + p_save_to_path); return anim; } @@ -1769,7 +1842,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m } mesh = src_mesh_node->get_mesh()->get_mesh(existing); - ResourceSaver::save(save_to_file, mesh); //override + ResourceSaver::save(mesh, save_to_file); //override mesh->set_path(save_to_file, true); //takeover existing, if needed @@ -2099,7 +2172,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p post_importer_plugins.write[i]->pre_process(scene, p_options); } + _pre_fix_animations(scene, scene, node_data, animation_data, fps); _post_fix_node(scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps); + _post_fix_animations(scene, scene, node_data, animation_data, fps); String root_type = p_options["nodes/root_type"]; root_type = root_type.split(" ")[0]; // full root_type is "ClassName (filename.gd)" for a script global class. @@ -2235,14 +2310,14 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p } print_verbose("Saving animation to: " + p_save_path + ".scn"); - err = ResourceSaver::save(p_save_path + ".res", library); //do not take over, let the changed files reload themselves + err = ResourceSaver::save(library, p_save_path + ".res"); //do not take over, let the changed files reload themselves ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save animation to file '" + p_save_path + ".res'."); } else { Ref<PackedScene> packer = memnew(PackedScene); packer->pack(scene); print_verbose("Saving scene to: " + p_save_path + ".scn"); - err = ResourceSaver::save(p_save_path + ".scn", packer); //do not take over, let the changed files reload themselves + err = ResourceSaver::save(packer, p_save_path + ".scn"); //do not take over, let the changed files reload themselves ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save scene to file '" + p_save_path + ".scn'."); } diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index db6ca0cdcf..b336931476 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -274,7 +274,9 @@ public: virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; } Node *_pre_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &r_collision_map, Pair<PackedVector3Array, PackedInt32Array> *r_occluder_arrays, List<Pair<NodePath, Node *>> &r_node_renames); + Node *_pre_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps); Node *_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps); + Node *_post_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps); Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks); void _create_clips(AnimationPlayer *anim, const Array &p_clips, bool p_bake_all); diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp index 64839bf199..d3079141e0 100644 --- a/editor/import/resource_importer_shader_file.cpp +++ b/editor/import/resource_importer_shader_file.cpp @@ -109,7 +109,7 @@ Error ResourceImporterShaderFile::import(const String &p_source_file, const Stri } } - ResourceSaver::save(p_save_path + ".res", shader_file); + ResourceSaver::save(shader_file, p_save_path + ".res"); return OK; } diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index deb3047864..0eed6184c0 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -597,7 +597,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String } if (!ok_on_pc) { - EditorNode::add_io_error(TTR("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correctly on PC.")); + EditorNode::add_io_error(vformat(TTR("%s: No suitable desktop VRAM compression algorithm enabled in Project Settings (S3TC or BPTC). This texture may not display correctly on desktop platforms."), p_source_file)); } } else { //import normally diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp index 93afb3381e..bae1b903c6 100644 --- a/editor/import/resource_importer_texture_atlas.cpp +++ b/editor/import/resource_importer_texture_atlas.cpp @@ -88,7 +88,7 @@ Error ResourceImporterTextureAtlas::import(const String &p_source_file, const St //use an xpm because it's size independent, the editor images are vector and size dependent //it's a simple hack Ref<Image> broken = memnew(Image((const char **)atlas_import_failed_xpm)); - ResourceSaver::save(p_save_path + ".tex", ImageTexture::create_from_image(broken)); + ResourceSaver::save(ImageTexture::create_from_image(broken), p_save_path + ".tex"); return OK; } @@ -386,7 +386,7 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file } String save_path = p_base_paths[E.key] + ".res"; - ResourceSaver::save(save_path, texture); + ResourceSaver::save(texture, save_path); idx++; } diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index f0ba1eb7a1..a1e00f7d30 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -33,7 +33,7 @@ #include "core/io/file_access.h" #include "core/io/marshalls.h" #include "core/io/resource_saver.h" -#include "scene/resources/audio_stream_sample.h" +#include "scene/resources/audio_stream_wav.h" const float TRIM_DB_LIMIT = -50; const int TRIM_FADE_OUT_FRAMES = 500; @@ -55,7 +55,7 @@ String ResourceImporterWAV::get_save_extension() const { } String ResourceImporterWAV::get_resource_type() const { - return "AudioStreamSample"; + return "AudioStreamWAV"; } bool ResourceImporterWAV::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const { @@ -86,7 +86,7 @@ void ResourceImporterWAV::get_import_options(const String &p_path, List<ImportOp r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "force/max_rate_hz", PROPERTY_HINT_RANGE, "11025,192000,1,exp"), 44100)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "edit/trim"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "edit/normalize"), false)); - // Keep the `edit/loop_mode` enum in sync with AudioStreamSample::LoopMode (note: +1 offset due to "Detect From WAV"). + // Keep the `edit/loop_mode` enum in sync with AudioStreamWAV::LoopMode (note: +1 offset due to "Detect From WAV"). r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "edit/loop_mode", PROPERTY_HINT_ENUM, "Detect From WAV,Disabled,Forward,Ping-Pong,Backward", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "edit/loop_begin"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "edit/loop_end"), -1)); @@ -130,7 +130,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s int format_bits = 0; int format_channels = 0; - AudioStreamSample::LoopMode loop_mode = AudioStreamSample::LOOP_DISABLED; + AudioStreamWAV::LoopMode loop_mode = AudioStreamWAV::LOOP_DISABLED; uint16_t compression_code = 1; bool format_found = false; bool data_found = false; @@ -282,11 +282,11 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s int loop_type = file->get_32(); if (loop_type == 0x00 || loop_type == 0x01 || loop_type == 0x02) { if (loop_type == 0x00) { - loop_mode = AudioStreamSample::LOOP_FORWARD; + loop_mode = AudioStreamWAV::LOOP_FORWARD; } else if (loop_type == 0x01) { - loop_mode = AudioStreamSample::LOOP_PINGPONG; + loop_mode = AudioStreamWAV::LOOP_PINGPONG; } else if (loop_type == 0x02) { - loop_mode = AudioStreamSample::LOOP_BACKWARD; + loop_mode = AudioStreamWAV::LOOP_BACKWARD; } loop_begin = file->get_32(); loop_end = file->get_32(); @@ -386,7 +386,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s bool trim = p_options["edit/trim"]; - if (trim && (loop_mode != AudioStreamSample::LOOP_DISABLED) && format_channels > 0) { + if (trim && (loop_mode != AudioStreamWAV::LOOP_DISABLED) && format_channels > 0) { int first = 0; int last = (frames / format_channels) - 1; bool found = false; @@ -431,7 +431,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s } if (import_loop_mode >= 2) { - loop_mode = (AudioStreamSample::LoopMode)(import_loop_mode - 1); + loop_mode = (AudioStreamWAV::LoopMode)(import_loop_mode - 1); loop_begin = p_options["edit/loop_begin"]; loop_end = p_options["edit/loop_end"]; // Wrap around to max frames, so `-1` can be used to select the end, etc. @@ -463,10 +463,10 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s } Vector<uint8_t> dst_data; - AudioStreamSample::Format dst_format; + AudioStreamWAV::Format dst_format; if (compression == 1) { - dst_format = AudioStreamSample::FORMAT_IMA_ADPCM; + dst_format = AudioStreamWAV::FORMAT_IMA_ADPCM; if (format_channels == 1) { _compress_ima_adpcm(data, dst_data); } else { @@ -503,7 +503,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s } } else { - dst_format = is16 ? AudioStreamSample::FORMAT_16_BITS : AudioStreamSample::FORMAT_8_BITS; + dst_format = is16 ? AudioStreamWAV::FORMAT_16_BITS : AudioStreamWAV::FORMAT_8_BITS; dst_data.resize(data.size() * (is16 ? 2 : 1)); { uint8_t *w = dst_data.ptrw(); @@ -521,7 +521,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s } } - Ref<AudioStreamSample> sample; + Ref<AudioStreamWAV> sample; sample.instantiate(); sample->set_data(dst_data); sample->set_format(dst_format); @@ -531,7 +531,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s sample->set_loop_end(loop_end); sample->set_stereo(format_channels == 2); - ResourceSaver::save(p_save_path + ".sample", sample); + ResourceSaver::save(sample, p_save_path + ".sample"); return OK; } diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index 0e2967dc42..6c12464b5a 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -35,6 +35,7 @@ #include "editor/editor_inspector.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/3d/importer_mesh_instance_3d.h" #include "scene/animation/animation_player.h" #include "scene/resources/importer_mesh.h" @@ -502,7 +503,7 @@ void SceneImportSettings::_update_camera() { Transform3D xf; xf.basis = Basis(Vector3(1, 0, 0), rot_x) * Basis(Vector3(0, 1, 0), rot_y); xf.origin = center; - xf.translate(0, 0, camera_size); + xf.translate_local(0, 0, camera_size); camera->set_transform(xf); } @@ -1184,7 +1185,7 @@ void SceneImportSettings::_save_dir_confirm() { ERR_CONTINUE(!material_map.has(id)); MaterialData &md = material_map[id]; - Error err = ResourceSaver::save(path, md.material); + Error err = ResourceSaver::save(md.material, path); if (err != OK) { EditorNode::get_singleton()->add_io_error(TTR("Can't make material external to file, write error:") + "\n\t" + path); continue; diff --git a/editor/import_defaults_editor.cpp b/editor/import_defaults_editor.cpp index 9d96822aef..a70f5225e9 100644 --- a/editor/import_defaults_editor.cpp +++ b/editor/import_defaults_editor.cpp @@ -36,6 +36,7 @@ #include "editor/editor_autoload_settings.h" #include "editor/editor_plugin_settings.h" #include "editor/editor_sectioned_inspector.h" +#include "editor/editor_settings.h" #include "editor/localization_editor.h" #include "editor/shader_globals_editor.h" #include "scene/gui/center_container.h" diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index f9e5885f9d..087ef48b56 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -34,6 +34,7 @@ #include "editor/editor_node.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" class ImportDockParameters : public Object { GDCLASS(ImportDockParameters, Object); diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index a509cf3d8f..79d94246ad 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -33,6 +33,7 @@ #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/plugins/script_editor_plugin.h" InspectorDock *InspectorDock::singleton = nullptr; @@ -64,6 +65,9 @@ void InspectorDock::_menu_option_confirm(int p_option, bool p_confirmed) { case COLLAPSE_ALL: { _menu_collapseall(); } break; + case EXPAND_REVERTABLE: { + _menu_expand_revertable(); + } break; case RESOURCE_SAVE: { _save_resource(false); @@ -400,6 +404,10 @@ void InspectorDock::_menu_expandall() { inspector->expand_all_folding(); } +void InspectorDock::_menu_expand_revertable() { + inspector->expand_revertable(); +} + void InspectorDock::_warning_pressed() { warning_dialog->popup_centered(); } @@ -453,6 +461,9 @@ void InspectorDock::_bind_methods() { ClassDB::bind_method("edit_resource", &InspectorDock::edit_resource); + ClassDB::bind_method("store_script_properties", &InspectorDock::store_script_properties); + ClassDB::bind_method("apply_script_properties", &InspectorDock::apply_script_properties); + ADD_SIGNAL(MethodInfo("request_help")); } @@ -515,6 +526,8 @@ void InspectorDock::update(Object *p_object) { p->clear(); p->add_icon_shortcut(get_theme_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons")), ED_SHORTCUT("property_editor/expand_all", TTR("Expand All")), EXPAND_ALL); p->add_icon_shortcut(get_theme_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons")), ED_SHORTCUT("property_editor/collapse_all", TTR("Collapse All")), COLLAPSE_ALL); + // Calling it 'revertable' internally, because that's what the implementation is based on, but labeling it as 'non-default' because that's more user friendly, even if not 100% accurate. + p->add_shortcut(ED_SHORTCUT("property_editor/expand_revertable", TTR("Expand Non-Default")), EXPAND_REVERTABLE); p->add_separator(TTR("Property Name Style")); p->add_radio_check_item(TTR("Raw"), PROPERTY_NAME_STYLE_RAW); @@ -565,6 +578,31 @@ EditorPropertyNameProcessor::Style InspectorDock::get_property_name_style() cons return property_name_style; } +void InspectorDock::store_script_properties(Object *p_object) { + ERR_FAIL_NULL(p_object); + ScriptInstance *si = p_object->get_script_instance(); + if (!si) { + return; + } + si->get_property_state(stored_properties); +} + +void InspectorDock::apply_script_properties(Object *p_object) { + ERR_FAIL_NULL(p_object); + ScriptInstance *si = p_object->get_script_instance(); + if (!si) { + return; + } + + for (const Pair<StringName, Variant> &E : stored_properties) { + Variant current; + if (si->get(E.first, current) && current.get_type() == E.second.get_type()) { + si->set(E.first, E.second); + } + } + stored_properties.clear(); +} + InspectorDock::InspectorDock(EditorData &p_editor_data) { singleton = this; set_name("Inspector"); @@ -645,7 +683,7 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) { open_docs_button->set_tooltip(TTR("Open documentation for this object.")); open_docs_button->set_shortcut(ED_SHORTCUT("property_editor/open_help", TTR("Open Documentation"))); subresource_hb->add_child(open_docs_button); - open_docs_button->connect("pressed", callable_mp(this, &InspectorDock::_menu_option), varray(OBJECT_REQUEST_HELP)); + open_docs_button->connect("pressed", callable_mp(this, &InspectorDock::_menu_option).bind(OBJECT_REQUEST_HELP)); new_resource_dialog = memnew(CreateDialog); EditorNode::get_singleton()->get_gui_base()->add_child(new_resource_dialog); diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h index 536852c0f2..e32410151f 100644 --- a/editor/inspector_dock.h +++ b/editor/inspector_dock.h @@ -61,6 +61,7 @@ class InspectorDock : public VBoxContainer { COLLAPSE_ALL, EXPAND_ALL, + EXPAND_REVERTABLE, // Matches `EditorPropertyNameProcessor::Style`. PROPERTY_NAME_STYLE_RAW, @@ -100,6 +101,7 @@ class InspectorDock : public VBoxContainer { Tree *unique_resources_list_tree = nullptr; EditorPropertyNameProcessor::Style property_name_style; + List<Pair<StringName, Variant>> stored_properties; void _prepare_menu(); void _menu_option(int p_option); @@ -123,6 +125,7 @@ class InspectorDock : public VBoxContainer { void _edit_back(); void _menu_collapseall(); void _menu_expandall(); + void _menu_expand_revertable(); void _select_history(int p_idx); void _prepare_history(); @@ -149,6 +152,9 @@ public: EditorPropertyNameProcessor::Style get_property_name_style() const; + void store_script_properties(Object *p_object); + void apply_script_properties(Object *p_object); + InspectorDock(EditorData &p_editor_data); ~InspectorDock(); }; diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index 0325f4bd5c..e8fb80eb57 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -36,6 +36,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_translation_parser.h" +#include "editor/filesystem_dock.h" #include "editor/pot_generator.h" #include "scene/gui/control.h" @@ -379,6 +380,95 @@ void LocalizationEditor::_update_pot_file_extensions() { } } +void LocalizationEditor::connect_filesystem_dock_signals(FileSystemDock *p_fs_dock) { + p_fs_dock->connect("files_moved", callable_mp(this, &LocalizationEditor::_filesystem_files_moved)); + p_fs_dock->connect("file_removed", callable_mp(this, &LocalizationEditor::_filesystem_file_removed)); +} + +void LocalizationEditor::_filesystem_files_moved(const String &p_old_file, const String &p_new_file) { + // Update remaps if the moved file is a part of them. + Dictionary remaps; + bool remaps_changed = false; + + if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { + remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + } + + // Check for the keys. + if (remaps.has(p_old_file)) { + PackedStringArray remapped_files = remaps[p_old_file]; + remaps.erase(p_old_file); + remaps[p_new_file] = remapped_files; + remaps_changed = true; + print_verbose(vformat("Changed remap key \"%s\" to \"%s\" due to a moved file.", p_old_file, p_new_file)); + } + + // Check for the Array elements of the values. + Array remap_keys = remaps.keys(); + for (int i = 0; i < remap_keys.size(); i++) { + PackedStringArray remapped_files = remaps[remap_keys[i]]; + bool remapped_files_updated = false; + + for (int j = 0; j < remapped_files.size(); j++) { + int splitter_pos = remapped_files[j].rfind(":"); + String res_path = remapped_files[j].substr(0, splitter_pos); + + if (res_path == p_old_file) { + String locale_name = remapped_files[j].substr(splitter_pos + 1); + // Replace the element at that index. + remapped_files.insert(j, p_new_file + ":" + locale_name); + remapped_files.remove_at(j + 1); + remaps_changed = true; + remapped_files_updated = true; + print_verbose(vformat("Changed remap value \"%s\" to \"%s\" of key \"%s\" due to a moved file.", res_path + ":" + locale_name, remapped_files[j], remap_keys[i])); + } + } + + if (remapped_files_updated) { + remaps[remap_keys[i]] = remapped_files; + } + } + + if (remaps_changed) { + ProjectSettings::get_singleton()->set_setting("internationalization/locale/translation_remaps", remaps); + update_translations(); + emit_signal("localization_changed"); + } +} + +void LocalizationEditor::_filesystem_file_removed(const String &p_file) { + // Check if the remaps are affected. + Dictionary remaps; + + if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { + remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + } + + bool remaps_changed = remaps.has(p_file); + + if (!remaps_changed) { + Array remap_keys = remaps.keys(); + for (int i = 0; i < remap_keys.size() && !remaps_changed; i++) { + PackedStringArray remapped_files = remaps[remap_keys[i]]; + for (int j = 0; j < remapped_files.size() && !remaps_changed; j++) { + int splitter_pos = remapped_files[j].rfind(":"); + String res_path = remapped_files[j].substr(0, splitter_pos); + remaps_changed = p_file == res_path; + if (remaps_changed) { + print_verbose(vformat("Remap value \"%s\" of key \"%s\" has been removed from the file system.", remapped_files[j], remap_keys[i])); + } + } + } + } else { + print_verbose(vformat("Remap key \"%s\" has been removed from the file system.", p_file)); + } + + if (remaps_changed) { + update_translations(); + emit_signal("localization_changed"); + } +} + void LocalizationEditor::update_translations() { if (updating_translations) { return; @@ -432,6 +522,13 @@ void LocalizationEditor::update_translations() { t->set_tooltip(0, keys[i]); t->set_metadata(0, keys[i]); t->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0, false, TTR("Remove")); + + // Display that it has been removed if this is the case. + if (!FileAccess::exists(keys[i])) { + t->set_text(0, t->get_text(0) + vformat(" (%s)", TTR("Removed"))); + t->set_tooltip(0, vformat(TTR("%s cannot be found."), t->get_tooltip(0))); + } + if (keys[i] == remap_selected) { t->select(0); translation_res_option_add_button->set_disabled(false); @@ -454,6 +551,12 @@ void LocalizationEditor::update_translations() { t2->set_editable(1, true); t2->set_metadata(1, path); t2->set_tooltip(1, locale); + + // Display that it has been removed if this is the case. + if (!FileAccess::exists(path)) { + t2->set_text(0, t2->get_text(0) + vformat(" (%s)", TTR("Removed"))); + t2->set_tooltip(0, vformat(TTR("%s cannot be found."), t2->get_tooltip(0))); + } } } } diff --git a/editor/localization_editor.h b/editor/localization_editor.h index 4b41a90cc2..10ccdfdc13 100644 --- a/editor/localization_editor.h +++ b/editor/localization_editor.h @@ -36,6 +36,7 @@ #include "scene/gui/tree.h" class EditorFileDialog; +class FileSystemDock; class LocalizationEditor : public VBoxContainer { GDCLASS(LocalizationEditor, VBoxContainer); @@ -81,6 +82,9 @@ class LocalizationEditor : public VBoxContainer { void _pot_generate(const String &p_file); void _update_pot_file_extensions(); + void _filesystem_files_moved(const String &p_old_file, const String &p_new_file); + void _filesystem_file_removed(const String &p_file); + protected: void _notification(int p_what); static void _bind_methods(); @@ -88,6 +92,7 @@ protected: public: void add_translation(const String &p_translation); void update_translations(); + void connect_filesystem_dock_signals(FileSystemDock *p_fs_dock); LocalizationEditor(); }; diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp index 7061204832..6d323572e6 100644 --- a/editor/plugin_config_dialog.cpp +++ b/editor/plugin_config_dialog.cpp @@ -81,8 +81,8 @@ void PluginConfigDialog::_on_confirmed() { template_content = templates[0].content; } Ref<Script> script = ScriptServer::get_language(lang_idx)->make_template(template_content, class_name, "EditorPlugin"); - script->set_path(script_path); - ResourceSaver::save(script_path, script); + script->set_path(script_path, true); + ResourceSaver::save(script); emit_signal(SNAME("plugin_ready"), script.ptr(), active_edit->is_pressed() ? _to_absolute_plugin_path(_get_subfolder()) : ""); } else { diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index a5ca55f6df..a7d7c0145a 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -35,6 +35,8 @@ #include "core/os/keyboard.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" +#include "scene/gui/separator.h" bool AbstractPolygon2DEditor::Vertex::operator==(const AbstractPolygon2DEditor::Vertex &p_vertex) const { return polygon == p_vertex.polygon && vertex == p_vertex.vertex; @@ -292,9 +294,9 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) _commit_action(); return true; } else { - pre_move_edit = vertices; edited_point = PosVertex(insert.polygon, insert.vertex + 1, xform.affine_inverse().xform(insert.pos)); vertices.insert(edited_point.vertex, edited_point.pos); + pre_move_edit = vertices; selected_point = Vertex(edited_point.polygon, edited_point.vertex); edge_point = PosVertex(); @@ -716,19 +718,19 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) { button_create = memnew(Button); button_create->set_flat(true); add_child(button_create); - button_create->connect("pressed", callable_mp(this, &AbstractPolygon2DEditor::_menu_option), varray(MODE_CREATE)); + button_create->connect("pressed", callable_mp(this, &AbstractPolygon2DEditor::_menu_option).bind(MODE_CREATE)); button_create->set_toggle_mode(true); button_edit = memnew(Button); button_edit->set_flat(true); add_child(button_edit); - button_edit->connect("pressed", callable_mp(this, &AbstractPolygon2DEditor::_menu_option), varray(MODE_EDIT)); + button_edit->connect("pressed", callable_mp(this, &AbstractPolygon2DEditor::_menu_option).bind(MODE_EDIT)); button_edit->set_toggle_mode(true); button_delete = memnew(Button); button_delete->set_flat(true); add_child(button_delete); - button_delete->connect("pressed", callable_mp(this, &AbstractPolygon2DEditor::_menu_option), varray(MODE_DELETE)); + button_delete->connect("pressed", callable_mp(this, &AbstractPolygon2DEditor::_menu_option).bind(MODE_DELETE)); button_delete->set_toggle_mode(true); create_resource = memnew(ConfirmationDialog); diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index d397c6da67..32d97c65a9 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -34,6 +34,7 @@ #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/animation/animation_blend_tree.h" StringName AnimationNodeBlendSpace1DEditor::get_blend_position_path() const { @@ -612,7 +613,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { top_hb->add_child(tool_blend); tool_blend->set_pressed(true); tool_blend->set_tooltip(TTR("Set the blending position within the space")); - tool_blend->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_tool_switch), varray(3)); + tool_blend->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_tool_switch).bind(3)); tool_select = memnew(Button); tool_select->set_flat(true); @@ -620,7 +621,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { tool_select->set_button_group(bg); top_hb->add_child(tool_select); tool_select->set_tooltip(TTR("Select and move points, create points with RMB.")); - tool_select->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_tool_switch), varray(0)); + tool_select->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_tool_switch).bind(0)); tool_create = memnew(Button); tool_create->set_flat(true); @@ -628,7 +629,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { tool_create->set_button_group(bg); top_hb->add_child(tool_create); tool_create->set_tooltip(TTR("Create points.")); - tool_create->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_tool_switch), varray(1)); + tool_create->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_tool_switch).bind(1)); tool_erase_sep = memnew(VSeparator); top_hb->add_child(tool_erase_sep); @@ -675,7 +676,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { open_editor = memnew(Button); edit_hb->add_child(open_editor); open_editor->set_text(TTR("Open Editor")); - open_editor->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_open_editor), varray(), CONNECT_DEFERRED); + open_editor->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_open_editor), CONNECT_DEFERRED); edit_hb->hide(); open_editor->hide(); diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h index 3488b4bf30..9b06f3248f 100644 --- a/editor/plugins/animation_blend_space_1d_editor.h +++ b/editor/plugins/animation_blend_space_1d_editor.h @@ -33,11 +33,11 @@ #include "editor/editor_plugin.h" #include "editor/plugins/animation_tree_editor_plugin.h" -#include "editor/property_editor.h" #include "scene/animation/animation_blend_space_1d.h" #include "scene/gui/button.h" #include "scene/gui/graph_edit.h" #include "scene/gui/popup.h" +#include "scene/gui/separator.h" #include "scene/gui/tree.h" class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin { diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 51aaa4f010..dc764725dd 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -38,6 +38,7 @@ #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" @@ -832,7 +833,7 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() { top_hb->add_child(tool_blend); tool_blend->set_pressed(true); tool_blend->set_tooltip(TTR("Set the blending position within the space")); - tool_blend->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_tool_switch), varray(3)); + tool_blend->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_tool_switch).bind(3)); tool_select = memnew(Button); tool_select->set_flat(true); @@ -840,7 +841,7 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() { tool_select->set_button_group(bg); top_hb->add_child(tool_select); tool_select->set_tooltip(TTR("Select and move points, create points with RMB.")); - tool_select->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_tool_switch), varray(0)); + tool_select->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_tool_switch).bind(0)); tool_create = memnew(Button); tool_create->set_flat(true); @@ -848,7 +849,7 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() { tool_create->set_button_group(bg); top_hb->add_child(tool_create); tool_create->set_tooltip(TTR("Create points.")); - tool_create->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_tool_switch), varray(1)); + tool_create->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_tool_switch).bind(1)); tool_triangle = memnew(Button); tool_triangle->set_flat(true); @@ -856,7 +857,7 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() { tool_triangle->set_button_group(bg); top_hb->add_child(tool_triangle); tool_triangle->set_tooltip(TTR("Create triangles by connecting points.")); - tool_triangle->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_tool_switch), varray(2)); + tool_triangle->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_tool_switch).bind(2)); tool_erase_sep = memnew(VSeparator); top_hb->add_child(tool_erase_sep); @@ -933,7 +934,7 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() { open_editor = memnew(Button); edit_hb->add_child(open_editor); open_editor->set_text(TTR("Open Editor")); - open_editor->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_open_editor), varray(), CONNECT_DEFERRED); + open_editor->connect("pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_open_editor), CONNECT_DEFERRED); edit_hb->hide(); open_editor->hide(); diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h index 88b9072599..26471df051 100644 --- a/editor/plugins/animation_blend_space_2d_editor.h +++ b/editor/plugins/animation_blend_space_2d_editor.h @@ -33,11 +33,11 @@ #include "editor/editor_plugin.h" #include "editor/plugins/animation_tree_editor_plugin.h" -#include "editor/property_editor.h" #include "scene/animation/animation_blend_space_2d.h" #include "scene/gui/button.h" #include "scene/gui/graph_edit.h" #include "scene/gui/popup.h" +#include "scene/gui/separator.h" #include "scene/gui/tree.h" class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin { diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 5e703cf814..79be2d04b3 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -38,6 +38,7 @@ #include "editor/editor_inspector.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" @@ -147,11 +148,11 @@ void AnimationNodeBlendTreeEditor::_update_graph() { name->set_expand_to_text_length_enabled(true); node->add_child(name); node->set_slot(0, false, 0, Color(), true, 0, get_theme_color(SNAME("font_color"), SNAME("Label"))); - name->connect("text_submitted", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed), varray(agnode), CONNECT_DEFERRED); - name->connect("focus_exited", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed_focus_out), varray(name, agnode), CONNECT_DEFERRED); + name->connect("text_submitted", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed).bind(agnode), CONNECT_DEFERRED); + name->connect("focus_exited", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed_focus_out).bind(name, agnode), CONNECT_DEFERRED); base = 1; node->set_show_close_button(true); - node->connect("close_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_request), varray(E), CONNECT_DEFERRED); + node->connect("close_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_request).bind(E), CONNECT_DEFERRED); } for (int i = 0; i < agnode->get_input_count(); i++) { @@ -179,7 +180,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { } } - node->connect("dragged", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_dragged), varray(E)); + node->connect("dragged", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_dragged).bind(E)); if (AnimationTreeEditor::get_singleton()->can_edit(agnode)) { node->add_child(memnew(HSeparator)); @@ -187,7 +188,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { open_in_editor->set_text(TTR("Open Editor")); open_in_editor->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); node->add_child(open_in_editor); - open_in_editor->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_open_in_editor), varray(E), CONNECT_DEFERRED); + open_in_editor->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_open_in_editor).bind(E), CONNECT_DEFERRED); open_in_editor->set_h_size_flags(SIZE_SHRINK_CENTER); } @@ -197,7 +198,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { edit_filters->set_text(TTR("Edit Filters")); edit_filters->set_icon(get_theme_icon(SNAME("AnimationFilter"), SNAME("EditorIcons"))); node->add_child(edit_filters); - edit_filters->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_edit_filters), varray(E), CONNECT_DEFERRED); + edit_filters->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_edit_filters).bind(E), CONNECT_DEFERRED); edit_filters->set_h_size_flags(SIZE_SHRINK_CENTER); } @@ -236,7 +237,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { animations[E] = pb; node->add_child(pb); - mb->get_popup()->connect("index_pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_anim_selected), varray(options, E), CONNECT_DEFERRED); + mb->get_popup()->connect("index_pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_anim_selected).bind(options, E), CONNECT_DEFERRED); } Ref<StyleBoxFlat> sb = node->get_theme_stylebox(SNAME("frame"), SNAME("GraphNode")); @@ -961,8 +962,8 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { graph->add_valid_right_disconnect_type(0); graph->add_valid_left_disconnect_type(0); graph->set_v_size_flags(SIZE_EXPAND_FILL); - graph->connect("connection_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_connection_request), varray(), CONNECT_DEFERRED); - graph->connect("disconnection_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_disconnection_request), varray(), CONNECT_DEFERRED); + graph->connect("connection_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_connection_request), CONNECT_DEFERRED); + graph->connect("disconnection_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_disconnection_request), CONNECT_DEFERRED); graph->connect("node_selected", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_selected)); graph->connect("scroll_offset_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_scroll_changed)); graph->connect("delete_nodes_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_nodes_request)); @@ -983,7 +984,7 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { add_node->set_text(TTR("Add Node...")); graph->get_zoom_hbox()->move_child(add_node, 0); add_node->get_popup()->connect("id_pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_add_node)); - add_node->connect("about_to_popup", callable_mp(this, &AnimationNodeBlendTreeEditor::_update_options_menu), varray(false)); + add_node->connect("about_to_popup", callable_mp(this, &AnimationNodeBlendTreeEditor::_update_options_menu).bind(false)); add_options.push_back(AddOption("Animation", "AnimationNodeAnimation")); add_options.push_back(AddOption("OneShot", "AnimationNodeOneShot", 2)); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h index b5bf91a1da..18199676b8 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.h +++ b/editor/plugins/animation_blend_tree_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_plugin.h" #include "editor/plugins/animation_tree_editor_plugin.h" -#include "editor/property_editor.h" #include "scene/animation/animation_blend_tree.h" #include "scene/gui/button.h" #include "scene/gui/graph_edit.h" diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index f493c4515c..ebd7525bb8 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -1426,19 +1426,19 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() { // Render every past/future step with the capture shader. RS::get_singleton()->canvas_item_set_material(onion.capture.canvas_item, onion.capture.material->get_rid()); - onion.capture.material->set_shader_param("bkg_color", GLOBAL_GET("rendering/environment/defaults/default_clear_color")); - onion.capture.material->set_shader_param("differences_only", onion.differences_only); - onion.capture.material->set_shader_param("present", onion.differences_only ? RS::get_singleton()->viewport_get_texture(present_rid) : RID()); + onion.capture.material->set_shader_uniform("bkg_color", GLOBAL_GET("rendering/environment/defaults/default_clear_color")); + onion.capture.material->set_shader_uniform("differences_only", onion.differences_only); + onion.capture.material->set_shader_uniform("present", onion.differences_only ? RS::get_singleton()->viewport_get_texture(present_rid) : RID()); int step_off_a = onion.past ? -onion.steps : 0; int step_off_b = onion.future ? onion.steps : 0; int cidx = 0; - onion.capture.material->set_shader_param("dir_color", onion.force_white_modulate ? Color(1, 1, 1) : Color(EDITOR_GET("editors/animation/onion_layers_past_color"))); + onion.capture.material->set_shader_uniform("dir_color", onion.force_white_modulate ? Color(1, 1, 1) : Color(EDITOR_GET("editors/animation/onion_layers_past_color"))); for (int step_off = step_off_a; step_off <= step_off_b; step_off++) { if (step_off == 0) { // Skip present step and switch to the color of future. if (!onion.force_white_modulate) { - onion.capture.material->set_shader_param("dir_color", EDITOR_GET("editors/animation/onion_layers_future_color")); + onion.capture.material->set_shader_uniform("dir_color", EDITOR_GET("editors/animation/onion_layers_future_color")); } continue; } @@ -1633,7 +1633,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug onion_toggle->set_flat(true); onion_toggle->set_toggle_mode(true); onion_toggle->set_tooltip(TTR("Enable Onion Skinning")); - onion_toggle->connect("pressed", callable_mp(this, &AnimationPlayerEditor::_onion_skinning_menu), varray(ONION_SKINNING_ENABLE)); + onion_toggle->connect("pressed", callable_mp(this, &AnimationPlayerEditor::_onion_skinning_menu).bind(ONION_SKINNING_ENABLE)); hb->add_child(onion_toggle); onion_skinning = memnew(MenuButton); @@ -1720,7 +1720,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug animation->connect("item_selected", callable_mp(this, &AnimationPlayerEditor::_animation_selected)); - frame->connect("value_changed", callable_mp(this, &AnimationPlayerEditor::_seek_value_changed), make_binds(true, false)); + frame->connect("value_changed", callable_mp(this, &AnimationPlayerEditor::_seek_value_changed).bind(true, false)); scale->connect("text_submitted", callable_mp(this, &AnimationPlayerEditor::_scale_changed)); last_active = false; diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 1258b9a03c..473450b292 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -38,6 +38,7 @@ #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" @@ -1018,7 +1019,7 @@ void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) { anim->set_animation(animations_to_add[p_index]); - String base_name = animations_to_add[p_index]; + String base_name = animations_to_add[p_index].validate_node_name(); int base = 1; String name = base_name; while (state_machine->has_node(name)) { @@ -1899,7 +1900,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { tool_select->set_button_group(bg); tool_select->set_pressed(true); tool_select->set_tooltip(TTR("Select and move nodes.\nRMB: Add node at position clicked.\nShift+LMB+Drag: Connects the selected node with another node or creates a new node if you select an area without nodes.")); - tool_select->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_update_mode), varray(), CONNECT_DEFERRED); + tool_select->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_update_mode), CONNECT_DEFERRED); tool_create = memnew(Button); tool_create->set_flat(true); @@ -1907,7 +1908,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { tool_create->set_toggle_mode(true); tool_create->set_button_group(bg); tool_create->set_tooltip(TTR("Create new nodes.")); - tool_create->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_update_mode), varray(), CONNECT_DEFERRED); + tool_create->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_update_mode), CONNECT_DEFERRED); tool_connect = memnew(Button); tool_connect->set_flat(true); @@ -1915,7 +1916,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { tool_connect->set_toggle_mode(true); tool_connect->set_button_group(bg); tool_connect->set_tooltip(TTR("Connect nodes.")); - tool_connect->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_update_mode), varray(), CONNECT_DEFERRED); + tool_connect->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_update_mode), CONNECT_DEFERRED); tool_erase_hb = memnew(HBoxContainer); top_hb->add_child(tool_erase_hb); @@ -1938,7 +1939,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { tool_erase = memnew(Button); tool_erase->set_flat(true); tool_erase->set_tooltip(TTR("Remove selected node or transition.")); - tool_erase->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_erase_selected), varray(false)); + tool_erase->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_erase_selected).bind(false)); tool_erase->set_disabled(true); tool_erase_hb->add_child(tool_erase); diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h index ea16abd64c..165940e639 100644 --- a/editor/plugins/animation_state_machine_editor.h +++ b/editor/plugins/animation_state_machine_editor.h @@ -33,7 +33,6 @@ #include "editor/editor_plugin.h" #include "editor/plugins/animation_tree_editor_plugin.h" -#include "editor/property_editor.h" #include "scene/animation/animation_node_state_machine.h" #include "scene/gui/button.h" #include "scene/gui/graph_edit.h" diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 7ea6906d72..bce4c9de8e 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -86,7 +86,7 @@ void AnimationTreeEditor::_update_path() { b->set_button_group(group); b->set_pressed(true); b->set_focus_mode(FOCUS_NONE); - b->connect("pressed", callable_mp(this, &AnimationTreeEditor::_path_button_pressed), varray(-1)); + b->connect("pressed", callable_mp(this, &AnimationTreeEditor::_path_button_pressed).bind(-1)); path_hb->add_child(b); for (int i = 0; i < button_path.size(); i++) { b = memnew(Button); @@ -96,7 +96,7 @@ void AnimationTreeEditor::_update_path() { path_hb->add_child(b); b->set_pressed(true); b->set_focus_mode(FOCUS_NONE); - b->connect("pressed", callable_mp(this, &AnimationTreeEditor::_path_button_pressed), varray(i)); + b->connect("pressed", callable_mp(this, &AnimationTreeEditor::_path_button_pressed).bind(i)); } } diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h index ab4ef5a001..a33d97f62f 100644 --- a/editor/plugins/animation_tree_editor_plugin.h +++ b/editor/plugins/animation_tree_editor_plugin.h @@ -32,7 +32,6 @@ #define ANIMATION_TREE_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" -#include "editor/property_editor.h" #include "scene/animation/animation_tree.h" #include "scene/gui/button.h" #include "scene/gui/graph_edit.h" diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index bb393c652d..8ee162d085 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -253,7 +253,7 @@ void EditorAssetLibraryItemDescription::add_preview(int p_id, bool p_video, cons preview.button = memnew(Button); preview.button->set_icon(previews->get_theme_icon(SNAME("ThumbnailWait"), SNAME("EditorIcons"))); preview.button->set_toggle_mode(true); - preview.button->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDescription::_preview_click), varray(p_id)); + preview.button->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDescription::_preview_click).bind(p_id)); preview_hb->add_child(preview.button); if (!p_video) { preview.image = previews->get_theme_icon(SNAME("ThumbnailWait"), SNAME("EditorIcons")); @@ -887,7 +887,7 @@ void EditorAssetLibrary::_request_image(ObjectID p_for, String p_image_url, Imag iq.queue_id = ++last_queue_id; iq.active = false; - iq.request->connect("request_completed", callable_mp(this, &EditorAssetLibrary::_image_request_completed), varray(iq.queue_id)); + iq.request->connect("request_completed", callable_mp(this, &EditorAssetLibrary::_image_request_completed).bind(iq.queue_id)); image_queue[iq.queue_id] = iq; @@ -1006,7 +1006,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int Button *first = memnew(Button); first->set_text(TTR("First", "Pagination")); if (p_page != 0) { - first->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(0)); + first->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search).bind(0)); } else { first->set_disabled(true); first->set_focus_mode(Control::FOCUS_NONE); @@ -1016,7 +1016,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int Button *prev = memnew(Button); prev->set_text(TTR("Previous", "Pagination")); if (p_page > 0) { - prev->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(p_page - 1)); + prev->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search).bind(p_page - 1)); } else { prev->set_disabled(true); prev->set_focus_mode(Control::FOCUS_NONE); @@ -1037,7 +1037,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int Button *current = memnew(Button); // Add padding to make page number buttons easier to click. current->set_text(vformat(" %d ", i + 1)); - current->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(i)); + current->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search).bind(i)); hbc->add_child(current); } @@ -1046,7 +1046,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int Button *next = memnew(Button); next->set_text(TTR("Next", "Pagination")); if (p_page < p_page_count - 1) { - next->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(p_page + 1)); + next->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search).bind(p_page + 1)); } else { next->set_disabled(true); next->set_focus_mode(Control::FOCUS_NONE); @@ -1057,7 +1057,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int Button *last = memnew(Button); last->set_text(TTR("Last", "Pagination")); if (p_page != p_page_count - 1) { - last->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(p_page_count - 1)); + last->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search).bind(p_page_count - 1)); } else { last->set_disabled(true); last->set_focus_mode(Control::FOCUS_NONE); diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp index 967a95be9d..70775c1ee2 100644 --- a/editor/plugins/bone_map_editor_plugin.cpp +++ b/editor/plugins/bone_map_editor_plugin.cpp @@ -33,6 +33,7 @@ #include "editor/editor_scale.h" #include "editor/import/post_import_plugin_skeleton_renamer.h" #include "editor/import/post_import_plugin_skeleton_rest_fixer.h" +#include "editor/import/post_import_plugin_skeleton_track_organizer.h" #include "editor/import/scene_import_settings.h" void BoneMapperButton::fetch_textures() { @@ -64,6 +65,9 @@ void BoneMapperButton::set_state(BoneMapState p_state) { case BONE_MAP_STATE_SET: { circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/set")); } break; + case BONE_MAP_STATE_MISSING: { + circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/missing")); + } break; case BONE_MAP_STATE_ERROR: { circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/error")); } break; @@ -258,7 +262,7 @@ void BoneMapper::recreate_editor() { for (int i = 0; i < len; i++) { if (profile->get_group(i) == profile->get_group_name(current_group_idx)) { BoneMapperButton *mb = memnew(BoneMapperButton(profile->get_bone_name(i), profile->is_require(i), current_bone_idx == i)); - mb->connect("pressed", callable_mp(this, &BoneMapper::set_current_bone_idx), varray(i), CONNECT_DEFERRED); + mb->connect("pressed", callable_mp(this, &BoneMapper::set_current_bone_idx).bind(i), CONNECT_DEFERRED); mb->set_h_grow_direction(GROW_DIRECTION_BOTH); mb->set_v_grow_direction(GROW_DIRECTION_BOTH); Vector2 vc = profile->get_handle_offset(i); @@ -310,16 +314,48 @@ void BoneMapper::recreate_items() { void BoneMapper::_update_state() { int len = bone_mapper_buttons.size(); for (int i = 0; i < len; i++) { - StringName sbn = bone_map->get_skeleton_bone_name(bone_mapper_buttons[i]->get_profile_bone_name()); - if (skeleton->find_bone(sbn) >= 0) { + StringName pbn = bone_mapper_buttons[i]->get_profile_bone_name(); + StringName sbn = bone_map->get_skeleton_bone_name(pbn); + int bone_idx = skeleton->find_bone(sbn); + if (bone_idx >= 0) { if (bone_map->get_skeleton_bone_name_count(sbn) == 1) { - bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_SET); + Ref<SkeletonProfile> prof = bone_map->get_profile(); + + StringName parent_name = prof->get_bone_parent(prof->find_bone(pbn)); + Vector<int> prof_parent_bones; + while (parent_name != StringName()) { + prof_parent_bones.push_back(skeleton->find_bone(bone_map->get_skeleton_bone_name(parent_name))); + if (prof->find_bone(parent_name) == -1) { + break; + } + parent_name = prof->get_bone_parent(prof->find_bone(parent_name)); + } + + int parent_id = skeleton->get_bone_parent(bone_idx); + Vector<int> skel_parent_bones; + while (parent_id >= 0) { + skel_parent_bones.push_back(parent_id); + parent_id = skeleton->get_bone_parent(parent_id); + } + + bool is_broken = false; + for (int j = 0; j < prof_parent_bones.size(); j++) { + if (prof_parent_bones[j] != -1 && !skel_parent_bones.has(prof_parent_bones[j])) { + is_broken = true; + } + } + + if (is_broken) { + bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_ERROR); + } else { + bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_SET); + } } else { bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_ERROR); } } else { if (bone_mapper_buttons[i]->is_require()) { - bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_ERROR); + bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_MISSING); } else { bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_UNSET); } @@ -379,11 +415,15 @@ void BoneMapEditor::create_editors() { } void BoneMapEditor::fetch_objects() { + skeleton = nullptr; // Hackey... but it may be the easist way to get a selected object from "ImporterScene". SceneImportSettings *si = SceneImportSettings::get_singleton(); if (!si) { return; } + if (!si->is_visible()) { + return; + } Node *selected = si->get_selected_node(); if (selected) { Skeleton3D *sk = Object::cast_to<Skeleton3D>(selected); @@ -404,11 +444,11 @@ void BoneMapEditor::_notification(int p_what) { create_editors(); } break; case NOTIFICATION_EXIT_TREE: { - if (!bone_mapper) { - return; + if (bone_mapper) { + remove_child(bone_mapper); + bone_mapper->queue_delete(); } - remove_child(bone_mapper); - bone_mapper->queue_delete(); + skeleton = nullptr; } break; } } @@ -436,14 +476,19 @@ void EditorInspectorPluginBoneMap::parse_begin(Object *p_object) { BoneMapEditorPlugin::BoneMapEditorPlugin() { // Register properties in editor settings. + EDITOR_DEF("editors/bone_mapper/handle_colors/unset", Color(0.3, 0.3, 0.3)); EDITOR_DEF("editors/bone_mapper/handle_colors/set", Color(0.1, 0.6, 0.25)); + EDITOR_DEF("editors/bone_mapper/handle_colors/missing", Color(0.8, 0.2, 0.8)); EDITOR_DEF("editors/bone_mapper/handle_colors/error", Color(0.8, 0.2, 0.2)); - EDITOR_DEF("editors/bone_mapper/handle_colors/unset", Color(0.3, 0.3, 0.3)); Ref<EditorInspectorPluginBoneMap> inspector_plugin; inspector_plugin.instantiate(); add_inspector_plugin(inspector_plugin); + Ref<PostImportPluginSkeletonTrackOrganizer> post_import_plugin_track_organizer; + post_import_plugin_track_organizer.instantiate(); + add_scene_post_import_plugin(post_import_plugin_track_organizer); + Ref<PostImportPluginSkeletonRenamer> post_import_plugin_renamer; post_import_plugin_renamer.instantiate(); add_scene_post_import_plugin(post_import_plugin_renamer); diff --git a/editor/plugins/bone_map_editor_plugin.h b/editor/plugins/bone_map_editor_plugin.h index 79fb47505b..339547ea10 100644 --- a/editor/plugins/bone_map_editor_plugin.h +++ b/editor/plugins/bone_map_editor_plugin.h @@ -47,6 +47,7 @@ public: enum BoneMapState { BONE_MAP_STATE_UNSET, BONE_MAP_STATE_SET, + BONE_MAP_STATE_MISSING, BONE_MAP_STATE_ERROR }; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 82772178e0..ac85eb5e1b 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -53,6 +53,7 @@ #include "scene/gui/flow_container.h" #include "scene/gui/grid_container.h" #include "scene/gui/nine_patch_rect.h" +#include "scene/gui/separator.h" #include "scene/gui/subviewport_container.h" #include "scene/gui/view_panner.h" #include "scene/main/canvas_layer.h" @@ -2793,10 +2794,10 @@ void CanvasItemEditor::_draw_rulers() { if (grid_snap_active || _is_grid_visible()) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (snap_relative && selection.size() > 0) { - ruler_transform.translate(_get_encompassing_rect_from_list(selection).position); + ruler_transform.translate_local(_get_encompassing_rect_from_list(selection).position); ruler_transform.scale_basis(grid_step * Math::pow(2.0, grid_step_multiplier)); } else { - ruler_transform.translate(grid_offset); + ruler_transform.translate_local(grid_offset); ruler_transform.scale_basis(grid_step * Math::pow(2.0, grid_step_multiplier)); } while ((transform * ruler_transform).get_scale().x < 50 || (transform * ruler_transform).get_scale().y < 50) { @@ -4236,13 +4237,13 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, Control *ctrl = Object::cast_to<Control>(canvas_item); if (key_pos) { - te->insert_node_value_key(ctrl, "rect_position", ctrl->get_position(), p_on_existing); + te->insert_node_value_key(ctrl, "position", ctrl->get_position(), p_on_existing); } if (key_rot) { - te->insert_node_value_key(ctrl, "rect_rotation", ctrl->get_rotation(), p_on_existing); + te->insert_node_value_key(ctrl, "rotation", ctrl->get_rotation(), p_on_existing); } if (key_scale) { - te->insert_node_value_key(ctrl, "rect_size", ctrl->get_size(), p_on_existing); + te->insert_node_value_key(ctrl, "size", ctrl->get_size(), p_on_existing); } } } @@ -4977,8 +4978,8 @@ CanvasItemEditor::CanvasItemEditor() { SceneTreeDock::get_singleton()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created)); SceneTreeDock::get_singleton()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position)); - EditorNode::get_singleton()->call_deferred(SNAME("connect"), "play_pressed", Callable(this, "_update_override_camera_button"), make_binds(true)); - EditorNode::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", Callable(this, "_update_override_camera_button"), make_binds(false)); + EditorNode::get_singleton()->call_deferred(SNAME("connect"), "play_pressed", Callable(this, "_update_override_camera_button").bind(true)); + EditorNode::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", Callable(this, "_update_override_camera_button").bind(false)); // A fluid container for all toolbars. HFlowContainer *main_flow = memnew(HFlowContainer); @@ -5072,7 +5073,7 @@ CanvasItemEditor::CanvasItemEditor() { select_button->set_flat(true); main_menu_hbox->add_child(select_button); select_button->set_toggle_mode(true); - select_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_SELECT)); + select_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_SELECT)); select_button->set_pressed(true); select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), Key::Q)); select_button->set_shortcut_context(this); @@ -5084,7 +5085,7 @@ CanvasItemEditor::CanvasItemEditor() { move_button->set_flat(true); main_menu_hbox->add_child(move_button); move_button->set_toggle_mode(true); - move_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_MOVE)); + move_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_MOVE)); move_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/move_mode", TTR("Move Mode"), Key::W)); move_button->set_shortcut_context(this); move_button->set_tooltip(TTR("Move Mode")); @@ -5093,7 +5094,7 @@ CanvasItemEditor::CanvasItemEditor() { rotate_button->set_flat(true); main_menu_hbox->add_child(rotate_button); rotate_button->set_toggle_mode(true); - rotate_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_ROTATE)); + rotate_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_ROTATE)); rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode", TTR("Rotate Mode"), Key::E)); rotate_button->set_shortcut_context(this); rotate_button->set_tooltip(TTR("Rotate Mode")); @@ -5102,7 +5103,7 @@ CanvasItemEditor::CanvasItemEditor() { scale_button->set_flat(true); main_menu_hbox->add_child(scale_button); scale_button->set_toggle_mode(true); - scale_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_SCALE)); + scale_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_SCALE)); scale_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/scale_mode", TTR("Scale Mode"), Key::S)); scale_button->set_shortcut_context(this); scale_button->set_tooltip(TTR("Shift: Scale proportionally.")); @@ -5113,21 +5114,21 @@ CanvasItemEditor::CanvasItemEditor() { list_select_button->set_flat(true); main_menu_hbox->add_child(list_select_button); list_select_button->set_toggle_mode(true); - list_select_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_LIST_SELECT)); + list_select_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_LIST_SELECT)); list_select_button->set_tooltip(TTR("Show list of selectable nodes at position clicked.")); pivot_button = memnew(Button); pivot_button->set_flat(true); main_menu_hbox->add_child(pivot_button); pivot_button->set_toggle_mode(true); - pivot_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_EDIT_PIVOT)); + pivot_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_EDIT_PIVOT)); pivot_button->set_tooltip(TTR("Click to change object's rotation pivot.")); pan_button = memnew(Button); pan_button->set_flat(true); main_menu_hbox->add_child(pan_button); pan_button->set_toggle_mode(true); - pan_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_PAN)); + pan_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_PAN)); pan_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/pan_mode", TTR("Pan Mode"), Key::G)); pan_button->set_shortcut_context(this); pan_button->set_tooltip(TTR("You can also use Pan View shortcut (Space by default) to pan in any mode.")); @@ -5136,7 +5137,7 @@ CanvasItemEditor::CanvasItemEditor() { ruler_button->set_flat(true); main_menu_hbox->add_child(ruler_button); ruler_button->set_toggle_mode(true); - ruler_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_RULER)); + ruler_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_RULER)); ruler_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/ruler_mode", TTR("Ruler Mode"), Key::R)); ruler_button->set_shortcut_context(this); ruler_button->set_tooltip(TTR("Ruler Mode")); @@ -5198,7 +5199,7 @@ CanvasItemEditor::CanvasItemEditor() { lock_button->set_flat(true); main_menu_hbox->add_child(lock_button); - lock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(LOCK_SELECTED)); + lock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(LOCK_SELECTED)); lock_button->set_tooltip(TTR("Lock selected node, preventing selection and movement.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. lock_button->set_shortcut(ED_SHORTCUT("editor/lock_selected_nodes", TTR("Lock Selected Node(s)"), KeyModifierMask::CMD | Key::L)); @@ -5206,7 +5207,7 @@ CanvasItemEditor::CanvasItemEditor() { unlock_button = memnew(Button); unlock_button->set_flat(true); main_menu_hbox->add_child(unlock_button); - unlock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(UNLOCK_SELECTED)); + unlock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(UNLOCK_SELECTED)); unlock_button->set_tooltip(TTR("Unlock selected node, allowing selection and movement.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. unlock_button->set_shortcut(ED_SHORTCUT("editor/unlock_selected_nodes", TTR("Unlock Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::L)); @@ -5214,16 +5215,16 @@ CanvasItemEditor::CanvasItemEditor() { group_button = memnew(Button); group_button->set_flat(true); main_menu_hbox->add_child(group_button); - group_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(GROUP_SELECTED)); - group_button->set_tooltip(TTR("Makes sure the object's children are not selectable.")); + group_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(GROUP_SELECTED)); + group_button->set_tooltip(TTR("Make selected node's children not selectable.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. group_button->set_shortcut(ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD | Key::G)); ungroup_button = memnew(Button); ungroup_button->set_flat(true); main_menu_hbox->add_child(ungroup_button); - ungroup_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(UNGROUP_SELECTED)); - ungroup_button->set_tooltip(TTR("Restores the object's children's ability to be selected.")); + ungroup_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(UNGROUP_SELECTED)); + ungroup_button->set_tooltip(TTR("Make selected node's children selectable.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. ungroup_button->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G)); @@ -5311,7 +5312,7 @@ CanvasItemEditor::CanvasItemEditor() { key_loc_button->set_toggle_mode(true); key_loc_button->set_pressed(true); key_loc_button->set_focus_mode(FOCUS_NONE); - key_loc_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(ANIM_INSERT_POS)); + key_loc_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(ANIM_INSERT_POS)); key_loc_button->set_tooltip(TTR("Translation mask for inserting keys.")); animation_hb->add_child(key_loc_button); @@ -5320,7 +5321,7 @@ CanvasItemEditor::CanvasItemEditor() { key_rot_button->set_toggle_mode(true); key_rot_button->set_pressed(true); key_rot_button->set_focus_mode(FOCUS_NONE); - key_rot_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(ANIM_INSERT_ROT)); + key_rot_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(ANIM_INSERT_ROT)); key_rot_button->set_tooltip(TTR("Rotation mask for inserting keys.")); animation_hb->add_child(key_rot_button); @@ -5328,14 +5329,14 @@ CanvasItemEditor::CanvasItemEditor() { key_scale_button->set_flat(true); key_scale_button->set_toggle_mode(true); key_scale_button->set_focus_mode(FOCUS_NONE); - key_scale_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(ANIM_INSERT_SCALE)); + key_scale_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(ANIM_INSERT_SCALE)); key_scale_button->set_tooltip(TTR("Scale mask for inserting keys.")); animation_hb->add_child(key_scale_button); key_insert_button = memnew(Button); key_insert_button->set_flat(true); key_insert_button->set_focus_mode(FOCUS_NONE); - key_insert_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(ANIM_INSERT_KEY)); + key_insert_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(ANIM_INSERT_KEY)); key_insert_button->set_tooltip(TTR("Insert keys (based on mask).")); key_insert_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/anim_insert_key", TTR("Insert Key"), Key::INSERT)); key_insert_button->set_shortcut_context(this); @@ -5376,7 +5377,7 @@ CanvasItemEditor::CanvasItemEditor() { add_child(selection_menu); selection_menu->set_min_size(Vector2(100, 0)); selection_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_selection_result_pressed)); - selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide), varray(), CONNECT_DEFERRED); + selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide), CONNECT_DEFERRED); add_node_menu = memnew(PopupMenu); add_child(add_node_menu); @@ -5915,7 +5916,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(CanvasItemEditor *p_canvas_it CheckBox *check = memnew(CheckBox); btn_group->add_child(check); check->set_text(texture_node_types[i]); - check->connect("button_down", callable_mp(this, &CanvasItemEditorViewport::_on_select_type), varray(check)); + check->connect("button_down", callable_mp(this, &CanvasItemEditorViewport::_on_select_type).bind(check)); check->set_button_group(button_group); } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 5b368de3cc..04fd819dec 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -214,8 +214,8 @@ private: int primary_grid_steps = 8; int grid_step_multiplier = 0; - real_t snap_rotation_step = 0.0; - real_t snap_rotation_offset = Math::deg2rad(15.0); + real_t snap_rotation_step = Math::deg2rad(15.0); + real_t snap_rotation_offset = 0.0; real_t snap_scale_step = 0.1f; bool smart_snap_active = false; bool grid_snap_active = false; diff --git a/editor/plugins/ray_cast_2d_editor_plugin.cpp b/editor/plugins/cast_2d_editor_plugin.cpp index 6f247a37ef..18c38e7ab8 100644 --- a/editor/plugins/ray_cast_2d_editor_plugin.cpp +++ b/editor/plugins/cast_2d_editor_plugin.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* ray_cast_2d_editor_plugin.cpp */ +/* cast_2d_editor_plugin.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,30 +28,32 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "ray_cast_2d_editor_plugin.h" +#include "cast_2d_editor_plugin.h" #include "canvas_item_editor_plugin.h" #include "editor/editor_node.h" +#include "scene/2d/ray_cast_2d.h" +#include "scene/2d/shape_cast_2d.h" -void RayCast2DEditor::_notification(int p_what) { +void Cast2DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - get_tree()->connect("node_removed", callable_mp(this, &RayCast2DEditor::_node_removed)); + get_tree()->connect("node_removed", callable_mp(this, &Cast2DEditor::_node_removed)); } break; case NOTIFICATION_EXIT_TREE: { - get_tree()->disconnect("node_removed", callable_mp(this, &RayCast2DEditor::_node_removed)); + get_tree()->disconnect("node_removed", callable_mp(this, &Cast2DEditor::_node_removed)); } break; } } -void RayCast2DEditor::_node_removed(Node *p_node) { +void Cast2DEditor::_node_removed(Node *p_node) { if (p_node == node) { node = nullptr; } } -bool RayCast2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { +bool Cast2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { if (!node || !node->is_visible_in_tree()) { return false; } @@ -60,10 +62,12 @@ bool RayCast2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) { + Vector2 target_position = node->get("target_position"); + if (mb->is_pressed()) { - if (xform.xform(node->get_target_position()).distance_to(mb->get_position()) < 8) { + if (xform.xform(target_position).distance_to(mb->get_position()) < 8) { pressed = true; - original_target_position = node->get_target_position(); + original_target_position = target_position; return true; } else { @@ -73,9 +77,9 @@ bool RayCast2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { } } else if (pressed) { undo_redo->create_action(TTR("Set target_position")); - undo_redo->add_do_method(node, "set_target_position", node->get_target_position()); + undo_redo->add_do_property(node, "target_position", target_position); undo_redo->add_do_method(canvas_item_editor, "update_viewport"); - undo_redo->add_undo_method(node, "set_target_position", original_target_position); + undo_redo->add_undo_property(node, "target_position", original_target_position); undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); undo_redo->commit_action(); @@ -90,7 +94,7 @@ bool RayCast2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { Vector2 point = canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position())); point = node->get_global_transform().affine_inverse().xform(point); - node->set_target_position(point); + node->set("target_position", point); canvas_item_editor->update_viewport(); node->notify_property_list_changed(); @@ -100,7 +104,7 @@ bool RayCast2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return false; } -void RayCast2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { +void Cast2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { if (!node || !node->is_visible_in_tree()) { return; } @@ -108,16 +112,16 @@ void RayCast2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { Transform2D gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); const Ref<Texture2D> handle = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons")); - p_overlay->draw_texture(handle, gt.xform(node->get_target_position()) - handle->get_size() / 2); + p_overlay->draw_texture(handle, gt.xform((Vector2)node->get("target_position")) - handle->get_size() / 2); } -void RayCast2DEditor::edit(Node *p_node) { +void Cast2DEditor::edit(Node2D *p_node) { if (!canvas_item_editor) { canvas_item_editor = CanvasItemEditor::get_singleton(); } - if (p_node) { - node = Object::cast_to<RayCast2D>(p_node); + if (Object::cast_to<RayCast2D>(p_node) || Object::cast_to<ShapeCast2D>(p_node)) { + node = p_node; } else { node = nullptr; } @@ -125,27 +129,27 @@ void RayCast2DEditor::edit(Node *p_node) { canvas_item_editor->update_viewport(); } -RayCast2DEditor::RayCast2DEditor() { +Cast2DEditor::Cast2DEditor() { undo_redo = EditorNode::get_singleton()->get_undo_redo(); } /////////////////////// -void RayCast2DEditorPlugin::edit(Object *p_object) { - ray_cast_2d_editor->edit(Object::cast_to<RayCast2D>(p_object)); +void Cast2DEditorPlugin::edit(Object *p_object) { + cast_2d_editor->edit(Object::cast_to<Node2D>(p_object)); } -bool RayCast2DEditorPlugin::handles(Object *p_object) const { - return Object::cast_to<RayCast2D>(p_object) != nullptr; +bool Cast2DEditorPlugin::handles(Object *p_object) const { + return Object::cast_to<RayCast2D>(p_object) != nullptr || Object::cast_to<ShapeCast2D>(p_object) != nullptr; } -void RayCast2DEditorPlugin::make_visible(bool p_visible) { +void Cast2DEditorPlugin::make_visible(bool p_visible) { if (!p_visible) { edit(nullptr); } } -RayCast2DEditorPlugin::RayCast2DEditorPlugin() { - ray_cast_2d_editor = memnew(RayCast2DEditor); - EditorNode::get_singleton()->get_gui_base()->add_child(ray_cast_2d_editor); +Cast2DEditorPlugin::Cast2DEditorPlugin() { + cast_2d_editor = memnew(Cast2DEditor); + EditorNode::get_singleton()->get_gui_base()->add_child(cast_2d_editor); } diff --git a/editor/plugins/ray_cast_2d_editor_plugin.h b/editor/plugins/cast_2d_editor_plugin.h index 74628da0e4..d9c0cc4a06 100644 --- a/editor/plugins/ray_cast_2d_editor_plugin.h +++ b/editor/plugins/cast_2d_editor_plugin.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* ray_cast_2d_editor_plugin.h */ +/* cast_2d_editor_plugin.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,20 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RAY_CAST_2D_EDITOR_PLUGIN_H -#define RAY_CAST_2D_EDITOR_PLUGIN_H +#ifndef CAST_2D_EDITOR_PLUGIN_H +#define CAST_2D_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" -#include "scene/2d/ray_cast_2d.h" +#include "scene/2d/node_2d.h" class CanvasItemEditor; -class RayCast2DEditor : public Control { - GDCLASS(RayCast2DEditor, Control); +class Cast2DEditor : public Control { + GDCLASS(Cast2DEditor, Control); UndoRedo *undo_redo = nullptr; CanvasItemEditor *canvas_item_editor = nullptr; - RayCast2D *node; + Node2D *node; bool pressed = false; Point2 original_target_position; @@ -53,27 +53,27 @@ protected: public: bool forward_canvas_gui_input(const Ref<InputEvent> &p_event); void forward_canvas_draw_over_viewport(Control *p_overlay); - void edit(Node *p_node); + void edit(Node2D *p_node); - RayCast2DEditor(); + Cast2DEditor(); }; -class RayCast2DEditorPlugin : public EditorPlugin { - GDCLASS(RayCast2DEditorPlugin, EditorPlugin); +class Cast2DEditorPlugin : public EditorPlugin { + GDCLASS(Cast2DEditorPlugin, EditorPlugin); - RayCast2DEditor *ray_cast_2d_editor = nullptr; + Cast2DEditor *cast_2d_editor = nullptr; public: - virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) override { return ray_cast_2d_editor->forward_canvas_gui_input(p_event); } - virtual void forward_canvas_draw_over_viewport(Control *p_overlay) override { ray_cast_2d_editor->forward_canvas_draw_over_viewport(p_overlay); } + virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) override { return cast_2d_editor->forward_canvas_gui_input(p_event); } + virtual void forward_canvas_draw_over_viewport(Control *p_overlay) override { cast_2d_editor->forward_canvas_draw_over_viewport(p_overlay); } - virtual String get_name() const override { return "RayCast2D"; } + virtual String get_name() const override { return "Cast2D"; } bool has_main_screen() const override { return false; } virtual void edit(Object *p_object) override; virtual bool handles(Object *p_object) const override; virtual void make_visible(bool visible) override; - RayCast2DEditorPlugin(); + Cast2DEditorPlugin(); }; -#endif // RAY_CAST_2D_EDITOR_PLUGIN_H +#endif // CAST_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp index ec038174fc..2756e45cf4 100644 --- a/editor/plugins/control_editor_plugin.cpp +++ b/editor/plugins/control_editor_plugin.cpp @@ -31,7 +31,9 @@ #include "control_editor_plugin.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" #include "editor/plugins/canvas_item_editor_plugin.h" +#include "scene/gui/separator.h" void ControlPositioningWarning::_update_warning() { if (!control_node) { diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 66e58339ed..8aeab684e3 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -36,6 +36,7 @@ #include "core/os/keyboard.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" CurveEditor::CurveEditor() { _selected_point = -1; @@ -542,11 +543,11 @@ void CurveEditor::update_view_transform() { const Vector2 scale = view_size / world_rect.size; Transform2D world_trans; - world_trans.translate(-world_rect.position - Vector2(0, world_rect.size.y)); + world_trans.translate_local(-world_rect.position - Vector2(0, world_rect.size.y)); world_trans.scale(Vector2(scale.x, -scale.y)); Transform2D view_trans; - view_trans.translate(view_margin); + view_trans.translate_local(view_margin); _world_to_view = view_trans * world_trans; } diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp index 5c90d70982..c572b5b7fe 100644 --- a/editor/plugins/debugger_editor_plugin.cpp +++ b/editor/plugins/debugger_editor_plugin.cpp @@ -35,6 +35,7 @@ #include "editor/debugger/editor_debugger_server.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/fileserver/editor_file_server.h" #include "editor/plugins/script_editor_plugin.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 6b632101d3..0196214ceb 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -307,7 +307,7 @@ Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const Ref<Resource> &p_from if (material->get_shader_mode() == Shader::MODE_SPATIAL) { RS::get_singleton()->mesh_surface_set_material(sphere, 0, material->get_rid()); - RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorMaterialPreviewPlugin *>(this), &EditorMaterialPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT); + RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorMaterialPreviewPlugin *>(this), &EditorMaterialPreviewPlugin::_generate_frame_started), Object::CONNECT_ONESHOT); preview_done.wait(); @@ -702,7 +702,7 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const Ref<Resource> &p_from, co xform.origin.z -= rot_aabb.size.z * 2; RS::get_singleton()->instance_set_transform(mesh_instance, xform); - RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorMeshPreviewPlugin *>(this), &EditorMeshPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT); + RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorMeshPreviewPlugin *>(this), &EditorMeshPreviewPlugin::_generate_frame_started), Object::CONNECT_ONESHOT); preview_done.wait(); @@ -812,7 +812,7 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const float fg = c.get_luminance() < 0.5 ? 1.0 : 0.0; sampled_font->draw_string(canvas_item, pos, sample, HORIZONTAL_ALIGNMENT_LEFT, -1.f, 50, Color(fg, fg, fg)); - RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorFontPreviewPlugin *>(this), &EditorFontPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT); + RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorFontPreviewPlugin *>(this), &EditorFontPreviewPlugin::_generate_frame_started), Object::CONNECT_ONESHOT); preview_done.wait(); diff --git a/modules/websocket/emws_server.cpp b/editor/plugins/editor_resource_conversion_plugin.cpp index 2033098cad..91394dbac7 100644 --- a/modules/websocket/emws_server.cpp +++ b/editor/plugins/editor_resource_conversion_plugin.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* emws_server.cpp */ +/* editor_resource_conversion_plugin.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,65 +28,37 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef JAVASCRIPT_ENABLED +#include "editor_resource_conversion_plugin.h" -#include "emws_server.h" -#include "core/os/os.h" - -void EMWSServer::set_extra_headers(const Vector<String> &p_headers) { +void EditorResourceConversionPlugin::_bind_methods() { + GDVIRTUAL_BIND(_converts_to); + GDVIRTUAL_BIND(_handles, "resource"); + GDVIRTUAL_BIND(_convert, "resource"); } -Error EMWSServer::listen(int p_port, Vector<String> p_protocols, bool gd_mp_api) { - return FAILED; -} +String EditorResourceConversionPlugin::converts_to() const { + String ret; + if (GDVIRTUAL_CALL(_converts_to, ret)) { + return ret; + } -bool EMWSServer::is_listening() const { - return false; + return ""; } -void EMWSServer::stop() { -} +bool EditorResourceConversionPlugin::handles(const Ref<Resource> &p_resource) const { + bool ret; + if (GDVIRTUAL_CALL(_handles, p_resource, ret)) { + return ret; + } -bool EMWSServer::has_peer(int p_id) const { return false; } -Ref<WebSocketPeer> EMWSServer::get_peer(int p_id) const { - return nullptr; -} - -Vector<String> EMWSServer::get_protocols() const { - Vector<String> out; - - return out; -} - -IPAddress EMWSServer::get_peer_address(int p_peer_id) const { - return IPAddress(); -} - -int EMWSServer::get_peer_port(int p_peer_id) const { - return 0; -} +Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) const { + Ref<Resource> ret; + if (GDVIRTUAL_CALL(_convert, p_resource, ret)) { + return ret; + } -void EMWSServer::disconnect_peer(int p_peer_id, int p_code, String p_reason) { + return Ref<Resource>(); } - -void EMWSServer::poll() { -} - -int EMWSServer::get_max_packet_size() const { - return 0; -} - -Error EMWSServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) { - return OK; -} - -EMWSServer::EMWSServer() { -} - -EMWSServer::~EMWSServer() { -} - -#endif // JAVASCRIPT_ENABLED diff --git a/modules/websocket/emws_server.h b/editor/plugins/editor_resource_conversion_plugin.h index 14a9449605..34b0837383 100644 --- a/modules/websocket/emws_server.h +++ b/editor/plugins/editor_resource_conversion_plugin.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* emws_server.h */ +/* editor_resource_conversion_plugin.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,37 +28,27 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EMWS_SERVER_H -#define EMWS_SERVER_H +#ifndef EDITOR_RESOURCE_CONVERSION_PLUGIN_H +#define EDITOR_RESOURCE_CONVERSION_PLUGIN_H -#ifdef JAVASCRIPT_ENABLED +#include "core/io/resource.h" +#include "core/object/gdvirtual.gen.inc" +#include "core/object/script_language.h" -#include "core/object/ref_counted.h" -#include "emws_peer.h" -#include "websocket_server.h" +class EditorResourceConversionPlugin : public RefCounted { + GDCLASS(EditorResourceConversionPlugin, RefCounted); -class EMWSServer : public WebSocketServer { - GDCIIMPL(EMWSServer, WebSocketServer); +protected: + static void _bind_methods(); -public: - Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) override; - void set_extra_headers(const Vector<String> &p_headers) override; - Error listen(int p_port, Vector<String> p_protocols = Vector<String>(), bool gd_mp_api = false) override; - void stop() override; - bool is_listening() const override; - bool has_peer(int p_id) const override; - Ref<WebSocketPeer> get_peer(int p_id) const override; - IPAddress get_peer_address(int p_peer_id) const override; - int get_peer_port(int p_peer_id) const override; - void disconnect_peer(int p_peer_id, int p_code = 1000, String p_reason = "") override; - int get_max_packet_size() const override; - virtual void poll() override; - virtual Vector<String> get_protocols() const; + GDVIRTUAL0RC(String, _converts_to) + GDVIRTUAL1RC(bool, _handles, Ref<Resource>) + GDVIRTUAL1RC(Ref<Resource>, _convert, Ref<Resource>) - EMWSServer(); - ~EMWSServer(); +public: + virtual String converts_to() const; + virtual bool handles(const Ref<Resource> &p_resource) const; + virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const; }; -#endif - -#endif // EMWS_SERVER_H +#endif // EDITOR_RESOURCE_CONVERSION_PLUGIN_H diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp index 848fb5887d..cadb974345 100644 --- a/editor/plugins/font_config_plugin.cpp +++ b/editor/plugins/font_config_plugin.cpp @@ -307,7 +307,7 @@ void EditorPropertyFontMetaOverride::update_property() { Button *remove = memnew(Button); remove->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); hbox->add_child(remove); - remove->connect("pressed", callable_mp(this, &EditorPropertyFontMetaOverride::_remove), varray(remove, name)); + remove->connect("pressed", callable_mp(this, &EditorPropertyFontMetaOverride::_remove).bind(remove, name)); prop->update_property(); } @@ -783,7 +783,7 @@ void EditorPropertyOTFeatures::update_property() { Button *remove = memnew(Button); remove->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); hbox->add_child(remove); - remove->connect("pressed", callable_mp(this, &EditorPropertyOTFeatures::_remove), varray(remove, name_tag)); + remove->connect("pressed", callable_mp(this, &EditorPropertyOTFeatures::_remove).bind(remove, name_tag)); prop->update_property(); } @@ -895,17 +895,45 @@ void FontPreview::_notification(int p_what) { Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); Color text_color = get_theme_color(SNAME("font_color"), SNAME("Label")); - font->draw_string(get_canvas_item(), Point2(0, font->get_height(font_size) + 2 * EDSCALE), name, HORIZONTAL_ALIGNMENT_CENTER, get_size().x, font_size, text_color); // Draw font preview. - Vector2 pos = Vector2(0, font->get_height(font_size)) + (get_size() - Vector2(0, font->get_height(font_size)) - line->get_size()) / 2; - line->draw(get_canvas_item(), pos, text_color); - - // Draw font baseline. - Color line_color = text_color; - line_color.a *= 0.6; - draw_line(Vector2(0, pos.y + line->get_line_ascent()), Vector2(pos.x - 5, pos.y + line->get_line_ascent()), line_color); - draw_line(Vector2(pos.x + line->get_size().x + 5, pos.y + line->get_line_ascent()), Vector2(get_size().x, pos.y + line->get_line_ascent()), line_color); + bool prev_ok = true; + if (prev_font.is_valid()) { + if (prev_font->get_font_name().is_empty()) { + prev_ok = false; + } else { + String name; + if (prev_font->get_font_style_name().is_empty()) { + name = prev_font->get_font_name(); + } else { + name = vformat("%s (%s)", prev_font->get_font_name(), prev_font->get_font_style_name()); + } + if (prev_font->is_class("FontVariation")) { + name += " " + TTR(" - Variation"); + } + font->draw_string(get_canvas_item(), Point2(0, font->get_height(font_size) + 2 * EDSCALE), name, HORIZONTAL_ALIGNMENT_CENTER, get_size().x, font_size, text_color); + + String sample; + static const String sample_base = U"12漢字ԱբΑαАбΑαאבابܐܒހށआআਆઆଆஆఆಆആආกิກິༀကႠა한글ሀᎣᐁᚁᚠᜀᜠᝀᝠកᠠᤁᥐAb😀"; + for (int i = 0; i < sample_base.length(); i++) { + if (prev_font->has_char(sample_base[i])) { + sample += sample_base[i]; + } + } + if (sample.is_empty()) { + sample = prev_font->get_supported_chars().substr(0, 6); + } + if (sample.is_empty()) { + prev_ok = false; + } else { + prev_font->draw_string(get_canvas_item(), Point2(0, font->get_height(font_size) + prev_font->get_height(25 * EDSCALE)), sample, HORIZONTAL_ALIGNMENT_CENTER, get_size().x, 25 * EDSCALE, text_color); + } + } + } + if (!prev_ok) { + text_color.a *= 0.5; + font->draw_string(get_canvas_item(), Point2(0, font->get_height(font_size) + 2 * EDSCALE), TTR("Unable to preview font"), HORIZONTAL_ALIGNMENT_CENTER, get_size().x, font_size, text_color); + } } break; } } @@ -917,30 +945,11 @@ Size2 FontPreview::get_minimum_size() const { } void FontPreview::set_data(const Ref<Font> &p_f) { - line->clear(); - if (p_f.is_valid()) { - name = vformat("%s (%s)", p_f->get_font_name(), p_f->get_font_style_name()); - if (p_f->is_class("FontVariation")) { - name += " " + TTR(" - Variation"); - } - String sample; - static const String sample_base = U"12漢字ԱբΑαАбΑαאבابܐܒހށआআਆઆଆஆఆಆആආกิກິༀကႠა한글ሀᎣᐁᚁᚠᜀᜠᝀᝠកᠠᤁᥐAb😀"; - for (int i = 0; i < sample_base.length(); i++) { - if (p_f->has_char(sample_base[i])) { - sample += sample_base[i]; - } - } - if (sample.is_empty()) { - sample = p_f->get_supported_chars().substr(0, 6); - } - line->add_string(sample, p_f, 50); - } - + prev_font = p_f; update(); } FontPreview::FontPreview() { - line.instantiate(); } /*************************************************************************/ @@ -965,6 +974,71 @@ bool EditorInspectorPluginFontPreview::parse_property(Object *p_object, const Va } /*************************************************************************/ +/* EditorPropertyFontNamesArray */ +/*************************************************************************/ + +void EditorPropertyFontNamesArray::_add_element() { + Size2 size = get_size(); + menu->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y)); + menu->reset_size(); + menu->popup(); +} + +void EditorPropertyFontNamesArray::_add_font(int p_option) { + if (updating) { + return; + } + + Variant array = object->get_array(); + int previous_size = array.call("size"); + + array.call("resize", previous_size + 1); + array.set(previous_size, menu->get_item_text(p_option)); + + emit_changed(get_edited_property(), array, "", false); + object->set_array(array); + update_property(); +} + +EditorPropertyFontNamesArray::EditorPropertyFontNamesArray() { + menu = memnew(PopupMenu); + menu->add_item("Sans-Serif", 0); + menu->add_item("Serif", 1); + menu->add_item("Monospace", 2); + menu->add_item("Fantasy", 3); + menu->add_item("Cursive", 4); + + menu->add_separator(); + + if (OS::get_singleton()) { + Vector<String> fonts = OS::get_singleton()->get_system_fonts(); + for (int i = 0; i < fonts.size(); i++) { + menu->add_item(fonts[i], i + 6); + } + } + add_child(menu); + menu->connect("id_pressed", callable_mp(this, &EditorPropertyFontNamesArray::_add_font)); +} + +/*************************************************************************/ +/* EditorInspectorPluginSystemFont */ +/*************************************************************************/ + +bool EditorInspectorPluginSystemFont::can_handle(Object *p_object) { + return Object::cast_to<SystemFont>(p_object) != nullptr; +} + +bool EditorInspectorPluginSystemFont::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) { + if (p_path == "font_names") { + EditorPropertyFontNamesArray *editor = memnew(EditorPropertyFontNamesArray); + editor->setup(p_type, p_hint_text); + add_property_editor(p_path, editor); + return true; + } + return false; +} + +/*************************************************************************/ /* FontEditorPlugin */ /*************************************************************************/ @@ -973,6 +1047,10 @@ FontEditorPlugin::FontEditorPlugin() { fc_plugin.instantiate(); EditorInspector::add_inspector_plugin(fc_plugin); + Ref<EditorInspectorPluginSystemFont> fs_plugin; + fs_plugin.instantiate(); + EditorInspector::add_inspector_plugin(fs_plugin); + Ref<EditorInspectorPluginFontPreview> fp_plugin; fp_plugin.instantiate(); EditorInspector::add_inspector_plugin(fp_plugin); diff --git a/editor/plugins/font_config_plugin.h b/editor/plugins/font_config_plugin.h index 67c16bfe60..3eaa2fdc17 100644 --- a/editor/plugins/font_config_plugin.h +++ b/editor/plugins/font_config_plugin.h @@ -34,6 +34,7 @@ #include "core/io/marshalls.h" #include "editor/editor_plugin.h" #include "editor/editor_properties.h" +#include "editor/editor_properties_array_dict.h" /*************************************************************************/ @@ -225,8 +226,7 @@ protected: void _notification(int p_what); static void _bind_methods(); - String name; - Ref<TextLine> line; + Ref<Font> prev_font; public: virtual Size2 get_minimum_size() const override; @@ -249,6 +249,33 @@ public: /*************************************************************************/ +class EditorPropertyFontNamesArray : public EditorPropertyArray { + GDCLASS(EditorPropertyFontNamesArray, EditorPropertyArray); + + PopupMenu *menu = nullptr; + +protected: + virtual void _add_element() override; + + void _add_font(int p_option); + static void _bind_methods(){}; + +public: + EditorPropertyFontNamesArray(); +}; + +/*************************************************************************/ + +class EditorInspectorPluginSystemFont : public EditorInspectorPlugin { + GDCLASS(EditorInspectorPluginSystemFont, EditorInspectorPlugin); + +public: + virtual bool can_handle(Object *p_object) override; + virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false) override; +}; + +/*************************************************************************/ + class FontEditorPlugin : public EditorPlugin { GDCLASS(FontEditorPlugin, EditorPlugin); diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h index b91a17d9e5..b5eca46ad3 100644 --- a/editor/plugins/gdextension_export_plugin.h +++ b/editor/plugins/gdextension_export_plugin.h @@ -31,7 +31,7 @@ #ifndef GDEXTENSION_EXPORT_PLUGIN_H #define GDEXTENSION_EXPORT_PLUGIN_H -#include "editor/editor_export.h" +#include "editor/export/editor_export.h" class GDExtensionExportPlugin : public EditorExportPlugin { protected: diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp index 643a470425..b54cb515e4 100644 --- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp @@ -140,7 +140,7 @@ void GPUParticlesCollisionSDF3DEditorPlugin::_sdf_save_path_and_bake(const Strin if (col_sdf) { Ref<Image> bake_img = col_sdf->bake(); if (bake_img.is_null()) { - EditorNode::get_singleton()->show_warning(TTR("Bake Error.")); + EditorNode::get_singleton()->show_warning(TTR("No faces detected during GPUParticlesCollisionSDF3D bake.\nCheck whether there are visible meshes matching the bake mask within its extents.")); return; } diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp index 5c7047a81f..542aee879b 100644 --- a/editor/plugins/gradient_editor_plugin.cpp +++ b/editor/plugins/gradient_editor_plugin.cpp @@ -33,6 +33,7 @@ #include "canvas_item_editor_plugin.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "node_3d_editor_plugin.h" Size2 GradientEditor::get_minimum_size() const { @@ -85,7 +86,7 @@ void GradientEditor::reverse_gradient() { } GradientEditor::GradientEditor() { - GradientEdit::get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(GradientEdit::get_picker())); + GradientEdit::get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(GradientEdit::get_picker())); editing = false; } diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index e21cb7e76a..1b4d98fc3f 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -32,6 +32,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/gui/subviewport_container.h" #include "scene/resources/fog_material.h" #include "scene/resources/particles_material.h" @@ -201,13 +202,13 @@ MaterialEditor::MaterialEditor() { sphere_switch->set_toggle_mode(true); sphere_switch->set_pressed(true); vb_shape->add_child(sphere_switch); - sphere_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed), varray(sphere_switch)); + sphere_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed).bind(sphere_switch)); box_switch = memnew(TextureButton); box_switch->set_toggle_mode(true); box_switch->set_pressed(false); vb_shape->add_child(box_switch); - box_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed), varray(box_switch)); + box_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed).bind(box_switch)); layout_3d->add_spacer(); @@ -217,12 +218,12 @@ MaterialEditor::MaterialEditor() { light_1_switch = memnew(TextureButton); light_1_switch->set_toggle_mode(true); vb_light->add_child(light_1_switch); - light_1_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed), varray(light_1_switch)); + light_1_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed).bind(light_1_switch)); light_2_switch = memnew(TextureButton); light_2_switch->set_toggle_mode(true); vb_light->add_child(light_2_switch); - light_2_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed), varray(light_2_switch)); + light_2_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed).bind(light_2_switch)); first_enter = true; @@ -339,17 +340,17 @@ Ref<Resource> StandardMaterial3DConversionPlugin::convert(const Ref<Resource> &p smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { // Texture parameter has to be treated specially since StandardMaterial3D saved it // as RID but ShaderMaterial needs Texture itself Ref<Texture2D> texture = mat->get_texture_by_name(E.name); if (texture.is_valid()) { - smat->set_shader_param(E.name, texture); + smat->set_shader_uniform(E.name, texture); } else { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_param(E.name, value); + smat->set_shader_uniform(E.name, value); } } @@ -385,17 +386,17 @@ Ref<Resource> ORMMaterial3DConversionPlugin::convert(const Ref<Resource> &p_reso smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { // Texture parameter has to be treated specially since ORMMaterial3D saved it // as RID but ShaderMaterial needs Texture itself Ref<Texture2D> texture = mat->get_texture_by_name(E.name); if (texture.is_valid()) { - smat->set_shader_param(E.name, texture); + smat->set_shader_uniform(E.name, texture); } else { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_param(E.name, value); + smat->set_shader_uniform(E.name, value); } } @@ -431,11 +432,11 @@ Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_ smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_param(E.name, value); + smat->set_shader_uniform(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -470,11 +471,11 @@ Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_param(E.name, value); + smat->set_shader_uniform(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -509,11 +510,11 @@ Ref<Resource> ProceduralSkyMaterialConversionPlugin::convert(const Ref<Resource> smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_param(E.name, value); + smat->set_shader_uniform(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -548,11 +549,11 @@ Ref<Resource> PanoramaSkyMaterialConversionPlugin::convert(const Ref<Resource> & smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_param(E.name, value); + smat->set_shader_uniform(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -587,11 +588,11 @@ Ref<Resource> PhysicalSkyMaterialConversionPlugin::convert(const Ref<Resource> & smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_param(E.name, value); + smat->set_shader_uniform(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -626,11 +627,11 @@ Ref<Resource> FogMaterialConversionPlugin::convert(const Ref<Resource> &p_resour smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_param(E.name, value); + smat->set_shader_uniform(E.name, value); } smat->set_render_priority(mat->get_render_priority()); diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 9c6247d59b..fc3da5fd9f 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -32,7 +32,7 @@ #define MATERIAL_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" -#include "editor/property_editor.h" +#include "editor/plugins/editor_resource_conversion_plugin.h" #include "scene/3d/camera_3d.h" #include "scene/3d/light_3d.h" #include "scene/3d/mesh_instance_3d.h" diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index b23395fea2..31c9f1e387 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -147,12 +147,12 @@ MeshEditor::MeshEditor() { light_1_switch = memnew(TextureButton); light_1_switch->set_toggle_mode(true); vb_light->add_child(light_1_switch); - light_1_switch->connect("pressed", callable_mp(this, &MeshEditor::_button_pressed), varray(light_1_switch)); + light_1_switch->connect("pressed", callable_mp(this, &MeshEditor::_button_pressed).bind(light_1_switch)); light_2_switch = memnew(TextureButton); light_2_switch->set_toggle_mode(true); vb_light->add_child(light_2_switch); - light_2_switch->connect("pressed", callable_mp(this, &MeshEditor::_button_pressed), varray(light_2_switch)); + light_2_switch->connect("pressed", callable_mp(this, &MeshEditor::_button_pressed).bind(light_2_switch)); first_enter = true; diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index 72bfc05270..319f6ee9de 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -289,8 +289,8 @@ MeshLibraryEditor::MeshLibraryEditor() { cd_update = memnew(ConfirmationDialog); add_child(cd_update); cd_update->set_ok_button_text(TTR("Apply without Transforms")); - cd_update->get_ok_button()->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm), varray(false)); - cd_update->add_button(TTR("Apply with Transforms"))->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm), varray(true)); + cd_update->get_ok_button()->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm).bind(false)); + cd_update->add_button(TTR("Apply with Transforms"))->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm).bind(true)); } void MeshLibraryEditorPlugin::edit(Object *p_node) { diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index 7207390922..fc4dc5bc2f 100644 --- a/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp @@ -291,7 +291,7 @@ MultiMeshEditor::MultiMeshEditor() { Button *b = memnew(Button); hbc->add_child(b); b->set_text(".."); - b->connect("pressed", callable_mp(this, &MultiMeshEditor::_browse), make_binds(false)); + b->connect("pressed", callable_mp(this, &MultiMeshEditor::_browse).bind(false)); vbc->add_margin_child(TTR("Target Surface:"), hbc); @@ -303,7 +303,7 @@ MultiMeshEditor::MultiMeshEditor() { hbc->add_child(b); b->set_text(".."); vbc->add_margin_child(TTR("Source Mesh:"), hbc); - b->connect("pressed", callable_mp(this, &MultiMeshEditor::_browse), make_binds(true)); + b->connect("pressed", callable_mp(this, &MultiMeshEditor::_browse).bind(true)); populate_axis = memnew(OptionButton); populate_axis->add_item(TTR("X-Axis")); diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 77cf1f0064..0070226d40 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -57,6 +57,7 @@ #include "scene/3d/position_3d.h" #include "scene/3d/ray_cast_3d.h" #include "scene/3d/reflection_probe.h" +#include "scene/3d/shape_cast_3d.h" #include "scene/3d/soft_dynamic_body_3d.h" #include "scene/3d/spring_arm_3d.h" #include "scene/3d/sprite_3d.h" @@ -74,6 +75,7 @@ #include "scene/resources/sphere_shape_3d.h" #include "scene/resources/surface_tool.h" #include "scene/resources/world_boundary_shape_3d.h" +#include "servers/navigation_server_3d.h" #define HANDLE_HALF_SIZE 9.5 @@ -2540,6 +2542,44 @@ void RayCast3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { ///// +ShapeCast3DGizmoPlugin::ShapeCast3DGizmoPlugin() { + const Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape"); + create_material("shape_material", gizmo_color); + const float gizmo_value = gizmo_color.get_v(); + const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65); + create_material("shape_material_disabled", gizmo_color_disabled); +} + +bool ShapeCast3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<ShapeCast3D>(p_spatial) != nullptr; +} + +String ShapeCast3DGizmoPlugin::get_gizmo_name() const { + return "ShapeCast3D"; +} + +int ShapeCast3DGizmoPlugin::get_priority() const { + return -1; +} + +void ShapeCast3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + ShapeCast3D *shapecast = Object::cast_to<ShapeCast3D>(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); + + const Ref<StandardMaterial3D> material = shapecast->is_enabled() ? shapecast->get_debug_material() : get_material("shape_material_disabled"); + + p_gizmo->add_lines(shapecast->get_debug_line_vertices(), material); + + if (shapecast->get_shape().is_valid()) { + p_gizmo->add_lines(shapecast->get_debug_shape_vertices(), material); + } + + p_gizmo->add_collision_segments(shapecast->get_debug_line_vertices()); +} + +///// + void SpringArm3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { SpringArm3D *spring_arm = Object::cast_to<SpringArm3D>(p_gizmo->get_spatial_node()); @@ -4799,10 +4839,6 @@ void CollisionPolygon3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { //// NavigationRegion3DGizmoPlugin::NavigationRegion3DGizmoPlugin() { - create_material("navigation_edge_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge", Color(0.5, 1, 1))); - create_material("navigation_edge_material_disabled", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge_disabled", Color(0.7, 0.7, 0.7))); - create_material("navigation_solid_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid", Color(0.5, 1, 1, 0.4))); - create_material("navigation_solid_material_disabled", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid_disabled", Color(0.7, 0.7, 0.7, 0.4))); } bool NavigationRegion3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { @@ -4818,24 +4854,19 @@ int NavigationRegion3DGizmoPlugin::get_priority() const { } void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - NavigationRegion3D *navmesh = Object::cast_to<NavigationRegion3D>(p_gizmo->get_spatial_node()); - - Ref<Material> edge_material = get_material("navigation_edge_material", p_gizmo); - Ref<Material> edge_material_disabled = get_material("navigation_edge_material_disabled", p_gizmo); - Ref<Material> solid_material = get_material("navigation_solid_material", p_gizmo); - Ref<Material> solid_material_disabled = get_material("navigation_solid_material_disabled", p_gizmo); + NavigationRegion3D *navigationregion = Object::cast_to<NavigationRegion3D>(p_gizmo->get_spatial_node()); p_gizmo->clear(); - Ref<NavigationMesh> navmeshie = navmesh->get_navigation_mesh(); - if (navmeshie.is_null()) { + Ref<NavigationMesh> navigationmesh = navigationregion->get_navigation_mesh(); + if (navigationmesh.is_null()) { return; } - Vector<Vector3> vertices = navmeshie->get_vertices(); + Vector<Vector3> vertices = navigationmesh->get_vertices(); const Vector3 *vr = vertices.ptr(); List<Face3> faces; - for (int i = 0; i < navmeshie->get_polygon_count(); i++) { - Vector<int> p = navmeshie->get_polygon(i); + for (int i = 0; i < navigationmesh->get_polygon_count(); i++) { + Vector<int> p = navigationmesh->get_polygon(i); for (int j = 2; j < p.size(); j++) { Face3 f; @@ -4892,17 +4923,90 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Ref<TriangleMesh> tmesh = memnew(TriangleMesh); tmesh->create(tmeshfaces); - if (lines.size()) { - p_gizmo->add_lines(lines, navmesh->is_enabled() ? edge_material : edge_material_disabled); - } p_gizmo->add_collision_triangles(tmesh); - Ref<ArrayMesh> m = memnew(ArrayMesh); - Array a; - a.resize(Mesh::ARRAY_MAX); - a[0] = tmeshfaces; - m->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a); - m->surface_set_material(0, navmesh->is_enabled() ? solid_material : solid_material_disabled); - p_gizmo->add_mesh(m); + + Ref<ArrayMesh> debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + int polygon_count = navigationmesh->get_polygon_count(); + + // build geometry face surface + Vector<Vector3> face_vertex_array; + face_vertex_array.resize(polygon_count * 3); + + for (int i = 0; i < polygon_count; i++) { + Vector<int> polygon = navigationmesh->get_polygon(i); + + face_vertex_array.push_back(vertices[polygon[0]]); + face_vertex_array.push_back(vertices[polygon[1]]); + face_vertex_array.push_back(vertices[polygon[2]]); + } + + Array face_mesh_array; + face_mesh_array.resize(Mesh::ARRAY_MAX); + face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array; + + // if enabled add vertex colors to colorize each face individually + bool enabled_geometry_face_random_color = NavigationServer3D::get_singleton()->get_debug_navigation_enable_geometry_face_random_color(); + if (enabled_geometry_face_random_color) { + Color debug_navigation_geometry_face_color = NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_color(); + Color polygon_color = debug_navigation_geometry_face_color; + + Vector<Color> face_color_array; + face_color_array.resize(polygon_count * 3); + + for (int i = 0; i < polygon_count; i++) { + polygon_color = debug_navigation_geometry_face_color * (Color(Math::randf(), Math::randf(), Math::randf())); + + Vector<int> polygon = navigationmesh->get_polygon(i); + + face_color_array.push_back(polygon_color); + face_color_array.push_back(polygon_color); + face_color_array.push_back(polygon_color); + } + face_mesh_array[Mesh::ARRAY_COLOR] = face_color_array; + } + + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, face_mesh_array); + Ref<StandardMaterial3D> debug_geometry_face_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_face_material(); + debug_mesh->surface_set_material(0, debug_geometry_face_material); + + // if enabled build geometry edge line surface + bool enabled_edge_lines = NavigationServer3D::get_singleton()->get_debug_navigation_enable_edge_lines(); + + if (enabled_edge_lines) { + Vector<Vector3> line_vertex_array; + line_vertex_array.resize(polygon_count * 6); + + for (int i = 0; i < polygon_count; i++) { + Vector<int> polygon = navigationmesh->get_polygon(i); + + line_vertex_array.push_back(vertices[polygon[0]]); + line_vertex_array.push_back(vertices[polygon[1]]); + line_vertex_array.push_back(vertices[polygon[1]]); + line_vertex_array.push_back(vertices[polygon[2]]); + line_vertex_array.push_back(vertices[polygon[2]]); + line_vertex_array.push_back(vertices[polygon[0]]); + } + + Array line_mesh_array; + line_mesh_array.resize(Mesh::ARRAY_MAX); + line_mesh_array[Mesh::ARRAY_VERTEX] = line_vertex_array; + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, line_mesh_array); + Ref<StandardMaterial3D> debug_geometry_edge_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_edge_material(); + debug_mesh->surface_set_material(1, debug_geometry_edge_material); + } + + if (!navigationregion->is_enabled()) { + if (debug_mesh.is_valid()) { + if (debug_mesh->get_surface_count() > 0) { + debug_mesh->surface_set_material(0, NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_face_disabled_material()); + } + if (debug_mesh->get_surface_count() > 1) { + debug_mesh->surface_set_material(1, NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_edge_disabled_material()); + } + } + } + + p_gizmo->add_mesh(debug_mesh); p_gizmo->add_collision_segments(lines); } @@ -5044,8 +5148,8 @@ Basis JointGizmosDrawer::look_body_toward_z(const Transform3D &p_joint_transform void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const Transform3D &p_offset, const Basis &p_base, real_t p_limit_lower, real_t p_limit_upper, Vector<Vector3> &r_points, bool p_inverse) { if (p_limit_lower == p_limit_upper) { - r_points.push_back(p_offset.translated(Vector3()).origin); - r_points.push_back(p_offset.translated(p_base.xform(Vector3(0.5, 0, 0))).origin); + r_points.push_back(p_offset.translated_local(Vector3()).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(0.5, 0, 0))).origin); } else { if (p_limit_lower > p_limit_upper) { @@ -5087,20 +5191,20 @@ void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const } if (i == points - 1) { - r_points.push_back(p_offset.translated(to).origin); - r_points.push_back(p_offset.translated(Vector3()).origin); + r_points.push_back(p_offset.translated_local(to).origin); + r_points.push_back(p_offset.translated_local(Vector3()).origin); } if (i == 0) { - r_points.push_back(p_offset.translated(from).origin); - r_points.push_back(p_offset.translated(Vector3()).origin); + r_points.push_back(p_offset.translated_local(from).origin); + r_points.push_back(p_offset.translated_local(Vector3()).origin); } - r_points.push_back(p_offset.translated(from).origin); - r_points.push_back(p_offset.translated(to).origin); + r_points.push_back(p_offset.translated_local(from).origin); + r_points.push_back(p_offset.translated_local(to).origin); } - r_points.push_back(p_offset.translated(Vector3(0, p_radius * 1.5, 0)).origin); - r_points.push_back(p_offset.translated(Vector3()).origin); + r_points.push_back(p_offset.translated_local(Vector3(0, p_radius * 1.5, 0)).origin); + r_points.push_back(p_offset.translated_local(Vector3()).origin); } } @@ -5116,17 +5220,17 @@ void JointGizmosDrawer::draw_cone(const Transform3D &p_offset, const Basis &p_ba Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w; - r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, a.x, a.y))).origin); - r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, b.x, b.y))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(d, a.x, a.y))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(d, b.x, b.y))).origin); if (i % 90 == 0) { - r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, a.x, a.y))).origin); - r_points.push_back(p_offset.translated(p_base.xform(Vector3())).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(d, a.x, a.y))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3())).origin); } } - r_points.push_back(p_offset.translated(p_base.xform(Vector3())).origin); - r_points.push_back(p_offset.translated(p_base.xform(Vector3(1, 0, 0))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3())).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(1, 0, 0))).origin); /// Twist float ts = Math::rad2deg(p_twist); @@ -5140,8 +5244,8 @@ void JointGizmosDrawer::draw_cone(const Transform3D &p_offset, const Basis &p_ba Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w * c; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w * cn; - r_points.push_back(p_offset.translated(p_base.xform(Vector3(c, a.x, a.y))).origin); - r_points.push_back(p_offset.translated(p_base.xform(Vector3(cn, b.x, b.y))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(c, a.x, a.y))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(cn, b.x, b.y))).origin); } } @@ -5325,17 +5429,17 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { void Joint3DGizmoPlugin::CreatePinJointGizmo(const Transform3D &p_offset, Vector<Vector3> &r_cursor_points) { float cs = 0.25; - r_cursor_points.push_back(p_offset.translated(Vector3(+cs, 0, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(-cs, 0, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, +cs, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, -cs, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, +cs)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, -cs)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(+cs, 0, 0)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(-cs, 0, 0)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(0, +cs, 0)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(0, -cs, 0)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(0, 0, +cs)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(0, 0, -cs)).origin); } void Joint3DGizmoPlugin::CreateHingeJointGizmo(const Transform3D &p_offset, const Transform3D &p_trs_joint, const Transform3D &p_trs_body_a, const Transform3D &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) { - r_common_points.push_back(p_offset.translated(Vector3(0, 0, 0.5)).origin); - r_common_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin); + r_common_points.push_back(p_offset.translated_local(Vector3(0, 0, 0.5)).origin); + r_common_points.push_back(p_offset.translated_local(Vector3(0, 0, -0.5)).origin); if (!p_use_limit) { p_limit_upper = -1; @@ -5368,34 +5472,34 @@ void Joint3DGizmoPlugin::CreateSliderJointGizmo(const Transform3D &p_offset, con p_linear_limit_upper = -p_linear_limit_upper; float cs = 0.25; - r_points.push_back(p_offset.translated(Vector3(0, 0, 0.5)).origin); - r_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin); + r_points.push_back(p_offset.translated_local(Vector3(0, 0, 0.5)).origin); + r_points.push_back(p_offset.translated_local(Vector3(0, 0, -0.5)).origin); if (p_linear_limit_lower >= p_linear_limit_upper) { - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, 0, 0)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, 0, 0)).origin); - - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, -cs)).origin); - - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, 0, 0)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, 0, 0)).origin); + + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, -cs)).origin); + + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, -cs)).origin); } else { - r_points.push_back(p_offset.translated(Vector3(+cs * 2, 0, 0)).origin); - r_points.push_back(p_offset.translated(Vector3(-cs * 2, 0, 0)).origin); + r_points.push_back(p_offset.translated_local(Vector3(+cs * 2, 0, 0)).origin); + r_points.push_back(p_offset.translated_local(Vector3(-cs * 2, 0, 0)).origin); } if (r_body_a_points) { @@ -5518,13 +5622,13 @@ void Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo( break; } -#define ADD_VTX(x, y, z) \ - { \ - Vector3 v; \ - v[a1] = (x); \ - v[a2] = (y); \ - v[a3] = (z); \ - r_points.push_back(p_offset.translated(v).origin); \ +#define ADD_VTX(x, y, z) \ + { \ + Vector3 v; \ + v[a1] = (x); \ + v[a2] = (y); \ + v[a3] = (z); \ + r_points.push_back(p_offset.translated_local(v).origin); \ } if (enable_lin && lll >= lul) { diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h index a0d7715347..739bf1b929 100644 --- a/editor/plugins/node_3d_editor_gizmos.h +++ b/editor/plugins/node_3d_editor_gizmos.h @@ -373,6 +373,18 @@ public: RayCast3DGizmoPlugin(); }; +class ShapeCast3DGizmoPlugin : public EditorNode3DGizmoPlugin { + GDCLASS(ShapeCast3DGizmoPlugin, EditorNode3DGizmoPlugin); + +public: + bool has_gizmo(Node3D *p_spatial) override; + String get_gizmo_name() const override; + int get_priority() const override; + void redraw(EditorNode3DGizmo *p_gizmo) override; + + ShapeCast3DGizmoPlugin(); +}; + class SpringArm3DGizmoPlugin : public EditorNode3DGizmoPlugin { GDCLASS(SpringArm3DGizmoPlugin, EditorNode3DGizmoPlugin); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 44ab4e0a41..6afc6798d0 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -356,14 +356,14 @@ void Node3DEditorViewport::_update_camera(real_t p_interp_delta) { Transform3D Node3DEditorViewport::to_camera_transform(const Cursor &p_cursor) const { Transform3D camera_transform; - camera_transform.translate(p_cursor.pos); + camera_transform.translate_local(p_cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -p_cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -p_cursor.y_rot); if (orthogonal) { - camera_transform.translate(0, 0, (get_zfar() - get_znear()) / 2.0); + camera_transform.translate_local(0, 0, (get_zfar() - get_znear()) / 2.0); } else { - camera_transform.translate(0, 0, p_cursor.distance); + camera_transform.translate_local(0, 0, p_cursor.distance); } return camera_transform; @@ -515,7 +515,7 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) { } } -ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) { +ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const { Vector3 ray = _get_ray(p_pos); Vector3 pos = _get_ray_pos(p_pos); Vector2 shrinked_pos = p_pos / subviewport_container->get_stretch_shrink(); @@ -651,10 +651,10 @@ Vector3 Node3DEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) { Vector2 screen_he = cm.get_viewport_half_extents(); Transform3D camera_transform; - camera_transform.translate(cursor.pos); + camera_transform.translate_local(cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); - camera_transform.translate(0, 0, cursor.distance); + camera_transform.translate_local(0, 0, cursor.distance); return camera_transform.xform(Vector3(((p_vector3.x / get_size().width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (p_vector3.y / get_size().height)) * 2.0 - 1.0) * screen_he.y, -(get_znear() + p_vector3.z))); } @@ -1260,7 +1260,9 @@ void Node3DEditorViewport::_surface_mouse_enter() { } void Node3DEditorViewport::_surface_mouse_exit() { - _remove_preview(); + _remove_preview_node(); + _reset_preview_material(); + _remove_preview_material(); } void Node3DEditorViewport::_surface_focus_enter() { @@ -1384,25 +1386,17 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { const real_t zoom_factor = 1 + (ZOOM_FREELOOK_MULTIPLIER - 1) * b->get_factor(); switch (b->get_button_index()) { case MouseButton::WHEEL_UP: { - if (b->is_alt_pressed()) { - scale_fov(-0.05); + if (is_freelook_active()) { + scale_freelook_speed(zoom_factor); } else { - if (is_freelook_active()) { - scale_freelook_speed(zoom_factor); - } else { - scale_cursor_distance(1.0 / zoom_factor); - } + scale_cursor_distance(1.0 / zoom_factor); } } break; case MouseButton::WHEEL_DOWN: { - if (b->is_alt_pressed()) { - scale_fov(0.05); + if (is_freelook_active()) { + scale_freelook_speed(1.0 / zoom_factor); } else { - if (is_freelook_active()) { - scale_freelook_speed(1.0 / zoom_factor); - } else { - scale_cursor_distance(zoom_factor); - } + scale_cursor_distance(zoom_factor); } } break; case MouseButton::RIGHT: { @@ -2100,7 +2094,7 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const Transform3D camera_transform; - camera_transform.translate(cursor.pos); + camera_transform.translate_local(cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); const bool invert_x_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_x_axis"); @@ -2110,7 +2104,7 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const (invert_y_axis ? -1 : 1) * p_relative.y * pan_speed, 0); translation *= cursor.distance / DISTANCE_DEFAULT; - camera_transform.translate(translation); + camera_transform.translate_local(translation); cursor.pos = camera_transform.origin; } @@ -2423,8 +2417,8 @@ void Node3DEditorViewport::_project_settings_changed() { const float fsr_sharpness = GLOBAL_GET("rendering/scaling_3d/fsr_sharpness"); viewport->set_fsr_sharpness(fsr_sharpness); - const float fsr_mipmap_bias = GLOBAL_GET("rendering/scaling_3d/fsr_mipmap_bias"); - viewport->set_fsr_mipmap_bias(fsr_mipmap_bias); + const float texture_mipmap_bias = GLOBAL_GET("rendering/textures/default_filters/texture_mipmap_bias"); + viewport->set_texture_mipmap_bias(texture_mipmap_bias); } void Node3DEditorViewport::_notification(int p_what) { @@ -2520,14 +2514,14 @@ void Node3DEditorViewport::_notification(int p_what) { const Vector3 offset(0.005, 0.005, 0.005); Basis aabb_s; aabb_s.scale(se->aabb.size + offset); - t.translate(se->aabb.position - offset / 2); + t.translate_local(se->aabb.position - offset / 2); t.basis = t.basis * aabb_s; } { const Vector3 offset(0.01, 0.01, 0.01); Basis aabb_s; aabb_s.scale(se->aabb.size + offset); - t_offset.translate(se->aabb.position - offset / 2); + t_offset.translate_local(se->aabb.position - offset / 2); t_offset.basis = t_offset.basis * aabb_s; } @@ -2703,6 +2697,13 @@ void Node3DEditorViewport::_notification(int p_what) { cinema_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); locked_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); } break; + + case NOTIFICATION_DRAG_END: { + // Clear preview material when dropped outside applicable object. + if (spatial_editor->get_preview_material().is_valid() && !is_drag_successful()) { + _remove_preview_material(); + } + } break; } } @@ -3794,7 +3795,7 @@ Node *Node3DEditorViewport::_sanitize_preview_node(Node *p_node) const { return p_node; } -void Node3DEditorViewport::_create_preview(const Vector<String> &files) const { +void Node3DEditorViewport::_create_preview_node(const Vector<String> &files) const { for (int i = 0; i < files.size(); i++) { String path = files[i]; Ref<Resource> res = ResourceLoader::load(path); @@ -3821,7 +3822,7 @@ void Node3DEditorViewport::_create_preview(const Vector<String> &files) const { *preview_bounds = _calculate_spatial_bounds(preview_node); } -void Node3DEditorViewport::_remove_preview() { +void Node3DEditorViewport::_remove_preview_node() { if (preview_node->get_parent()) { for (int i = preview_node->get_child_count() - 1; i >= 0; i--) { Node *node = preview_node->get_child(i); @@ -3832,6 +3833,106 @@ void Node3DEditorViewport::_remove_preview() { } } +bool Node3DEditorViewport::_apply_preview_material(ObjectID p_target, const Point2 &p_point) const { + _reset_preview_material(); + + if (p_target.is_null()) { + return false; + } + + spatial_editor->set_preview_material_target(p_target); + + Object *target_inst = ObjectDB::get_instance(p_target); + + bool is_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL); + + MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(target_inst); + if (is_ctrl && mesh_instance) { + Ref<Mesh> mesh = mesh_instance->get_mesh(); + int surface_count = mesh->get_surface_count(); + + Vector3 world_ray = _get_ray(p_point); + Vector3 world_pos = _get_ray_pos(p_point); + + int closest_surface = -1; + float closest_dist = 1e20; + + Transform3D gt = mesh_instance->get_global_transform(); + + Transform3D ai = gt.affine_inverse(); + Vector3 xform_ray = ai.basis.xform(world_ray).normalized(); + Vector3 xform_pos = ai.xform(world_pos); + + for (int surface = 0; surface < surface_count; surface++) { + Ref<TriangleMesh> surface_mesh = mesh->generate_surface_triangle_mesh(surface); + + Vector3 rpos, rnorm; + if (surface_mesh->intersect_ray(xform_pos, xform_ray, rpos, rnorm)) { + Vector3 hitpos = gt.xform(rpos); + + const real_t dist = world_pos.distance_to(hitpos); + + if (dist < 0) { + continue; + } + + if (dist < closest_dist) { + closest_surface = surface; + closest_dist = dist; + } + } + } + + if (closest_surface == -1) { + return false; + } + + if (spatial_editor->get_preview_material() != mesh_instance->get_surface_override_material(closest_surface)) { + spatial_editor->set_preview_material_surface(closest_surface); + spatial_editor->set_preview_reset_material(mesh_instance->get_surface_override_material(closest_surface)); + mesh_instance->set_surface_override_material(closest_surface, spatial_editor->get_preview_material()); + } + + return true; + } + + GeometryInstance3D *geometry_instance = Object::cast_to<GeometryInstance3D>(target_inst); + if (geometry_instance && spatial_editor->get_preview_material() != geometry_instance->get_material_override()) { + spatial_editor->set_preview_reset_material(geometry_instance->get_material_override()); + geometry_instance->set_material_override(spatial_editor->get_preview_material()); + return true; + } + + return false; +} + +void Node3DEditorViewport::_reset_preview_material() const { + ObjectID last_target = spatial_editor->get_preview_material_target(); + if (last_target.is_null()) { + return; + } + Object *last_target_inst = ObjectDB::get_instance(last_target); + + MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(last_target_inst); + GeometryInstance3D *geometry_instance = Object::cast_to<GeometryInstance3D>(last_target_inst); + if (mesh_instance && spatial_editor->get_preview_material_surface() != -1) { + mesh_instance->set_surface_override_material(spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_reset_material()); + spatial_editor->set_preview_material_surface(-1); + } else if (geometry_instance) { + geometry_instance->set_material_override(spatial_editor->get_preview_reset_material()); + } +} + +void Node3DEditorViewport::_remove_preview_material() { + preview_material_label->hide(); + preview_material_label_desc->hide(); + + spatial_editor->set_preview_material(Ref<Material>()); + spatial_editor->set_preview_reset_material(Ref<Material>()); + spatial_editor->set_preview_material_target(ObjectID()); + spatial_editor->set_preview_material_surface(-1); +} + bool Node3DEditorViewport::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) { if (p_desired_node->get_scene_file_path() == p_target_scene_path) { return true; @@ -3930,7 +4031,26 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po } void Node3DEditorViewport::_perform_drop_data() { - _remove_preview(); + if (spatial_editor->get_preview_material_target().is_valid()) { + GeometryInstance3D *geometry_instance = Object::cast_to<GeometryInstance3D>(ObjectDB::get_instance(spatial_editor->get_preview_material_target())); + MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(ObjectDB::get_instance(spatial_editor->get_preview_material_target())); + if (mesh_instance && spatial_editor->get_preview_material_surface() != -1) { + editor_data->get_undo_redo().create_action(vformat(TTR("Set Surface %d Override Material"), spatial_editor->get_preview_material_surface())); + editor_data->get_undo_redo().add_do_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_material()); + editor_data->get_undo_redo().add_undo_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_reset_material()); + editor_data->get_undo_redo().commit_action(); + } else if (geometry_instance) { + editor_data->get_undo_redo().create_action(TTR("Set Material Override")); + editor_data->get_undo_redo().add_do_method(geometry_instance, "set_material_override", spatial_editor->get_preview_material()); + editor_data->get_undo_redo().add_undo_method(geometry_instance, "set_material_override", spatial_editor->get_preview_reset_material()); + editor_data->get_undo_redo().commit_action(); + } + + _remove_preview_material(); + return; + } + + _remove_preview_node(); Vector<String> error_files; @@ -3968,7 +4088,7 @@ void Node3DEditorViewport::_perform_drop_data() { bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { bool can_instantiate = false; - if (!preview_node->is_inside_tree()) { + if (!preview_node->is_inside_tree() && spatial_editor->get_preview_material().is_null()) { Dictionary d = p_data; if (d.has("type") && (String(d["type"]) == "files")) { Vector<String> files = d["files"]; @@ -3977,40 +4097,78 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions); List<String> mesh_extensions; ResourceLoader::get_recognized_extensions_for_type("Mesh", &mesh_extensions); + List<String> material_extensions; + ResourceLoader::get_recognized_extensions_for_type("Material", &material_extensions); + List<String> texture_extensions; + ResourceLoader::get_recognized_extensions_for_type("Texture", &texture_extensions); for (int i = 0; i < files.size(); i++) { // Check if dragged files with mesh or scene extension can be created at least once. - if (mesh_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) { + if (mesh_extensions.find(files[i].get_extension()) || + scene_extensions.find(files[i].get_extension()) || + material_extensions.find(files[i].get_extension()) || + texture_extensions.find(files[i].get_extension())) { Ref<Resource> res = ResourceLoader::load(files[i]); if (res.is_null()) { continue; } Ref<PackedScene> scn = res; + Ref<Material> mat = res; + Ref<Texture2D> tex = res; if (scn.is_valid()) { Node *instantiated_scene = scn->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); if (!instantiated_scene) { continue; } memdelete(instantiated_scene); + } else if (mat.is_valid()) { + Ref<BaseMaterial3D> base_mat = res; + Ref<ShaderMaterial> shader_mat = res; + + if (base_mat.is_null() && !shader_mat.is_null()) { + break; + } + + spatial_editor->set_preview_material(mat); + break; + } else if (tex.is_valid()) { + Ref<StandardMaterial3D> new_mat = memnew(StandardMaterial3D); + new_mat->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, tex); + + spatial_editor->set_preview_material(new_mat); + break; + } else { + continue; } can_instantiate = true; break; } } if (can_instantiate) { - _create_preview(files); + _create_preview_node(files); } } } else { - can_instantiate = true; + if (preview_node->is_inside_tree()) { + can_instantiate = true; + } } if (can_instantiate) { Transform3D global_transform = Transform3D(Basis(), _get_instance_position(p_point)); preview_node->set_global_transform(global_transform); + return true; + } + + if (spatial_editor->get_preview_material().is_valid()) { + preview_material_label->show(); + preview_material_label_desc->show(); + + ObjectID new_preview_material_target = _select_ray(p_point); + return _apply_preview_material(new_preview_material_target, p_point); } - return can_instantiate; + return false; } void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { @@ -4048,7 +4206,7 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_ } else { accept->set_text(TTR("Cannot drag and drop into multiple selected nodes.")); accept->popup_centered(); - _remove_preview(); + _remove_preview_node(); return; } @@ -4450,7 +4608,7 @@ void Node3DEditorViewport::register_shortcut_action(const String &p_path, const Ref<Shortcut> sc = ED_SHORTCUT(p_path, p_name, p_keycode); shortcut_changed_callback(sc, p_path); // Connect to the change event on the shortcut so the input binding can be updated. - sc->connect("changed", callable_mp(this, &Node3DEditorViewport::shortcut_changed_callback), varray(sc, p_path)); + sc->connect("changed", callable_mp(this, &Node3DEditorViewport::shortcut_changed_callback).bind(sc, p_path)); } // Update the action in the InputMap to the provided shortcut events. @@ -4699,6 +4857,23 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p zoom_limit_label->hide(); surface->add_child(zoom_limit_label); + preview_material_label = memnew(Label); + preview_material_label->set_anchors_and_offsets_preset(LayoutPreset::PRESET_BOTTOM_LEFT); + preview_material_label->set_offset(Side::SIDE_TOP, -70 * EDSCALE); + preview_material_label->set_text(TTR("Overriding material...")); + preview_material_label->add_theme_color_override("font_color", Color(1, 1, 1, 1)); + preview_material_label->hide(); + surface->add_child(preview_material_label); + + preview_material_label_desc = memnew(Label); + preview_material_label_desc->set_anchors_and_offsets_preset(LayoutPreset::PRESET_BOTTOM_LEFT); + preview_material_label_desc->set_offset(Side::SIDE_TOP, -50 * EDSCALE); + preview_material_label_desc->set_text(TTR("Drag and drop to override the material of any geometry node.\nHold Ctrl when dropping to override a specific surface.")); + preview_material_label_desc->add_theme_color_override("font_color", Color(0.8, 0.8, 0.8, 1)); + preview_material_label_desc->add_theme_constant_override("line_spacing", 0); + preview_material_label_desc->hide(); + surface->add_child(preview_material_label_desc); + frame_time_gradient = memnew(Gradient); // The color is set when the theme changes. frame_time_gradient->add_point(0.5, Color()); @@ -6225,7 +6400,7 @@ void fragment() { Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial); rotate_mat->set_render_priority(Material::RENDER_PRIORITY_MAX); rotate_mat->set_shader(rotate_shader); - rotate_mat->set_shader_param("albedo", col); + rotate_mat->set_shader_uniform("albedo", col); rotate_gizmo_color[i] = rotate_mat; Array arrays = surftool->commit_to_arrays(); @@ -6233,7 +6408,7 @@ void fragment() { rotate_gizmo[i]->surface_set_material(0, rotate_mat); Ref<ShaderMaterial> rotate_mat_hl = rotate_mat->duplicate(); - rotate_mat_hl->set_shader_param("albedo", albedo); + rotate_mat_hl->set_shader_uniform("albedo", albedo); rotate_gizmo_color_hl[i] = rotate_mat_hl; if (i == 2) { // Rotation white outline @@ -6274,7 +6449,7 @@ void fragment() { )"); border_mat->set_shader(border_shader); - border_mat->set_shader_param("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0)); + border_mat->set_shader_uniform("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0)); rotate_gizmo[3] = Ref<ArrayMesh>(memnew(ArrayMesh)); rotate_gizmo[3]->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays); @@ -6527,8 +6702,8 @@ void Node3DEditor::_init_grid() { fade_size = CLAMP(fade_size, min_fade_size, max_fade_size); real_t grid_fade_size = (grid_size - primary_grid_steps) * fade_size; - grid_mat[c]->set_shader_param("grid_size", grid_fade_size); - grid_mat[c]->set_shader_param("orthogonal", orthogonal); + grid_mat[c]->set_shader_uniform("grid_size", grid_fade_size); + grid_mat[c]->set_shader_uniform("orthogonal", orthogonal); // Cache these so we don't have to re-access memory. Vector<Vector3> &ref_grid = grid_points[c]; @@ -6999,8 +7174,8 @@ void Node3DEditor::_notification(int p_what) { SceneTreeDock::get_singleton()->get_tree_editor()->connect("node_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); editor_selection->connect("selection_changed", callable_mp(this, &Node3DEditor::_selection_changed)); - EditorNode::get_singleton()->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(false)); - EditorNode::get_singleton()->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(true)); + EditorNode::get_singleton()->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button).bind(false)); + EditorNode::get_singleton()->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button).bind(true)); _update_preview_environment(); @@ -7314,6 +7489,7 @@ void Node3DEditor::_register_all_gizmos() { add_gizmo_plugin(Ref<Label3DGizmoPlugin>(memnew(Label3DGizmoPlugin))); add_gizmo_plugin(Ref<Position3DGizmoPlugin>(memnew(Position3DGizmoPlugin))); add_gizmo_plugin(Ref<RayCast3DGizmoPlugin>(memnew(RayCast3DGizmoPlugin))); + add_gizmo_plugin(Ref<ShapeCast3DGizmoPlugin>(memnew(ShapeCast3DGizmoPlugin))); add_gizmo_plugin(Ref<SpringArm3DGizmoPlugin>(memnew(SpringArm3DGizmoPlugin))); add_gizmo_plugin(Ref<VehicleWheel3DGizmoPlugin>(memnew(VehicleWheel3DGizmoPlugin))); add_gizmo_plugin(Ref<VisibleOnScreenNotifier3DGizmoPlugin>(memnew(VisibleOnScreenNotifier3DGizmoPlugin))); @@ -7375,9 +7551,9 @@ void Node3DEditor::_sun_direction_draw() { sun_direction->draw_rect(Rect2(Vector2(), sun_direction->get_size()), Color(1, 1, 1, 1)); Vector3 z_axis = preview_sun->get_transform().basis.get_column(Vector3::AXIS_Z); z_axis = get_editor_viewport(0)->camera->get_camera_transform().basis.xform_inv(z_axis); - sun_direction_material->set_shader_param("sun_direction", Vector3(z_axis.x, -z_axis.y, z_axis.z)); + sun_direction_material->set_shader_uniform("sun_direction", Vector3(z_axis.x, -z_axis.y, z_axis.z)); Color color = sun_color->get_pick_color() * sun_energy->get_value(); - sun_direction_material->set_shader_param("sun_color", Vector3(color.r, color.g, color.b)); + sun_direction_material->set_shader_uniform("sun_color", Vector3(color.r, color.g, color.b)); } void Node3DEditor::_preview_settings_changed() { @@ -7538,8 +7714,6 @@ Node3DEditor::Node3DEditor() { HBoxContainer *main_menu_hbox = memnew(HBoxContainer); main_flow->add_child(main_menu_hbox); - Vector<Variant> button_binds; - button_binds.resize(1); String sct; // Add some margin to the left for better aesthetics. @@ -7554,8 +7728,7 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true); tool_button[TOOL_MODE_SELECT]->set_flat(true); tool_button[TOOL_MODE_SELECT]->set_pressed(true); - button_binds.write[0] = MENU_TOOL_SELECT; - tool_button[TOOL_MODE_SELECT]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); + tool_button[TOOL_MODE_SELECT]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_TOOL_SELECT)); tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), Key::Q)); tool_button[TOOL_MODE_SELECT]->set_shortcut_context(this); tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.")); @@ -7565,8 +7738,8 @@ Node3DEditor::Node3DEditor() { main_menu_hbox->add_child(tool_button[TOOL_MODE_MOVE]); tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true); tool_button[TOOL_MODE_MOVE]->set_flat(true); - button_binds.write[0] = MENU_TOOL_MOVE; - tool_button[TOOL_MODE_MOVE]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); + + tool_button[TOOL_MODE_MOVE]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_TOOL_MOVE)); tool_button[TOOL_MODE_MOVE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_move", TTR("Move Mode"), Key::W)); tool_button[TOOL_MODE_MOVE]->set_shortcut_context(this); @@ -7574,8 +7747,7 @@ Node3DEditor::Node3DEditor() { main_menu_hbox->add_child(tool_button[TOOL_MODE_ROTATE]); tool_button[TOOL_MODE_ROTATE]->set_toggle_mode(true); tool_button[TOOL_MODE_ROTATE]->set_flat(true); - button_binds.write[0] = MENU_TOOL_ROTATE; - tool_button[TOOL_MODE_ROTATE]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); + tool_button[TOOL_MODE_ROTATE]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_TOOL_ROTATE)); tool_button[TOOL_MODE_ROTATE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Rotate Mode"), Key::E)); tool_button[TOOL_MODE_ROTATE]->set_shortcut_context(this); @@ -7583,8 +7755,7 @@ Node3DEditor::Node3DEditor() { main_menu_hbox->add_child(tool_button[TOOL_MODE_SCALE]); tool_button[TOOL_MODE_SCALE]->set_toggle_mode(true); tool_button[TOOL_MODE_SCALE]->set_flat(true); - button_binds.write[0] = MENU_TOOL_SCALE; - tool_button[TOOL_MODE_SCALE]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); + tool_button[TOOL_MODE_SCALE]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_TOOL_SCALE)); tool_button[TOOL_MODE_SCALE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_scale", TTR("Scale Mode"), Key::R)); tool_button[TOOL_MODE_SCALE]->set_shortcut_context(this); @@ -7594,15 +7765,13 @@ Node3DEditor::Node3DEditor() { main_menu_hbox->add_child(tool_button[TOOL_MODE_LIST_SELECT]); tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true); tool_button[TOOL_MODE_LIST_SELECT]->set_flat(true); - button_binds.write[0] = MENU_TOOL_LIST_SELECT; - tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); + tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_TOOL_LIST_SELECT)); tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show list of selectable nodes at position clicked.")); tool_button[TOOL_LOCK_SELECTED] = memnew(Button); main_menu_hbox->add_child(tool_button[TOOL_LOCK_SELECTED]); tool_button[TOOL_LOCK_SELECTED]->set_flat(true); - button_binds.write[0] = MENU_LOCK_SELECTED; - tool_button[TOOL_LOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); + tool_button[TOOL_LOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_LOCK_SELECTED)); tool_button[TOOL_LOCK_SELECTED]->set_tooltip(TTR("Lock selected node, preventing selection and movement.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. tool_button[TOOL_LOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/lock_selected_nodes", TTR("Lock Selected Node(s)"), KeyModifierMask::CMD | Key::L)); @@ -7610,8 +7779,7 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_UNLOCK_SELECTED] = memnew(Button); main_menu_hbox->add_child(tool_button[TOOL_UNLOCK_SELECTED]); tool_button[TOOL_UNLOCK_SELECTED]->set_flat(true); - button_binds.write[0] = MENU_UNLOCK_SELECTED; - tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); + tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_UNLOCK_SELECTED)); tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock selected node, allowing selection and movement.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. tool_button[TOOL_UNLOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/unlock_selected_nodes", TTR("Unlock Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::L)); @@ -7619,18 +7787,16 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_GROUP_SELECTED] = memnew(Button); main_menu_hbox->add_child(tool_button[TOOL_GROUP_SELECTED]); tool_button[TOOL_GROUP_SELECTED]->set_flat(true); - button_binds.write[0] = MENU_GROUP_SELECTED; - tool_button[TOOL_GROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); - tool_button[TOOL_GROUP_SELECTED]->set_tooltip(TTR("Makes sure the object's children are not selectable.")); + tool_button[TOOL_GROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_GROUP_SELECTED)); + tool_button[TOOL_GROUP_SELECTED]->set_tooltip(TTR("Make selected node's children not selectable.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. tool_button[TOOL_GROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD | Key::G)); tool_button[TOOL_UNGROUP_SELECTED] = memnew(Button); main_menu_hbox->add_child(tool_button[TOOL_UNGROUP_SELECTED]); tool_button[TOOL_UNGROUP_SELECTED]->set_flat(true); - button_binds.write[0] = MENU_UNGROUP_SELECTED; - tool_button[TOOL_UNGROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); - tool_button[TOOL_UNGROUP_SELECTED]->set_tooltip(TTR("Restores the object's children's ability to be selected.")); + tool_button[TOOL_UNGROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_UNGROUP_SELECTED)); + tool_button[TOOL_UNGROUP_SELECTED]->set_tooltip(TTR("Make selected node's children selectable.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. tool_button[TOOL_UNGROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G)); @@ -7640,8 +7806,7 @@ Node3DEditor::Node3DEditor() { main_menu_hbox->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]); tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_toggle_mode(true); tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true); - button_binds.write[0] = MENU_TOOL_LOCAL_COORDS; - tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", callable_mp(this, &Node3DEditor::_menu_item_toggled), button_binds); + tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", callable_mp(this, &Node3DEditor::_menu_item_toggled).bind(MENU_TOOL_LOCAL_COORDS)); tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_shortcut(ED_SHORTCUT("spatial_editor/local_coords", TTR("Use Local Space"), Key::T)); tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_shortcut_context(this); @@ -7649,8 +7814,7 @@ Node3DEditor::Node3DEditor() { main_menu_hbox->add_child(tool_option_button[TOOL_OPT_USE_SNAP]); tool_option_button[TOOL_OPT_USE_SNAP]->set_toggle_mode(true); tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true); - button_binds.write[0] = MENU_TOOL_USE_SNAP; - tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", callable_mp(this, &Node3DEditor::_menu_item_toggled), button_binds); + tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", callable_mp(this, &Node3DEditor::_menu_item_toggled).bind(MENU_TOOL_USE_SNAP)); tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut(ED_SHORTCUT("spatial_editor/snap", TTR("Use Snap"), Key::Y)); tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut_context(this); @@ -7661,8 +7825,7 @@ Node3DEditor::Node3DEditor() { tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_toggle_mode(true); tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_flat(true); tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_disabled(true); - button_binds.write[0] = MENU_TOOL_OVERRIDE_CAMERA; - tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->connect("toggled", callable_mp(this, &Node3DEditor::_menu_item_toggled), button_binds); + tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->connect("toggled", callable_mp(this, &Node3DEditor::_menu_item_toggled).bind(MENU_TOOL_OVERRIDE_CAMERA)); _update_camera_override_button(false); main_menu_hbox->add_child(memnew(VSeparator)); @@ -7670,7 +7833,7 @@ Node3DEditor::Node3DEditor() { sun_button->set_tooltip(TTR("Toggle preview sunlight.\nIf a DirectionalLight3D node is added to the scene, preview sunlight is disabled.")); sun_button->set_toggle_mode(true); sun_button->set_flat(true); - sun_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED); + sun_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), CONNECT_DEFERRED); sun_button->set_disabled(true); main_menu_hbox->add_child(sun_button); @@ -7679,7 +7842,7 @@ Node3DEditor::Node3DEditor() { environ_button->set_tooltip(TTR("Toggle preview environment.\nIf a WorldEnvironment node is added to the scene, preview environment is disabled.")); environ_button->set_toggle_mode(true); environ_button->set_flat(true); - environ_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED); + environ_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), CONNECT_DEFERRED); environ_button->set_disabled(true); main_menu_hbox->add_child(environ_button); @@ -7866,7 +8029,7 @@ Node3DEditor::Node3DEditor() { settings_vbc->add_margin_child(TTR("View Z-Far:"), settings_zfar); for (uint32_t i = 0; i < VIEWPORTS_COUNT; ++i) { - settings_dialog->connect("confirmed", callable_mp(viewports[i], &Node3DEditorViewport::_view_settings_confirmed), varray(0.0)); + settings_dialog->connect("confirmed", callable_mp(viewports[i], &Node3DEditorViewport::_view_settings_confirmed).bind(0.0)); } /* XFORM DIALOG */ @@ -7991,8 +8154,8 @@ void fragment() { )"); sun_direction_material.instantiate(); sun_direction_material->set_shader(sun_direction_shader); - sun_direction_material->set_shader_param("sun_direction", Vector3(0, 0, 1)); - sun_direction_material->set_shader_param("sun_color", Vector3(1, 1, 1)); + sun_direction_material->set_shader_uniform("sun_direction", Vector3(0, 0, 1)); + sun_direction_material->set_shader_uniform("sun_color", Vector3(1, 1, 1)); sun_direction->set_material(sun_direction_material); HBoxContainer *sun_angle_hbox = memnew(HBoxContainer); @@ -8028,7 +8191,7 @@ void fragment() { sun_color->set_edit_alpha(false); sun_vb->add_margin_child(TTR("Sun Color"), sun_color); sun_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); - sun_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(sun_color->get_picker())); + sun_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(sun_color->get_picker())); sun_energy = memnew(EditorSpinSlider); sun_vb->add_margin_child(TTR("Sun Energy"), sun_energy); @@ -8044,7 +8207,7 @@ void fragment() { sun_add_to_scene = memnew(Button); sun_add_to_scene->set_text(TTR("Add Sun to Scene")); sun_add_to_scene->set_tooltip(TTR("Adds a DirectionalLight3D node matching the preview sun settings to the current scene.\nHold Shift while clicking to also add the preview environment to the current scene.")); - sun_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_sun_to_scene), varray(false)); + sun_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_sun_to_scene).bind(false)); sun_vb->add_spacer(); sun_vb->add_child(sun_add_to_scene); @@ -8074,12 +8237,12 @@ void fragment() { environ_sky_color = memnew(ColorPickerButton); environ_sky_color->set_edit_alpha(false); environ_sky_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); - environ_sky_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(environ_sky_color->get_picker())); + environ_sky_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(environ_sky_color->get_picker())); environ_vb->add_margin_child(TTR("Sky Color"), environ_sky_color); environ_ground_color = memnew(ColorPickerButton); environ_ground_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); environ_ground_color->set_edit_alpha(false); - environ_ground_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(environ_ground_color->get_picker())); + environ_ground_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(environ_ground_color->get_picker())); environ_vb->add_margin_child(TTR("Ground Color"), environ_ground_color); environ_energy = memnew(EditorSpinSlider); environ_energy->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); @@ -8091,29 +8254,29 @@ void fragment() { environ_ao_button = memnew(Button); environ_ao_button->set_text(TTR("AO")); environ_ao_button->set_toggle_mode(true); - environ_ao_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + environ_ao_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), CONNECT_DEFERRED); fx_vb->add_child(environ_ao_button); environ_glow_button = memnew(Button); environ_glow_button->set_text(TTR("Glow")); environ_glow_button->set_toggle_mode(true); - environ_glow_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + environ_glow_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), CONNECT_DEFERRED); fx_vb->add_child(environ_glow_button); environ_tonemap_button = memnew(Button); environ_tonemap_button->set_text(TTR("Tonemap")); environ_tonemap_button->set_toggle_mode(true); - environ_tonemap_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + environ_tonemap_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), CONNECT_DEFERRED); fx_vb->add_child(environ_tonemap_button); environ_gi_button = memnew(Button); environ_gi_button->set_text(TTR("GI")); environ_gi_button->set_toggle_mode(true); - environ_gi_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + environ_gi_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), CONNECT_DEFERRED); fx_vb->add_child(environ_gi_button); environ_vb->add_margin_child(TTR("Post Process"), fx_vb); environ_add_to_scene = memnew(Button); environ_add_to_scene->set_text(TTR("Add Environment to Scene")); environ_add_to_scene->set_tooltip(TTR("Adds a WorldEnvironment node matching the preview environment settings to the current scene.\nHold Shift while clicking to also add the preview sun to the current scene.")); - environ_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_environment_to_scene), varray(false)); + environ_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_environment_to_scene).bind(false)); environ_vb->add_spacer(); environ_vb->add_child(environ_add_to_scene); @@ -8140,7 +8303,6 @@ void fragment() { _preview_settings_changed(); } } - Node3DEditor::~Node3DEditor() { memdelete(preview_node); } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 244b461e16..4469271a38 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -227,6 +227,9 @@ private: Label *locked_label = nullptr; Label *zoom_limit_label = nullptr; + Label *preview_material_label = nullptr; + Label *preview_material_label_desc = nullptr; + VBoxContainer *top_right_vbox = nullptr; ViewportRotationControl *rotation_control = nullptr; Gradient *frame_time_gradient = nullptr; @@ -244,7 +247,7 @@ private: void _compute_edit(const Point2 &p_point); void _clear_selected(); void _select_clicked(bool p_allow_locked); - ObjectID _select_ray(const Point2 &p_pos); + ObjectID _select_ray(const Point2 &p_pos) const; void _find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked); Vector3 _get_ray_pos(const Vector2 &p_pos) const; Vector3 _get_ray(const Vector2 &p_pos) const; @@ -272,6 +275,7 @@ private: float get_fov() const; ObjectID clicked; + ObjectID material_target; Vector<_RayResult> selection_results; bool clicked_wants_append = false; bool selection_in_progress = false; @@ -399,8 +403,11 @@ private: Node *_sanitize_preview_node(Node *p_node) const; - void _create_preview(const Vector<String> &files) const; - void _remove_preview(); + void _create_preview_node(const Vector<String> &files) const; + void _remove_preview_node(); + bool _apply_preview_material(ObjectID p_target, const Point2 &p_point) const; + void _reset_preview_material() const; + void _remove_preview_material(); bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); bool _create_instance(Node *parent, String &path, const Point2 &p_point); void _perform_drop_data(); @@ -593,6 +600,11 @@ private: Node3D *preview_node = nullptr; AABB preview_bounds; + Ref<Material> preview_material; + Ref<Material> preview_reset_material; + ObjectID preview_material_target; + int preview_material_surface = -1; + struct Gizmo { bool visible = false; real_t scale = 0; @@ -850,6 +862,15 @@ public: void set_can_preview(Camera3D *p_preview); + void set_preview_material(Ref<Material> p_material) { preview_material = p_material; } + Ref<Material> get_preview_material() { return preview_material; } + void set_preview_reset_material(Ref<Material> p_material) { preview_reset_material = p_material; } + Ref<Material> get_preview_reset_material() const { return preview_reset_material; } + void set_preview_material_target(ObjectID p_object_id) { preview_material_target = p_object_id; } + ObjectID get_preview_material_target() const { return preview_material_target; } + void set_preview_material_surface(int p_surface) { preview_material_surface = p_surface; } + int get_preview_material_surface() const { return preview_material_surface; } + Node3DEditorViewport *get_editor_viewport(int p_idx) { ERR_FAIL_INDEX_V(p_idx, static_cast<int>(VIEWPORTS_COUNT), nullptr); return viewports[p_idx]; diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp index 9e666ef70a..fd331c4127 100644 --- a/editor/plugins/path_2d_editor_plugin.cpp +++ b/editor/plugins/path_2d_editor_plugin.cpp @@ -537,7 +537,7 @@ Path2DEditor::Path2DEditor() { curve_edit->set_toggle_mode(true); curve_edit->set_focus_mode(Control::FOCUS_NONE); curve_edit->set_tooltip(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Click: Add Point") + "\n" + TTR("Left Click: Split Segment (in curve)") + "\n" + TTR("Right Click: Delete Point")); - curve_edit->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected), varray(MODE_EDIT)); + curve_edit->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_EDIT)); base_hb->add_child(curve_edit); curve_edit_curve = memnew(Button); @@ -545,7 +545,7 @@ Path2DEditor::Path2DEditor() { curve_edit_curve->set_toggle_mode(true); curve_edit_curve->set_focus_mode(Control::FOCUS_NONE); curve_edit_curve->set_tooltip(TTR("Select Control Points (Shift+Drag)")); - curve_edit_curve->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected), varray(MODE_EDIT_CURVE)); + curve_edit_curve->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_EDIT_CURVE)); base_hb->add_child(curve_edit_curve); curve_create = memnew(Button); @@ -553,7 +553,7 @@ Path2DEditor::Path2DEditor() { curve_create->set_toggle_mode(true); curve_create->set_focus_mode(Control::FOCUS_NONE); curve_create->set_tooltip(TTR("Add Point (in empty space)")); - curve_create->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected), varray(MODE_CREATE)); + curve_create->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_CREATE)); base_hb->add_child(curve_create); curve_del = memnew(Button); @@ -561,14 +561,14 @@ Path2DEditor::Path2DEditor() { curve_del->set_toggle_mode(true); curve_del->set_focus_mode(Control::FOCUS_NONE); curve_del->set_tooltip(TTR("Delete Point")); - curve_del->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected), varray(MODE_DELETE)); + curve_del->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_DELETE)); base_hb->add_child(curve_del); curve_close = memnew(Button); curve_close->set_flat(true); curve_close->set_focus_mode(Control::FOCUS_NONE); curve_close->set_tooltip(TTR("Close Curve")); - curve_close->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected), varray(ACTION_CLOSE)); + curve_close->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(ACTION_CLOSE)); base_hb->add_child(curve_close); PopupMenu *menu; diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index 36f559b2ae..65b15a6001 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -34,6 +34,7 @@ #include "core/math/geometry_3d.h" #include "core/os/keyboard.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" #include "node_3d_editor_plugin.h" #include "scene/resources/curve.h" @@ -557,9 +558,9 @@ void Path3DEditorPlugin::_update_theme() { void Path3DEditorPlugin::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - curve_create->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(0)); - curve_edit->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(1)); - curve_del->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(2)); + curve_create->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed).bind(0)); + curve_edit->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed).bind(1)); + curve_del->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed).bind(2)); curve_close->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_close_curve)); _update_theme(); diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index a682bb455c..4f46c99a04 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -192,7 +192,7 @@ void Polygon2DEditor::_update_bone_list() { cb->set_pressed(true); } - cb->connect("pressed", callable_mp(this, &Polygon2DEditor::_bone_paint_selected), varray(i)); + cb->connect("pressed", callable_mp(this, &Polygon2DEditor::_bone_paint_selected).bind(i)); } uv_edit_draw->update(); @@ -1238,7 +1238,7 @@ Polygon2DEditor::Polygon2DEditor() { button_uv->set_flat(true); add_child(button_uv); button_uv->set_tooltip(TTR("Open Polygon 2D UV editor.")); - button_uv->connect("pressed", callable_mp(this, &Polygon2DEditor::_menu_option), varray(MODE_EDIT_UV)); + button_uv->connect("pressed", callable_mp(this, &Polygon2DEditor::_menu_option).bind(MODE_EDIT_UV)); uv_mode = UV_MODE_EDIT_POINT; uv_edit = memnew(AcceptDialog); @@ -1276,10 +1276,10 @@ Polygon2DEditor::Polygon2DEditor() { uv_edit_mode[2]->set_button_group(uv_edit_group); uv_edit_mode[3]->set_button_group(uv_edit_group); - uv_edit_mode[0]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select), varray(0)); - uv_edit_mode[1]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select), varray(1)); - uv_edit_mode[2]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select), varray(2)); - uv_edit_mode[3]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select), varray(3)); + uv_edit_mode[0]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select).bind(0)); + uv_edit_mode[1]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select).bind(1)); + uv_edit_mode[2]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select).bind(2)); + uv_edit_mode[3]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select).bind(3)); uv_mode_hb->add_child(memnew(VSeparator)); @@ -1289,7 +1289,7 @@ Polygon2DEditor::Polygon2DEditor() { uv_button[i]->set_flat(true); uv_button[i]->set_toggle_mode(true); uv_mode_hb->add_child(uv_button[i]); - uv_button[i]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_mode), varray(i)); + uv_button[i]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_mode).bind(i)); uv_button[i]->set_focus_mode(FOCUS_NONE); } diff --git a/editor/plugins/polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp index 1c69e0d635..83092f990f 100644 --- a/editor/plugins/polygon_3d_editor_plugin.cpp +++ b/editor/plugins/polygon_3d_editor_plugin.cpp @@ -532,13 +532,13 @@ Polygon3DEditor::Polygon3DEditor() { button_create = memnew(Button); button_create->set_flat(true); add_child(button_create); - button_create->connect("pressed", callable_mp(this, &Polygon3DEditor::_menu_option), varray(MODE_CREATE)); + button_create->connect("pressed", callable_mp(this, &Polygon3DEditor::_menu_option).bind(MODE_CREATE)); button_create->set_toggle_mode(true); button_edit = memnew(Button); button_edit->set_flat(true); add_child(button_edit); - button_edit->connect("pressed", callable_mp(this, &Polygon3DEditor::_menu_option), varray(MODE_EDIT)); + button_edit->connect("pressed", callable_mp(this, &Polygon3DEditor::_menu_option).bind(MODE_EDIT)); button_edit->set_toggle_mode(true); mode = MODE_EDIT; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index f4d42ff456..c53ac59c11 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -41,6 +41,7 @@ #include "editor/debugger/script_editor_debugger.h" #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" #include "editor/editor_run_script.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" @@ -590,7 +591,7 @@ void ScriptEditor::_go_to_tab(int p_idx) { } } - Control *c = Object::cast_to<Control>(tab_container->get_tab_control(p_idx)); + Control *c = tab_container->get_tab_control(p_idx); if (!c) { return; } @@ -812,7 +813,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) { if (history_pos >= 0) { idx = tab_container->get_tab_idx_from_control(history[history_pos].control); } - tab_container->set_current_tab(idx); + _go_to_tab(idx); } else { _update_selected_editor_menu(); } @@ -882,7 +883,7 @@ void ScriptEditor::_queue_close_tabs() { // Maybe there are unsaved changes. if (se->is_unsaved()) { _ask_close_current_unsaved_tab(se); - erase_tab_confirm->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &ScriptEditor::_queue_close_tabs), varray(), CONNECT_ONESHOT); + erase_tab_confirm->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &ScriptEditor::_queue_close_tabs), CONNECT_ONESHOT); break; } } @@ -1447,20 +1448,20 @@ void ScriptEditor::_menu_option(int p_option) { case WINDOW_MOVE_UP: { if (tab_container->get_current_tab() > 0) { tab_container->move_child(current, tab_container->get_current_tab() - 1); - tab_container->set_current_tab(tab_container->get_current_tab() - 1); + tab_container->set_current_tab(tab_container->get_current_tab()); _update_script_names(); } } break; case WINDOW_MOVE_DOWN: { if (tab_container->get_current_tab() < tab_container->get_tab_count() - 1) { tab_container->move_child(current, tab_container->get_current_tab() + 1); - tab_container->set_current_tab(tab_container->get_current_tab() + 1); + tab_container->set_current_tab(tab_container->get_current_tab()); _update_script_names(); } } break; default: { if (p_option >= WINDOW_SELECT_BASE) { - tab_container->set_current_tab(p_option - WINDOW_SELECT_BASE); + _go_to_tab(p_option - WINDOW_SELECT_BASE); _update_script_names(); } } @@ -1493,14 +1494,14 @@ void ScriptEditor::_menu_option(int p_option) { case WINDOW_MOVE_UP: { if (tab_container->get_current_tab() > 0) { tab_container->move_child(help, tab_container->get_current_tab() - 1); - tab_container->set_current_tab(tab_container->get_current_tab() - 1); + tab_container->set_current_tab(tab_container->get_current_tab()); _update_script_names(); } } break; case WINDOW_MOVE_DOWN: { if (tab_container->get_current_tab() < tab_container->get_tab_count() - 1) { tab_container->move_child(help, tab_container->get_current_tab() + 1); - tab_container->set_current_tab(tab_container->get_current_tab() + 1); + tab_container->set_current_tab(tab_container->get_current_tab()); _update_script_names(); } } break; @@ -1542,7 +1543,7 @@ void ScriptEditor::_show_save_theme_as_dialog() { file_dialog_option = THEME_SAVE_AS; file_dialog->clear_filters(); file_dialog->add_filter("*.tet"); - file_dialog->set_current_path(EditorSettings::get_singleton()->get_text_editor_themes_dir().plus_file(EditorSettings::get_singleton()->get("text_editor/theme/color_theme"))); + file_dialog->set_current_path(EditorPaths::get_singleton()->get_text_editor_themes_dir().plus_file(EditorSettings::get_singleton()->get("text_editor/theme/color_theme"))); file_dialog->popup_file_dialog(); file_dialog->set_title(TTR("Save Theme As...")); } @@ -1852,10 +1853,12 @@ void ScriptEditor::_update_members_overview_visibility() { if (members_overview_enabled && se->show_members_overview()) { members_overview_alphabeta_sort_button->set_visible(true); + filter_methods->set_visible(true); members_overview->set_visible(true); overview_vbox->set_visible(true); } else { members_overview_alphabeta_sort_button->set_visible(false); + filter_methods->set_visible(false); members_overview->set_visible(false); overview_vbox->set_visible(false); } @@ -1910,6 +1913,7 @@ void ScriptEditor::_update_help_overview_visibility() { if (help_overview_enabled) { members_overview_alphabeta_sort_button->set_visible(false); + filter_methods->set_visible(false); help_overview->set_visible(true); overview_vbox->set_visible(true); filename->set_text(se->get_name()); @@ -2124,8 +2128,8 @@ void ScriptEditor::_update_script_names() { sd.index = i; sedata.set(i, sd); } - tab_container->set_current_tab(new_prev_tab); - tab_container->set_current_tab(new_cur_tab); + _go_to_tab(new_prev_tab); + _go_to_tab(new_cur_tab); _sort_list_on_update = false; } @@ -2153,8 +2157,10 @@ void ScriptEditor::_update_script_names() { } if (tab_container->get_current_tab() == sedata_filtered[i].index) { script_list->select(index); + script_name_label->set_text(sedata_filtered[i].name); script_icon->set_texture(sedata_filtered[i].icon); + ScriptEditorBase *se = _get_current_editor(); if (se) { se->enable_editor(); @@ -3264,7 +3270,7 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) { p_layout->set_value("ScriptEditor", "list_split_offset", list_split->get_split_offset()); // Save the cache. - script_editor_cache->save(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("script_editor_cache.cfg")); + script_editor_cache->save(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("script_editor_cache.cfg")); } void ScriptEditor::_help_class_open(const String &p_class) { @@ -3645,7 +3651,7 @@ ScriptEditor::ScriptEditor() { current_theme = ""; script_editor_cache.instantiate(); - script_editor_cache->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("script_editor_cache.cfg")); + script_editor_cache->load(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("script_editor_cache.cfg")); completion_cache = memnew(EditorScriptCodeCompletionCache); restoring_layout = false; @@ -3685,7 +3691,7 @@ ScriptEditor::ScriptEditor() { script_list->set_v_size_flags(SIZE_EXPAND_FILL); script_split->set_split_offset(70 * EDSCALE); _sort_list_on_update = true; - script_list->connect("gui_input", callable_mp(this, &ScriptEditor::_script_list_gui_input), varray(), CONNECT_DEFERRED); + script_list->connect("gui_input", callable_mp(this, &ScriptEditor::_script_list_gui_input), CONNECT_DEFERRED); script_list->set_allow_rmb_select(true); script_list->set_drag_forwarding(this); @@ -3853,14 +3859,14 @@ ScriptEditor::ScriptEditor() { site_search = memnew(Button); site_search->set_flat(true); site_search->set_text(TTR("Online Docs")); - site_search->connect("pressed", callable_mp(this, &ScriptEditor::_menu_option), varray(SEARCH_WEBSITE)); + site_search->connect("pressed", callable_mp(this, &ScriptEditor::_menu_option).bind(SEARCH_WEBSITE)); menu_hb->add_child(site_search); site_search->set_tooltip(TTR("Open Godot online documentation.")); help_search = memnew(Button); help_search->set_flat(true); help_search->set_text(TTR("Search Help")); - help_search->connect("pressed", callable_mp(this, &ScriptEditor::_menu_option), varray(SEARCH_HELP)); + help_search->connect("pressed", callable_mp(this, &ScriptEditor::_menu_option).bind(SEARCH_HELP)); menu_hb->add_child(help_search); help_search->set_tooltip(TTR("Search the reference documentation.")); @@ -3885,7 +3891,7 @@ ScriptEditor::ScriptEditor() { erase_tab_confirm = memnew(ConfirmationDialog); erase_tab_confirm->set_ok_button_text(TTR("Save")); erase_tab_confirm->add_button(TTR("Discard"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard"); - erase_tab_confirm->connect("confirmed", callable_mp(this, &ScriptEditor::_close_current_tab), varray(true)); + erase_tab_confirm->connect("confirmed", callable_mp(this, &ScriptEditor::_close_current_tab).bind(true)); erase_tab_confirm->connect("custom_action", callable_mp(this, &ScriptEditor::_close_discard_current_tab)); add_child(erase_tab_confirm); @@ -3939,8 +3945,8 @@ ScriptEditor::ScriptEditor() { help_search_dialog->connect("go_to_help", callable_mp(this, &ScriptEditor::_help_class_goto)); find_in_files_dialog = memnew(FindInFilesDialog); - find_in_files_dialog->connect(FindInFilesDialog::SIGNAL_FIND_REQUESTED, callable_mp(this, &ScriptEditor::_start_find_in_files), varray(false)); - find_in_files_dialog->connect(FindInFilesDialog::SIGNAL_REPLACE_REQUESTED, callable_mp(this, &ScriptEditor::_start_find_in_files), varray(true)); + find_in_files_dialog->connect(FindInFilesDialog::SIGNAL_FIND_REQUESTED, callable_mp(this, &ScriptEditor::_start_find_in_files).bind(false)); + find_in_files_dialog->connect(FindInFilesDialog::SIGNAL_REPLACE_REQUESTED, callable_mp(this, &ScriptEditor::_start_find_in_files).bind(true)); add_child(find_in_files_dialog); find_in_files = memnew(FindInFilesPanel); find_in_files_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Search Results"), find_in_files); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 14e3eb5402..5d5f452390 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1456,7 +1456,7 @@ void ScriptTextEditor::clear_breakpoints() { void ScriptTextEditor::set_tooltip_request_func(const Callable &p_toolip_callback) { Variant args[1] = { this }; const Variant *argp[] = { &args[0] }; - code_editor->get_text_editor()->set_tooltip_request_func(p_toolip_callback.bind(argp, 1)); + code_editor->get_text_editor()->set_tooltip_request_func(p_toolip_callback.bindp(argp, 1)); } void ScriptTextEditor::set_debugger_active(bool p_active) { @@ -1862,7 +1862,7 @@ void ScriptTextEditor::_enable_code_editor() { color_picker = memnew(ColorPicker); color_picker->set_deferred_mode(true); color_picker->connect("color_changed", callable_mp(this, &ScriptTextEditor::_color_changed)); - color_panel->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(color_picker)); + color_panel->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(color_picker)); color_panel->add_child(color_picker); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index bdf566e991..e700412188 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -41,7 +41,6 @@ #include "editor/filesystem_dock.h" #include "editor/plugins/visual_shader_editor_plugin.h" #include "editor/project_settings_editor.h" -#include "editor/property_editor.h" #include "editor/shader_create_dialog.h" #include "scene/gui/split_container.h" #include "servers/display_server.h" @@ -309,9 +308,9 @@ void ShaderTextEditor::_check_shader_mode() { } } -static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { - RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); - return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt); +static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) { + RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(p_variable); + return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); } static String complete_from_path; @@ -358,7 +357,7 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptLa ShaderLanguage sl; String calltip; ShaderLanguage::ShaderCompileInfo info; - info.global_variable_type_func = _get_global_variable_type; + info.global_shader_uniform_type_func = _get_global_shader_uniform_type; if (shader.is_null()) { info.is_include = true; @@ -448,7 +447,7 @@ void ShaderTextEditor::_validate_script() { sl.set_warning_flags(flags); ShaderLanguage::ShaderCompileInfo info; - info.global_variable_type_func = _get_global_variable_type; + info.global_shader_uniform_type_func = _get_global_shader_uniform_type; if (shader.is_null()) { info.is_include = true; @@ -831,18 +830,18 @@ void ShaderEditor::save_external_data(const String &p_str) { Ref<Shader> edited_shader = shader_editor->get_edited_shader(); if (edited_shader.is_valid()) { - ResourceSaver::save(edited_shader->get_path(), edited_shader); + ResourceSaver::save(edited_shader); } if (shader.is_valid() && shader != edited_shader) { - ResourceSaver::save(shader->get_path(), shader); + ResourceSaver::save(shader); } Ref<ShaderInclude> edited_shader_inc = shader_editor->get_edited_shader_include(); if (edited_shader_inc.is_valid()) { - ResourceSaver::save(edited_shader_inc->get_path(), edited_shader_inc); + ResourceSaver::save(edited_shader_inc); } if (shader_inc.is_valid() && shader_inc != edited_shader_inc) { - ResourceSaver::save(shader_inc->get_path(), shader_inc); + ResourceSaver::save(shader_inc); } disk_changed->hide(); @@ -1424,7 +1423,7 @@ ShaderEditorPlugin::ShaderEditorPlugin() { button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Shader Editor"), main_split); // Defer connect because Editor class is not in the binding system yet. - EditorNode::get_singleton()->call_deferred("connect", "resource_saved", callable_mp(this, &ShaderEditorPlugin::_resource_saved), varray(), CONNECT_DEFERRED); + EditorNode::get_singleton()->call_deferred("connect", "resource_saved", callable_mp(this, &ShaderEditorPlugin::_resource_saved), CONNECT_DEFERRED); shader_create_dialog = memnew(ShaderCreateDialog); vb->add_child(shader_create_dialog); diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp index 4458555de2..4874944d33 100644 --- a/editor/plugins/shader_file_editor_plugin.cpp +++ b/editor/plugins/shader_file_editor_plugin.cpp @@ -37,7 +37,6 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" -#include "editor/property_editor.h" #include "servers/display_server.h" #include "servers/rendering/shader_types.h" @@ -282,7 +281,7 @@ ShaderFileEditor::ShaderFileEditor() { stage_hb->add_child(button); stages[i] = button; button->set_button_group(bg); - button->connect("pressed", callable_mp(this, &ShaderFileEditor::_version_selected), varray(i)); + button->connect("pressed", callable_mp(this, &ShaderFileEditor::_version_selected).bind(i)); } error_text = memnew(RichTextLabel); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 93e44c8ca0..c453ed26aa 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -157,7 +157,7 @@ void BoneTransformEditor::_property_keyed(const String &p_path, bool p_advance) if (split.size() == 3 && split[0] == "bones") { int bone_idx = split[1].to_int(); if (split[2] == "position") { - te->insert_transform_key(skeleton, skeleton->get_bone_name(bone_idx), Animation::TYPE_POSITION_3D, skeleton->get(p_path)); + te->insert_transform_key(skeleton, skeleton->get_bone_name(bone_idx), Animation::TYPE_POSITION_3D, (Vector3)skeleton->get(p_path) / skeleton->get_motion_scale()); } if (split[2] == "rotation") { te->insert_transform_key(skeleton, skeleton->get_bone_name(bone_idx), Animation::TYPE_ROTATION_3D, skeleton->get(p_path)); @@ -319,7 +319,7 @@ void Skeleton3DEditor::insert_keys(const bool p_all_bones) { } if (pos_enabled && (p_all_bones || te->has_track(skeleton, name, Animation::TYPE_POSITION_3D))) { - te->insert_transform_key(skeleton, name, Animation::TYPE_POSITION_3D, skeleton->get_bone_pose_position(i)); + te->insert_transform_key(skeleton, name, Animation::TYPE_POSITION_3D, skeleton->get_bone_pose_position(i) / skeleton->get_motion_scale()); } if (rot_enabled && (p_all_bones || te->has_track(skeleton, name, Animation::TYPE_ROTATION_3D))) { te->insert_transform_key(skeleton, name, Animation::TYPE_ROTATION_3D, skeleton->get_bone_pose_rotation(i)); @@ -515,7 +515,7 @@ void Skeleton3DEditor::_file_selected(const String &p_file) { } } - Error err = ResourceSaver::save(p_file, sp); + Error err = ResourceSaver::save(sp, p_file); if (err != OK) { EditorNode::get_singleton()->show_warning(vformat(TTR("Error saving file: %s"), p_file)); @@ -782,7 +782,7 @@ void Skeleton3DEditor::create_editors() { key_insert_button = memnew(Button); key_insert_button->set_flat(true); key_insert_button->set_focus_mode(FOCUS_NONE); - key_insert_button->connect("pressed", callable_mp(this, &Skeleton3DEditor::insert_keys), varray(false)); + key_insert_button->connect("pressed", callable_mp(this, &Skeleton3DEditor::insert_keys).bind(false)); key_insert_button->set_tooltip(TTR("Insert key of bone poses already exist track.")); key_insert_button->set_shortcut(ED_SHORTCUT("skeleton_3d_editor/insert_key_to_existing_tracks", TTR("Insert Key (Existing Tracks)"), Key::INSERT)); animation_hb->add_child(key_insert_button); @@ -790,7 +790,7 @@ void Skeleton3DEditor::create_editors() { key_insert_all_button = memnew(Button); key_insert_all_button->set_flat(true); key_insert_all_button->set_focus_mode(FOCUS_NONE); - key_insert_all_button->connect("pressed", callable_mp(this, &Skeleton3DEditor::insert_keys), varray(true)); + key_insert_all_button->connect("pressed", callable_mp(this, &Skeleton3DEditor::insert_keys).bind(true)); key_insert_all_button->set_tooltip(TTR("Insert key of all bone poses.")); key_insert_all_button->set_shortcut(ED_SHORTCUT("skeleton_3d_editor/insert_key_of_all_bones", TTR("Insert Key (All Bones)"), KeyModifierMask::CMD + Key::INSERT)); animation_hb->add_child(key_insert_all_button); @@ -836,7 +836,7 @@ void Skeleton3DEditor::_notification(int p_what) { key_scale_button->set_icon(get_theme_icon(SNAME("KeyScale"), SNAME("EditorIcons"))); key_insert_button->set_icon(get_theme_icon(SNAME("Key"), SNAME("EditorIcons"))); key_insert_all_button->set_icon(get_theme_icon(SNAME("NewKey"), SNAME("EditorIcons"))); - get_tree()->connect("node_removed", callable_mp(this, &Skeleton3DEditor::_node_removed), Vector<Variant>(), Object::CONNECT_ONESHOT); + get_tree()->connect("node_removed", callable_mp(this, &Skeleton3DEditor::_node_removed), Object::CONNECT_ONESHOT); break; } case NOTIFICATION_ENTER_TREE: { @@ -921,8 +921,8 @@ void fragment() { )"); handle_material->set_shader(handle_shader); Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("EditorBoneHandle"), SNAME("EditorIcons")); - handle_material->set_shader_param("point_size", handle->get_width()); - handle_material->set_shader_param("texture_albedo", handle); + handle_material->set_shader_uniform("point_size", handle->get_width()); + handle_material->set_shader_uniform("texture_albedo", handle); handles_mesh_instance = memnew(MeshInstance3D); handles_mesh_instance->set_cast_shadows_setting(GeometryInstance3D::SHADOW_CASTING_SETTING_OFF); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 0b6c0a9f0c..a39d24a167 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -1306,7 +1306,7 @@ SpriteFramesEditor::SpriteFramesEditor() { empty2->connect("pressed", callable_mp(this, &SpriteFramesEditor::_empty2_pressed)); move_up->connect("pressed", callable_mp(this, &SpriteFramesEditor::_up_pressed)); move_down->connect("pressed", callable_mp(this, &SpriteFramesEditor::_down_pressed)); - file->connect("files_selected", callable_mp(this, &SpriteFramesEditor::_file_load_request), make_binds(-1)); + file->connect("files_selected", callable_mp(this, &SpriteFramesEditor::_file_load_request).bind(-1)); loading_scene = false; sel = -1; @@ -1333,7 +1333,7 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_h->set_max(128); split_sheet_h->set_step(1); split_sheet_hb->add_child(split_sheet_h); - split_sheet_h->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed), varray(PARAM_FRAME_COUNT)); + split_sheet_h->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT)); split_sheet_hb->add_child(memnew(Label(TTR("Vertical:")))); split_sheet_v = memnew(SpinBox); @@ -1341,7 +1341,7 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_v->set_max(128); split_sheet_v->set_step(1); split_sheet_hb->add_child(split_sheet_v); - split_sheet_v->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed), varray(PARAM_FRAME_COUNT)); + split_sheet_v->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT)); split_sheet_hb->add_child(memnew(VSeparator)); split_sheet_hb->add_child(memnew(Label(TTR("Size:")))); @@ -1349,13 +1349,13 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_size_x->set_min(1); split_sheet_size_x->set_step(1); split_sheet_size_x->set_suffix("px"); - split_sheet_size_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed), varray(PARAM_SIZE)); + split_sheet_size_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE)); split_sheet_hb->add_child(split_sheet_size_x); split_sheet_size_y = memnew(SpinBox); split_sheet_size_y->set_min(1); split_sheet_size_y->set_step(1); split_sheet_size_y->set_suffix("px"); - split_sheet_size_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed), varray(PARAM_SIZE)); + split_sheet_size_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE)); split_sheet_hb->add_child(split_sheet_size_y); split_sheet_hb->add_child(memnew(VSeparator)); @@ -1364,13 +1364,13 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_sep_x->set_min(0); split_sheet_sep_x->set_step(1); split_sheet_sep_x->set_suffix("px"); - split_sheet_sep_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed), varray(PARAM_USE_CURRENT)); + split_sheet_sep_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); split_sheet_hb->add_child(split_sheet_sep_x); split_sheet_sep_y = memnew(SpinBox); split_sheet_sep_y->set_min(0); split_sheet_sep_y->set_step(1); split_sheet_sep_y->set_suffix("px"); - split_sheet_sep_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed), varray(PARAM_USE_CURRENT)); + split_sheet_sep_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); split_sheet_hb->add_child(split_sheet_sep_y); split_sheet_hb->add_child(memnew(VSeparator)); @@ -1379,13 +1379,13 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_offset_x->set_min(0); split_sheet_offset_x->set_step(1); split_sheet_offset_x->set_suffix("px"); - split_sheet_offset_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed), varray(PARAM_USE_CURRENT)); + split_sheet_offset_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); split_sheet_hb->add_child(split_sheet_offset_x); split_sheet_offset_y = memnew(SpinBox); split_sheet_offset_y->set_min(0); split_sheet_offset_y->set_step(1); split_sheet_offset_y->set_suffix("px"); - split_sheet_offset_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed), varray(PARAM_USE_CURRENT)); + split_sheet_offset_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); split_sheet_hb->add_child(split_sheet_offset_y); split_sheet_hb->add_spacer(); diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 84caede081..196d87da36 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -32,6 +32,7 @@ #include "core/os/keyboard.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" void TextEditor::add_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) { ERR_FAIL_COND(p_highlighter.is_null()); @@ -275,7 +276,7 @@ void TextEditor::update_settings() { void TextEditor::set_tooltip_request_func(const Callable &p_toolip_callback) { Variant args[1] = { this }; const Variant *argp[] = { &args[0] }; - code_editor->get_text_editor()->set_tooltip_request_func(p_toolip_callback.bind(argp, 1)); + code_editor->get_text_editor()->set_tooltip_request_func(p_toolip_callback.bindp(argp, 1)); } Control *TextEditor::get_edit_menu() { diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index 0fc7079a24..64cafa17f3 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -57,8 +57,8 @@ void Texture3DEditor::_texture_changed() { } void Texture3DEditor::_update_material() { - material->set_shader_param("layer", (layer->get_value() + 0.5) / texture->get_depth()); - material->set_shader_param("tex", texture->get_rid()); + material->set_shader_uniform("layer", (layer->get_value() + 0.5) / texture->get_depth()); + material->set_shader_uniform("tex", texture->get_rid()); String format = Image::get_format_name(texture->get_format()); diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index cb146fd342..2c6f70463d 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -68,9 +68,9 @@ void TextureLayeredEditor::_texture_changed() { } void TextureLayeredEditor::_update_material() { - materials[0]->set_shader_param("layer", layer->get_value()); - materials[2]->set_shader_param("layer", layer->get_value()); - materials[texture->get_layered_type()]->set_shader_param("tex", texture->get_rid()); + materials[0]->set_shader_uniform("layer", layer->get_value()); + materials[2]->set_shader_uniform("layer", layer->get_value()); + materials[texture->get_layered_type()]->set_shader_uniform("tex", texture->get_rid()); Vector3 v(1, 1, 1); v.normalize(); @@ -79,10 +79,10 @@ void TextureLayeredEditor::_update_material() { b.rotate(Vector3(1, 0, 0), x_rot); b.rotate(Vector3(0, 1, 0), y_rot); - materials[1]->set_shader_param("normal", v); - materials[1]->set_shader_param("rot", b); - materials[2]->set_shader_param("normal", v); - materials[2]->set_shader_param("rot", b); + materials[1]->set_shader_uniform("normal", v); + materials[1]->set_shader_uniform("rot", b); + materials[2]->set_shader_uniform("normal", v); + materials[2]->set_shader_uniform("rot", b); String format = Image::get_format_name(texture->get_format()); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index dd98247428..0bd8a8a484 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -35,7 +35,9 @@ #include "core/os/keyboard.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/gui/check_box.h" +#include "scene/gui/separator.h" #include "scene/gui/view_panner.h" #include "scene/resources/texture.h" @@ -239,7 +241,7 @@ void TextureRegionEditor::_region_draw() { hscroll->set_value((hscroll->get_min() + hscroll->get_max() - hscroll->get_page()) / 2); vscroll->set_value((vscroll->get_min() + vscroll->get_max() - vscroll->get_page()) / 2); // This ensures that the view is updated correctly. - callable_bind(callable_mp(this, &TextureRegionEditor::_pan_callback), Vector2(1, 0)).call_deferred(nullptr, 0); + callable_mp(this, &TextureRegionEditor::_pan_callback).bind(Vector2(1, 0)).call_deferredp(nullptr, 0); request_center = false; } @@ -1153,7 +1155,7 @@ bool EditorInspectorPluginTextureRegion::parse_property(Object *p_object, const if (((Object::cast_to<Sprite2D>(p_object) || Object::cast_to<Sprite3D>(p_object) || Object::cast_to<NinePatchRect>(p_object) || Object::cast_to<StyleBoxTexture>(p_object)) && p_path == "region_rect") || (Object::cast_to<AtlasTexture>(p_object) && p_path == "region")) { Button *button = EditorInspector::create_inspector_action_button(TTR("Edit Region")); button->set_icon(texture_region_editor->get_theme_icon(SNAME("RegionEdit"), SNAME("EditorIcons"))); - button->connect("pressed", callable_mp(this, &EditorInspectorPluginTextureRegion::_region_edit), varray(p_object)); + button->connect("pressed", callable_mp(this, &EditorInspectorPluginTextureRegion::_region_edit).bind(p_object)); add_property_editor(p_path, button, true); } } diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 744ed1f1a2..bbc22c8622 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -36,6 +36,7 @@ #include "editor/editor_resource_picker.h" #include "editor/editor_scale.h" #include "editor/progress_dialog.h" +#include "scene/gui/color_picker.h" void ThemeItemImportTree::_update_items_tree() { import_items_tree->clear(); @@ -1103,15 +1104,15 @@ ThemeItemImportTree::ThemeItemImportTree() { select_all_items_button->set_flat(true); select_all_items_button->set_tooltip(select_all_items_tooltip); button_set->add_child(select_all_items_button); - select_all_items_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_select_all_data_type_pressed), varray(i)); + select_all_items_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_select_all_data_type_pressed).bind(i)); select_full_items_button->set_flat(true); select_full_items_button->set_tooltip(select_full_items_tooltip); button_set->add_child(select_full_items_button); - select_full_items_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_select_full_data_type_pressed), varray(i)); + select_full_items_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_select_full_data_type_pressed).bind(i)); deselect_all_items_button->set_flat(true); deselect_all_items_button->set_tooltip(deselect_all_items_tooltip); button_set->add_child(deselect_all_items_button); - deselect_all_items_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_deselect_all_data_type_pressed), varray(i)); + deselect_all_items_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_deselect_all_data_type_pressed).bind(i)); total_selected_items_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); total_selected_items_label->hide(); @@ -1142,12 +1143,12 @@ ThemeItemImportTree::ThemeItemImportTree() { import_collapse_types_button->set_flat(true); import_collapse_types_button->set_tooltip(TTR("Collapse types.")); import_buttons->add_child(import_collapse_types_button); - import_collapse_types_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_toggle_type_items), varray(true)); + import_collapse_types_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_toggle_type_items).bind(true)); import_expand_types_button = memnew(Button); import_expand_types_button->set_flat(true); import_expand_types_button->set_tooltip(TTR("Expand types.")); import_buttons->add_child(import_expand_types_button); - import_expand_types_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_toggle_type_items), varray(false)); + import_expand_types_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_toggle_type_items).bind(false)); import_buttons->add_child(memnew(VSeparator)); @@ -1938,7 +1939,7 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito edit_add_type_hb->add_child(edit_add_type_value); edit_add_type_button = memnew(Button); edit_add_type_hb->add_child(edit_add_type_button); - edit_add_type_button->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_add_theme_type), varray("")); + edit_add_type_button->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_add_theme_type).bind("")); VBoxContainer *edit_items_vb = memnew(VBoxContainer); edit_items_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL); @@ -1956,42 +1957,42 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito edit_items_add_color->set_flat(true); edit_items_add_color->set_disabled(true); edit_items_toolbar->add_child(edit_items_add_color); - edit_items_add_color->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog), varray(Theme::DATA_TYPE_COLOR)); + edit_items_add_color->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog).bind(Theme::DATA_TYPE_COLOR)); edit_items_add_constant = memnew(Button); edit_items_add_constant->set_tooltip(TTR("Add Constant Item")); edit_items_add_constant->set_flat(true); edit_items_add_constant->set_disabled(true); edit_items_toolbar->add_child(edit_items_add_constant); - edit_items_add_constant->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog), varray(Theme::DATA_TYPE_CONSTANT)); + edit_items_add_constant->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog).bind(Theme::DATA_TYPE_CONSTANT)); edit_items_add_font = memnew(Button); edit_items_add_font->set_tooltip(TTR("Add Font Item")); edit_items_add_font->set_flat(true); edit_items_add_font->set_disabled(true); edit_items_toolbar->add_child(edit_items_add_font); - edit_items_add_font->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog), varray(Theme::DATA_TYPE_FONT)); + edit_items_add_font->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog).bind(Theme::DATA_TYPE_FONT)); edit_items_add_font_size = memnew(Button); edit_items_add_font_size->set_tooltip(TTR("Add Font Size Item")); edit_items_add_font_size->set_flat(true); edit_items_add_font_size->set_disabled(true); edit_items_toolbar->add_child(edit_items_add_font_size); - edit_items_add_font_size->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog), varray(Theme::DATA_TYPE_FONT_SIZE)); + edit_items_add_font_size->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog).bind(Theme::DATA_TYPE_FONT_SIZE)); edit_items_add_icon = memnew(Button); edit_items_add_icon->set_tooltip(TTR("Add Icon Item")); edit_items_add_icon->set_flat(true); edit_items_add_icon->set_disabled(true); edit_items_toolbar->add_child(edit_items_add_icon); - edit_items_add_icon->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog), varray(Theme::DATA_TYPE_ICON)); + edit_items_add_icon->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog).bind(Theme::DATA_TYPE_ICON)); edit_items_add_stylebox = memnew(Button); edit_items_add_stylebox->set_tooltip(TTR("Add StyleBox Item")); edit_items_add_stylebox->set_flat(true); edit_items_add_stylebox->set_disabled(true); edit_items_toolbar->add_child(edit_items_add_stylebox); - edit_items_add_stylebox->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog), varray(Theme::DATA_TYPE_STYLEBOX)); + edit_items_add_stylebox->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_open_add_theme_item_dialog).bind(Theme::DATA_TYPE_STYLEBOX)); edit_items_toolbar->add_child(memnew(VSeparator)); @@ -2271,11 +2272,11 @@ VBoxContainer *ThemeTypeEditor::_create_item_list(Theme::DataType p_data_type) { LineEdit *item_add_edit = memnew(LineEdit); item_add_edit->set_h_size_flags(SIZE_EXPAND_FILL); item_add_hb->add_child(item_add_edit); - item_add_edit->connect("text_submitted", callable_mp(this, &ThemeTypeEditor::_item_add_lineedit_cbk), varray(p_data_type, item_add_edit)); + item_add_edit->connect("text_submitted", callable_mp(this, &ThemeTypeEditor::_item_add_lineedit_cbk).bind(p_data_type, item_add_edit)); Button *item_add_button = memnew(Button); item_add_button->set_text(TTR("Add")); item_add_hb->add_child(item_add_button); - item_add_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_add_cbk), varray(p_data_type, item_add_edit)); + item_add_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_add_cbk).bind(p_data_type, item_add_edit)); return items_list; } @@ -2418,7 +2419,7 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_ item_name_edit->set_h_size_flags(SIZE_EXPAND_FILL); item_name_edit->set_text(p_item_name); item_name_container->add_child(item_name_edit); - item_name_edit->connect("text_submitted", callable_mp(this, &ThemeTypeEditor::_item_rename_entered), varray(p_data_type, p_item_name, item_name_container)); + item_name_edit->connect("text_submitted", callable_mp(this, &ThemeTypeEditor::_item_rename_entered).bind(p_data_type, p_item_name, item_name_container)); item_name_edit->hide(); Button *item_rename_button = memnew(Button); @@ -2426,21 +2427,21 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_ item_rename_button->set_tooltip(TTR("Rename Item")); item_rename_button->set_flat(true); item_name_container->add_child(item_rename_button); - item_rename_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_rename_cbk), varray(p_data_type, p_item_name, item_name_container)); + item_rename_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_rename_cbk).bind(p_data_type, p_item_name, item_name_container)); Button *item_remove_button = memnew(Button); item_remove_button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); item_remove_button->set_tooltip(TTR("Remove Item")); item_remove_button->set_flat(true); item_name_container->add_child(item_remove_button); - item_remove_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_remove_cbk), varray(p_data_type, p_item_name)); + item_remove_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_remove_cbk).bind(p_data_type, p_item_name)); Button *item_rename_confirm_button = memnew(Button); item_rename_confirm_button->set_icon(get_theme_icon(SNAME("ImportCheck"), SNAME("EditorIcons"))); item_rename_confirm_button->set_tooltip(TTR("Confirm Item Rename")); item_rename_confirm_button->set_flat(true); item_name_container->add_child(item_rename_confirm_button); - item_rename_confirm_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_rename_confirmed), varray(p_data_type, p_item_name, item_name_container)); + item_rename_confirm_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_rename_confirmed).bind(p_data_type, p_item_name, item_name_container)); item_rename_confirm_button->hide(); Button *item_rename_cancel_button = memnew(Button); @@ -2448,7 +2449,7 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_ item_rename_cancel_button->set_tooltip(TTR("Cancel Item Rename")); item_rename_cancel_button->set_flat(true); item_name_container->add_child(item_rename_cancel_button); - item_rename_cancel_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_rename_canceled), varray(p_data_type, p_item_name, item_name_container)); + item_rename_cancel_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_rename_canceled).bind(p_data_type, p_item_name, item_name_container)); item_rename_cancel_button->hide(); } else { item_name->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); @@ -2458,7 +2459,7 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_ item_override_button->set_tooltip(TTR("Override Item")); item_override_button->set_flat(true); item_name_container->add_child(item_override_button); - item_override_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_override_cbk), varray(p_data_type, p_item_name)); + item_override_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_override_cbk).bind(p_data_type, p_item_name)); } return item_control; @@ -2491,8 +2492,8 @@ void ThemeTypeEditor::_update_type_items() { if (E.value) { item_editor->set_pick_color(edited_theme->get_color(E.key, edited_type)); - item_editor->connect("color_changed", callable_mp(this, &ThemeTypeEditor::_color_item_changed), varray(E.key)); - item_editor->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(item_editor->get_picker())); + item_editor->connect("color_changed", callable_mp(this, &ThemeTypeEditor::_color_item_changed).bind(E.key)); + item_editor->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(item_editor->get_picker())); } else { item_editor->set_pick_color(Theme::get_default()->get_color(E.key, edited_type)); item_editor->set_disabled(true); @@ -2525,7 +2526,7 @@ void ThemeTypeEditor::_update_type_items() { if (E.value) { item_editor->set_value(edited_theme->get_constant(E.key, edited_type)); - item_editor->connect("value_changed", callable_mp(this, &ThemeTypeEditor::_constant_item_changed), varray(E.key)); + item_editor->connect("value_changed", callable_mp(this, &ThemeTypeEditor::_constant_item_changed).bind(E.key)); } else { item_editor->set_value(Theme::get_default()->get_constant(E.key, edited_type)); item_editor->set_editable(false); @@ -2559,7 +2560,7 @@ void ThemeTypeEditor::_update_type_items() { item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); - item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_font_item_changed), varray(E.key)); + item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_font_item_changed).bind(E.key)); } else { if (Theme::get_default()->has_font(E.key, edited_type)) { item_editor->set_edited_resource(Theme::get_default()->get_font(E.key, edited_type)); @@ -2596,7 +2597,7 @@ void ThemeTypeEditor::_update_type_items() { if (E.value) { item_editor->set_value(edited_theme->get_font_size(E.key, edited_type)); - item_editor->connect("value_changed", callable_mp(this, &ThemeTypeEditor::_font_size_item_changed), varray(E.key)); + item_editor->connect("value_changed", callable_mp(this, &ThemeTypeEditor::_font_size_item_changed).bind(E.key)); } else { item_editor->set_value(Theme::get_default()->get_font_size(E.key, edited_type)); item_editor->set_editable(false); @@ -2630,7 +2631,7 @@ void ThemeTypeEditor::_update_type_items() { item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); - item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_icon_item_changed), varray(E.key)); + item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_icon_item_changed).bind(E.key)); } else { if (Theme::get_default()->has_icon(E.key, edited_type)) { item_editor->set_edited_resource(Theme::get_default()->get_icon(E.key, edited_type)); @@ -2677,7 +2678,7 @@ void ThemeTypeEditor::_update_type_items() { item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); - item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_stylebox_item_changed), varray(leading_stylebox.item_name)); + item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_stylebox_item_changed).bind(leading_stylebox.item_name)); stylebox_items_list->add_child(item_control); stylebox_items_list->add_child(memnew(HSeparator)); @@ -2702,7 +2703,7 @@ void ThemeTypeEditor::_update_type_items() { item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); - item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_stylebox_item_changed), varray(E.key)); + item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_stylebox_item_changed).bind(E.key)); Button *pin_leader_button = memnew(Button); pin_leader_button->set_flat(true); @@ -2710,7 +2711,7 @@ void ThemeTypeEditor::_update_type_items() { pin_leader_button->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons"))); pin_leader_button->set_tooltip(TTR("Pin this StyleBox as a main style. Editing its properties will update the same properties in all other StyleBoxes of this type.")); item_control->add_child(pin_leader_button); - pin_leader_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_on_pin_leader_button_pressed), varray(item_editor, E.key)); + pin_leader_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_on_pin_leader_button_pressed).bind(item_editor, E.key)); } else { if (Theme::get_default()->has_stylebox(E.key, edited_type)) { item_editor->set_edited_resource(Theme::get_default()->get_stylebox(E.key, edited_type)); @@ -3380,6 +3381,7 @@ ThemeTypeEditor::ThemeTypeEditor() { theme_type_list = memnew(OptionButton); theme_type_list->set_h_size_flags(SIZE_EXPAND_FILL); + theme_type_list->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); type_list_hb->add_child(theme_type_list); theme_type_list->connect("item_selected", callable_mp(this, &ThemeTypeEditor::_list_type_selected)); @@ -3522,8 +3524,8 @@ void ThemeEditor::_preview_scene_dialog_cbk(const String &p_path) { } _add_preview_tab(preview_tab, p_path.get_file(), get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"))); - preview_tab->connect("scene_invalidated", callable_mp(this, &ThemeEditor::_remove_preview_tab_invalid), varray(preview_tab)); - preview_tab->connect("scene_reloaded", callable_mp(this, &ThemeEditor::_update_preview_tab), varray(preview_tab)); + preview_tab->connect("scene_invalidated", callable_mp(this, &ThemeEditor::_remove_preview_tab_invalid).bind(preview_tab)); + preview_tab->connect("scene_reloaded", callable_mp(this, &ThemeEditor::_update_preview_tab).bind(preview_tab)); } void ThemeEditor::_add_preview_tab(ThemeEditorPreview *p_preview_tab, const String &p_preview_name, const Ref<Texture2D> &p_icon) { @@ -3617,13 +3619,13 @@ ThemeEditor::ThemeEditor() { Button *theme_save_button = memnew(Button); theme_save_button->set_text(TTR("Save")); theme_save_button->set_flat(true); - theme_save_button->connect("pressed", callable_mp(this, &ThemeEditor::_theme_save_button_cbk), varray(false)); + theme_save_button->connect("pressed", callable_mp(this, &ThemeEditor::_theme_save_button_cbk).bind(false)); top_menu->add_child(theme_save_button); Button *theme_save_as_button = memnew(Button); theme_save_as_button->set_text(TTR("Save As...")); theme_save_as_button->set_flat(true); - theme_save_as_button->connect("pressed", callable_mp(this, &ThemeEditor::_theme_save_button_cbk), varray(true)); + theme_save_as_button->connect("pressed", callable_mp(this, &ThemeEditor::_theme_save_button_cbk).bind(true)); top_menu->add_child(theme_save_as_button); top_menu->add_child(memnew(VSeparator)); diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp index 0c7303dda4..b5c6c6d651 100644 --- a/editor/plugins/theme_editor_preview.cpp +++ b/editor/plugins/theme_editor_preview.cpp @@ -36,6 +36,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "scene/gui/button.h" +#include "scene/gui/check_button.h" #include "scene/gui/color_picker.h" #include "scene/gui/progress_bar.h" #include "scene/resources/packed_scene.h" diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 69a3d4e937..1bf24a7393 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -2198,7 +2198,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_fix_selected_and_hovered).unbind(1)); sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_source_display).unbind(1)); sources_list->connect("item_selected", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_sources_lists_current)); - sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list, source_sort_button)); + sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list).bind(sources_list, source_sort_button)); sources_list->add_user_signal(MethodInfo("sort_request")); sources_list->connect("sort_request", callable_mp(this, &TileMapEditorTilesPlugin::_update_tile_set_sources_list)); split_container_left_side->add_child(sources_list); diff --git a/editor/plugins/tiles/tile_proxies_manager_dialog.cpp b/editor/plugins/tiles/tile_proxies_manager_dialog.cpp index 3fe13fd341..12e1615484 100644 --- a/editor/plugins/tiles/tile_proxies_manager_dialog.cpp +++ b/editor/plugins/tiles/tile_proxies_manager_dialog.cpp @@ -340,7 +340,7 @@ TileProxiesManagerDialog::TileProxiesManagerDialog() { source_level_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); source_level_list->set_select_mode(ItemList::SELECT_MULTI); source_level_list->set_allow_rmb_select(true); - source_level_list->connect("item_clicked", callable_mp(this, &TileProxiesManagerDialog::_right_clicked), varray(source_level_list)); + source_level_list->connect("item_clicked", callable_mp(this, &TileProxiesManagerDialog::_right_clicked).bind(source_level_list)); vbox_container->add_child(source_level_list); Label *coords_level_label = memnew(Label); @@ -351,7 +351,7 @@ TileProxiesManagerDialog::TileProxiesManagerDialog() { coords_level_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); coords_level_list->set_select_mode(ItemList::SELECT_MULTI); coords_level_list->set_allow_rmb_select(true); - coords_level_list->connect("item_clicked", callable_mp(this, &TileProxiesManagerDialog::_right_clicked), varray(coords_level_list)); + coords_level_list->connect("item_clicked", callable_mp(this, &TileProxiesManagerDialog::_right_clicked).bind(coords_level_list)); vbox_container->add_child(coords_level_list); Label *alternative_level_label = memnew(Label); @@ -362,7 +362,7 @@ TileProxiesManagerDialog::TileProxiesManagerDialog() { alternative_level_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); alternative_level_list->set_select_mode(ItemList::SELECT_MULTI); alternative_level_list->set_allow_rmb_select(true); - alternative_level_list->connect("item_clicked", callable_mp(this, &TileProxiesManagerDialog::_right_clicked), varray(alternative_level_list)); + alternative_level_list->connect("item_clicked", callable_mp(this, &TileProxiesManagerDialog::_right_clicked).bind(alternative_level_list)); vbox_container->add_child(alternative_level_list); popup_menu = memnew(PopupMenu); diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 20e548acba..6950f57a00 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -735,15 +735,15 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { // --- Custom Data --- ADD_TILE_DATA_EDITOR_GROUP("Custom Data"); for (int i = 0; i < tile_set->get_custom_data_layers_count(); i++) { - if (tile_set->get_custom_data_name(i).is_empty()) { + if (tile_set->get_custom_data_layer_name(i).is_empty()) { ADD_TILE_DATA_EDITOR(group, vformat("Custom Data %d", i), vformat("custom_data_%d", i)); } else { - ADD_TILE_DATA_EDITOR(group, tile_set->get_custom_data_name(i), vformat("custom_data_%d", i)); + ADD_TILE_DATA_EDITOR(group, tile_set->get_custom_data_layer_name(i), vformat("custom_data_%d", i)); } if (!tile_data_editors.has(vformat("custom_data_%d", i))) { TileDataDefaultEditor *tile_data_custom_data_editor = memnew(TileDataDefaultEditor()); tile_data_custom_data_editor->hide(); - tile_data_custom_data_editor->setup_property_editor(tile_set->get_custom_data_type(i), vformat("custom_data_%d", i), tile_set->get_custom_data_name(i)); + tile_data_custom_data_editor->setup_property_editor(tile_set->get_custom_data_layer_type(i), vformat("custom_data_%d", i), tile_set->get_custom_data_layer_name(i)); tile_data_custom_data_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); tile_data_custom_data_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); tile_data_editors[vformat("custom_data_%d", i)] = tile_data_custom_data_editor; @@ -913,7 +913,7 @@ void TileSetAtlasSourceEditor::_update_atlas_view() { button->add_theme_style_override("hover", memnew(StyleBoxEmpty)); button->add_theme_style_override("focus", memnew(StyleBoxEmpty)); button->add_theme_style_override("pressed", memnew(StyleBoxEmpty)); - button->connect("pressed", callable_mp(tile_set_atlas_source, &TileSetAtlasSource::create_alternative_tile), varray(tile_id, TileSetSource::INVALID_TILE_ALTERNATIVE)); + button->connect("pressed", callable_mp(tile_set_atlas_source, &TileSetAtlasSource::create_alternative_tile).bind(tile_id, TileSetSource::INVALID_TILE_ALTERNATIVE)); button->set_rect(Rect2(Vector2(pos.x, pos.y + (y_increment - texture_region_base_size.y) / 2.0), Vector2(texture_region_base_size_min, texture_region_base_size_min))); button->set_expand_icon(true); @@ -1822,7 +1822,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_unscaled_draw() { Vector2i position = texture_region.get_center() + tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); Transform2D xform = tile_atlas_control->get_parent_control()->get_transform(); - xform.translate(position); + xform.translate_local(position); if (tools_button_group->get_pressed_button() == tool_select_button && selection.has({ coords, 0 })) { continue; @@ -1845,7 +1845,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_unscaled_draw() { Vector2i position = texture_region.get_center() + tile_set_atlas_source->get_tile_effective_texture_offset(E.tile, 0); Transform2D xform = tile_atlas_control->get_parent_control()->get_transform(); - xform.translate(position); + xform.translate_local(position); TileMapCell cell; cell.source_id = tile_set_atlas_source_id; @@ -1886,6 +1886,12 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_gui_input(const Ref<In tile_atlas_control_unscaled->update(); alternative_tiles_control->update(); alternative_tiles_control_unscaled->update(); + + if (drag_type == DRAG_TYPE_MAY_POPUP_MENU) { + if (Vector2(drag_start_mouse_pos).distance_to(tile_atlas_control->get_local_mouse_position()) > 5.0 * EDSCALE) { + drag_type = DRAG_TYPE_NONE; + } + } } Ref<InputEventMouseButton> mb = p_event; @@ -1911,7 +1917,10 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_gui_input(const Ref<In } } else if (mb->get_button_index() == MouseButton::RIGHT) { if (mb->is_pressed()) { - // Right click pressed + drag_type = DRAG_TYPE_MAY_POPUP_MENU; + drag_start_mouse_pos = alternative_tiles_control->get_local_mouse_position(); + } else if (drag_type == DRAG_TYPE_MAY_POPUP_MENU) { + // Right click released and wasn't dragged too far Vector3 tile = tile_atlas_view->get_alternative_tile_at_pos(mouse_local_pos); selection.clear(); @@ -1989,7 +1998,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw() { Vector2 position = rect.get_center(); Transform2D xform = alternative_tiles_control->get_parent_control()->get_transform(); - xform.translate(position); + xform.translate_local(position); if (tools_button_group->get_pressed_button() == tool_select_button && selection.has({ coords, alternative_tile })) { continue; @@ -2013,7 +2022,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw() { Vector2 position = rect.get_center(); Transform2D xform = alternative_tiles_control->get_parent_control()->get_transform(); - xform.translate(position); + xform.translate_local(position); TileMapCell cell; cell.source_id = tile_set_atlas_source_id; diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index de373e121b..81804710b4 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -710,9 +710,9 @@ TileSetEditor::TileSetEditor() { sources_list->set_v_size_flags(SIZE_EXPAND_FILL); sources_list->connect("item_selected", callable_mp(this, &TileSetEditor::_source_selected)); sources_list->connect("item_selected", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_sources_lists_current)); - sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list, source_sort_button)); + sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list).bind(sources_list, source_sort_button)); sources_list->add_user_signal(MethodInfo("sort_request")); - sources_list->connect("sort_request", callable_mp(this, &TileSetEditor::_update_sources_list), varray(-1)); + sources_list->connect("sort_request", callable_mp(this, &TileSetEditor::_update_sources_list).bind(-1)); sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); sources_list->set_drag_forwarding(this); split_container_left_side->add_child(sources_list); diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index 97553578ba..b5134f6893 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -116,7 +116,7 @@ void TilesEditorPlugin::_thread() { // Add the viewport at the last moment to avoid rendering too early. EditorNode::get_singleton()->add_child(viewport); - RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_preview_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT); + RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_preview_frame_started), Object::CONNECT_ONESHOT); pattern_preview_done.wait(); @@ -127,7 +127,7 @@ void TilesEditorPlugin::_thread() { const Variant *args_ptr[] = { &args[0], &args[1] }; Variant r; Callable::CallError error; - item.callback.call(args_ptr, 2, r, error); + item.callback.callp(args_ptr, 2, r, error); viewport->queue_delete(); } else { @@ -155,6 +155,9 @@ void TilesEditorPlugin::_update_editors() { // Update the viewport. CanvasItemEditor::get_singleton()->update_viewport(); + // Make sure the tile set editor is visible if we have one assigned. + tileset_editor_button->set_visible(is_visible && tile_set.is_valid()); + // Update visibility of bottom panel buttons. if (tileset_editor_button->is_pressed() && !tile_set.is_valid()) { if (tile_map) { @@ -181,12 +184,14 @@ void TilesEditorPlugin::_notification(int p_what) { } void TilesEditorPlugin::make_visible(bool p_visible) { - if (p_visible) { + is_visible = p_visible; + + if (is_visible) { // Disable and hide invalid editors. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); tileset_editor_button->set_visible(tile_set.is_valid()); tilemap_editor_button->set_visible(tile_map); - if (tile_map) { + if (tile_map && !is_editing_tile_set) { EditorNode::get_singleton()->make_bottom_panel_item_visible(tilemap_editor); } else { EditorNode::get_singleton()->make_bottom_panel_item_visible(tileset_editor); @@ -345,6 +350,8 @@ void TilesEditorPlugin::edit(Object *p_object) { // Update edited objects. tile_set = Ref<TileSet>(); + is_editing_tile_set = false; + if (p_object) { if (p_object->is_class("TileMap")) { tile_map_id = p_object->get_instance_id(); @@ -359,6 +366,7 @@ void TilesEditorPlugin::edit(Object *p_object) { tile_map_id = ObjectID(); } } + is_editing_tile_set = true; EditorNode::get_singleton()->make_bottom_panel_item_visible(tileset_editor); } } diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h index a22e782b34..b1fe6f8df6 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.h +++ b/editor/plugins/tiles/tiles_editor_plugin.h @@ -53,9 +53,12 @@ public: }; private: + bool is_visible = false; + bool tile_map_changed_needs_update = false; ObjectID tile_map_id; Ref<TileSet> tile_set; + bool is_editing_tile_set = false; Button *tilemap_editor_button = nullptr; TileMapEditor *tilemap_editor = nullptr; diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index 443d5975cd..cf55465417 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -35,6 +35,8 @@ #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" +#include "scene/gui/separator.h" VersionControlEditorPlugin *VersionControlEditorPlugin::singleton = nullptr; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 69a125a029..4a144bc391 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -40,10 +40,17 @@ #include "editor/editor_node.h" #include "editor/editor_properties.h" #include "editor/editor_scale.h" +#include "editor/plugins/curve_editor_plugin.h" #include "editor/plugins/shader_editor_plugin.h" #include "scene/animation/animation_player.h" +#include "scene/gui/button.h" +#include "scene/gui/code_edit.h" +#include "scene/gui/graph_edit.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" +#include "scene/gui/popup.h" +#include "scene/gui/rich_text_label.h" +#include "scene/gui/tree.h" #include "scene/gui/view_panner.h" #include "scene/main/window.h" #include "scene/resources/visual_shader_nodes.h" @@ -91,17 +98,6 @@ void VisualShaderNodePlugin::_bind_methods() { /////////////////// -static Ref<StyleBoxEmpty> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) { - Ref<StyleBoxEmpty> style(memnew(StyleBoxEmpty)); - style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE); - style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE); - style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE); - style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE); - return style; -} - -/////////////////// - VisualShaderGraphPlugin::VisualShaderGraphPlugin() { } @@ -199,7 +195,7 @@ void VisualShaderGraphPlugin::set_input_port_default_value(VisualShader::Type p_ Callable ce = callable_mp(editor, &VisualShaderEditor::_draw_color_over_button); if (!button->is_connected("draw", ce)) { - button->connect("draw", ce, varray(button, p_value)); + button->connect("draw", ce.bind(button, p_value)); } } break; case Variant::BOOL: { @@ -364,8 +360,6 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Control *offset; - static Ref<StyleBoxEmpty> label_style = make_empty_stylebox(2, 1, 2, 1); - static const Color type_color[] = { Color(0.38, 0.85, 0.96), // scalar (float) Color(0.49, 0.78, 0.94), // scalar (int) @@ -423,7 +417,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { size = resizable_node->get_size(); node->set_resizable(true); - node->connect("resize_request", callable_mp(editor, &VisualShaderEditor::_node_resized), varray((int)p_type, p_id)); + node->connect("resize_request", callable_mp(editor, &VisualShaderEditor::_node_resized).bind((int)p_type, p_id)); } if (is_expression) { expression = expression_node->get_expression(); @@ -435,10 +429,10 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (p_id >= 2) { node->set_show_close_button(true); - node->connect("close_request", callable_mp(editor, &VisualShaderEditor::_delete_node_request), varray(p_type, p_id), CONNECT_DEFERRED); + node->connect("close_request", callable_mp(editor, &VisualShaderEditor::_delete_node_request).bind(p_type, p_id), CONNECT_DEFERRED); } - node->connect("dragged", callable_mp(editor, &VisualShaderEditor::_node_dragged), varray(p_id)); + node->connect("dragged", callable_mp(editor, &VisualShaderEditor::_node_dragged).bind(p_id)); Control *custom_editor = nullptr; int port_offset = 1; @@ -485,8 +479,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { register_uniform_name(p_id, uniform_name); uniform_name->set_h_size_flags(Control::SIZE_EXPAND_FILL); uniform_name->set_text(uniform->get_uniform_name()); - uniform_name->connect("text_submitted", callable_mp(editor, &VisualShaderEditor::_uniform_line_edit_changed), varray(p_id)); - uniform_name->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_uniform_line_edit_focus_out), varray(uniform_name, p_id)); + uniform_name->connect("text_submitted", callable_mp(editor, &VisualShaderEditor::_uniform_line_edit_changed).bind(p_id)); + uniform_name->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_uniform_line_edit_focus_out).bind(uniform_name, p_id)); if (vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") { hb = memnew(HBoxContainer); @@ -526,7 +520,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Callable ce = callable_mp(graph_plugin, &VisualShaderGraphPlugin::update_curve); if (curve->get_texture().is_valid() && !curve->get_texture()->is_connected("changed", ce)) { - curve->get_texture()->connect("changed", ce, varray(p_id)); + curve->get_texture()->connect("changed", ce.bind(p_id)); } CurveEditor *curve_editor = memnew(CurveEditor); @@ -544,7 +538,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Callable ce = callable_mp(graph_plugin, &VisualShaderGraphPlugin::update_curve_xyz); if (curve_xyz->get_texture().is_valid() && !curve_xyz->get_texture()->is_connected("changed", ce)) { - curve_xyz->get_texture()->connect("changed", ce, varray(p_id)); + curve_xyz->get_texture()->connect("changed", ce.bind(p_id)); } CurveEditor *curve_editor_x = memnew(CurveEditor); @@ -607,14 +601,14 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Button *add_input_btn = memnew(Button); add_input_btn->set_text(TTR("Add Input")); - add_input_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_input_port), varray(p_id, group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR_3D, input_port_name), CONNECT_DEFERRED); + add_input_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_input_port).bind(p_id, group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR_3D, input_port_name), CONNECT_DEFERRED); hb2->add_child(add_input_btn); hb2->add_spacer(); Button *add_output_btn = memnew(Button); add_output_btn->set_text(TTR("Add Output")); - add_output_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_output_port), varray(p_id, group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR_3D, output_port_name), CONNECT_DEFERRED); + add_output_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_output_port).bind(p_id, group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR_3D, output_port_name), CONNECT_DEFERRED); hb2->add_child(add_output_btn); node->add_child(hb2); @@ -722,7 +716,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Button *button = memnew(Button); hb->add_child(button); register_default_input_button(p_id, i, button); - button->connect("pressed", callable_mp(editor, &VisualShaderEditor::_edit_port_default_input), varray(button, p_id, i)); + button->connect("pressed", callable_mp(editor, &VisualShaderEditor::_edit_port_default_input).bind(button, p_id, i)); if (default_value.get_type() != Variant::NIL) { // only a label set_input_port_default_value(p_type, p_id, i, default_value); } else { @@ -747,32 +741,32 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { type_box->add_item(TTR("Sampler")); type_box->select(group_node->get_input_port_type(i)); type_box->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); - type_box->connect("item_selected", callable_mp(editor, &VisualShaderEditor::_change_input_port_type), varray(p_id, i), CONNECT_DEFERRED); + type_box->connect("item_selected", callable_mp(editor, &VisualShaderEditor::_change_input_port_type).bind(p_id, i), CONNECT_DEFERRED); LineEdit *name_box = memnew(LineEdit); hb->add_child(name_box); name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0)); name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); name_box->set_text(name_left); - name_box->connect("text_submitted", callable_mp(editor, &VisualShaderEditor::_change_input_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED); - name_box->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, false), CONNECT_DEFERRED); + name_box->connect("text_submitted", callable_mp(editor, &VisualShaderEditor::_change_input_port_name).bind(name_box, p_id, i), CONNECT_DEFERRED); + name_box->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_port_name_focus_out).bind(name_box, p_id, i, false), CONNECT_DEFERRED); Button *remove_btn = memnew(Button); remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); remove_btn->set_tooltip(TTR("Remove") + " " + name_left); - remove_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_remove_input_port), varray(p_id, i), CONNECT_DEFERRED); + remove_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_remove_input_port).bind(p_id, i), CONNECT_DEFERRED); hb->add_child(remove_btn); } else { Label *label = memnew(Label); label->set_text(name_left); - label->add_theme_style_override("normal", label_style); //more compact + label->add_theme_style_override("normal", editor->get_theme_stylebox(SNAME("label_style"), SNAME("VShaderEditor"))); //more compact hb->add_child(label); if (vsnode->is_input_port_default(i, mode) && !port_left_used) { Label *hint_label = memnew(Label); hint_label->set_text(TTR("[default]")); hint_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("font_readonly_color"), SNAME("TextEdit"))); - hint_label->add_theme_style_override("normal", label_style); + hint_label->add_theme_style_override("normal", editor->get_theme_stylebox(SNAME("label_style"), SNAME("VShaderEditor"))); hb->add_child(hint_label); } } @@ -787,7 +781,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Button *remove_btn = memnew(Button); remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); remove_btn->set_tooltip(TTR("Remove") + " " + name_left); - remove_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_remove_output_port), varray(p_id, i), CONNECT_DEFERRED); + remove_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_remove_output_port).bind(p_id, i), CONNECT_DEFERRED); hb->add_child(remove_btn); LineEdit *name_box = memnew(LineEdit); @@ -795,8 +789,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0)); name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); name_box->set_text(name_right); - name_box->connect("text_submitted", callable_mp(editor, &VisualShaderEditor::_change_output_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED); - name_box->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, true), CONNECT_DEFERRED); + name_box->connect("text_submitted", callable_mp(editor, &VisualShaderEditor::_change_output_port_name).bind(name_box, p_id, i), CONNECT_DEFERRED); + name_box->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_port_name_focus_out).bind(name_box, p_id, i, true), CONNECT_DEFERRED); OptionButton *type_box = memnew(OptionButton); hb->add_child(type_box); @@ -809,11 +803,11 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { type_box->add_item(TTR("Transform")); type_box->select(group_node->get_output_port_type(i)); type_box->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); - type_box->connect("item_selected", callable_mp(editor, &VisualShaderEditor::_change_output_port_type), varray(p_id, i), CONNECT_DEFERRED); + type_box->connect("item_selected", callable_mp(editor, &VisualShaderEditor::_change_output_port_type).bind(p_id, i), CONNECT_DEFERRED); } else { Label *label = memnew(Label); label->set_text(name_right); - label->add_theme_style_override("normal", label_style); //more compact + label->add_theme_style_override("normal", editor->get_theme_stylebox(SNAME("label_style"), SNAME("VShaderEditor"))); //more compact hb->add_child(label); } } @@ -827,7 +821,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { expand->set_pressed_texture(editor->get_theme_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); expand->set_v_size_flags(Control::SIZE_SHRINK_CENTER); expand->set_pressed(vsnode->_is_output_port_expanded(i)); - expand->connect("pressed", callable_mp(editor, &VisualShaderEditor::_expand_output_port), varray(p_id, i, !vsnode->_is_output_port_expanded(i)), CONNECT_DEFERRED); + expand->connect("pressed", callable_mp(editor, &VisualShaderEditor::_expand_output_port).bind(p_id, i, !vsnode->_is_output_port_expanded(i)), CONNECT_DEFERRED); hb->add_child(expand); } if (vsnode->has_output_port_preview(i) && port_right != VisualShaderNode::PORT_TYPE_TRANSFORM && port_right != VisualShaderNode::PORT_TYPE_SAMPLER) { @@ -839,7 +833,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { register_output_port(p_id, j, preview); - preview->connect("pressed", callable_mp(editor, &VisualShaderEditor::_preview_select_port), varray(p_id, j), CONNECT_DEFERRED); + preview->connect("pressed", callable_mp(editor, &VisualShaderEditor::_preview_select_port).bind(p_id, j), CONNECT_DEFERRED); hb->add_child(preview); } } @@ -1021,7 +1015,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { expression_box->set_context_menu_enabled(false); expression_box->set_draw_line_numbers(true); - expression_box->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_expression_focus_out), varray(expression_box, p_id)); + expression_box->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_expression_focus_out).bind(expression_box, p_id)); } if (is_comment) { @@ -1080,6 +1074,23 @@ VisualShaderGraphPlugin::~VisualShaderGraphPlugin() { ///////////////// +void VisualShaderEditedProperty::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_edited_property", "value"), &VisualShaderEditedProperty::set_edited_property); + ClassDB::bind_method(D_METHOD("get_edited_property"), &VisualShaderEditedProperty::get_edited_property); + + ADD_PROPERTY(PropertyInfo(Variant::NIL, "edited_property", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_edited_property", "get_edited_property"); +} + +void VisualShaderEditedProperty::set_edited_property(Variant p_variant) { + edited_property = p_variant; +} + +Variant VisualShaderEditedProperty::get_edited_property() const { + return edited_property; +} + +///////////////// + Vector2 VisualShaderEditor::selection_center; List<VisualShaderEditor::CopyItem> VisualShaderEditor::copy_items_buffer; List<VisualShader::Connection> VisualShaderEditor::copy_connections_buffer; @@ -2287,10 +2298,8 @@ void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id, } } -void VisualShaderEditor::_port_edited() { +void VisualShaderEditor::_port_edited(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing) { VisualShader::Type type = get_current_shader_type(); - - Variant value = property_editor->get_variant(); Ref<VisualShaderNode> vsn = visual_shader->get_node(type, editing_node); ERR_FAIL_COND(!vsn.is_valid()); @@ -2298,30 +2307,51 @@ void VisualShaderEditor::_port_edited() { Ref<VisualShaderNodeCustom> custom = Object::cast_to<VisualShaderNodeCustom>(vsn.ptr()); if (custom.is_valid()) { - undo_redo->add_do_method(custom.ptr(), "_set_input_port_default_value", editing_port, value); + undo_redo->add_do_method(custom.ptr(), "_set_input_port_default_value", editing_port, p_value); undo_redo->add_undo_method(custom.ptr(), "_set_input_port_default_value", editing_port, vsn->get_input_port_default_value(editing_port)); } else { - undo_redo->add_do_method(vsn.ptr(), "set_input_port_default_value", editing_port, value); + undo_redo->add_do_method(vsn.ptr(), "set_input_port_default_value", editing_port, p_value); undo_redo->add_undo_method(vsn.ptr(), "set_input_port_default_value", editing_port, vsn->get_input_port_default_value(editing_port)); } - undo_redo->add_do_method(graph_plugin.ptr(), "set_input_port_default_value", type, editing_node, editing_port, value); + undo_redo->add_do_method(graph_plugin.ptr(), "set_input_port_default_value", type, editing_node, editing_port, p_value); undo_redo->add_undo_method(graph_plugin.ptr(), "set_input_port_default_value", type, editing_node, editing_port, vsn->get_input_port_default_value(editing_port)); undo_redo->commit_action(); - - property_editor->hide(); } void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node, int p_port) { VisualShader::Type type = get_current_shader_type(); + Ref<VisualShaderNode> vs_node = visual_shader->get_node(type, p_node); + Variant value = vs_node->get_input_port_default_value(p_port); + + edited_property_holder->set_edited_property(value); + + if (property_editor) { + property_editor->disconnect("property_changed", callable_mp(this, &VisualShaderEditor::_port_edited)); + property_editor_popup->remove_child(property_editor); + } - Ref<VisualShaderNode> vsn = visual_shader->get_node(type, p_node); + // TODO: Define these properties with actual PropertyInfo and feed it to the property editor widget. + property_editor = EditorInspector::instantiate_property_editor(edited_property_holder.ptr(), value.get_type(), "edited_property", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE); + if (property_editor) { + property_editor->set_object_and_property(edited_property_holder.ptr(), "edited_property"); + property_editor->update_property(); + property_editor->set_name_split_ratio(0); + property_editor_popup->add_child(property_editor); + + property_editor->connect("property_changed", callable_mp(this, &VisualShaderEditor::_port_edited)); + + Button *button = Object::cast_to<Button>(p_button); + if (button) { + property_editor_popup->set_position(button->get_screen_position() + Vector2(0, button->get_size().height) * graph->get_zoom()); + } + property_editor_popup->reset_size(); + if (button) { + property_editor_popup->popup(); + } else { + property_editor_popup->popup_centered_ratio(); + } + } - Button *button = Object::cast_to<Button>(p_button); - ERR_FAIL_COND(!button); - Variant value = vsn->get_input_port_default_value(p_port); - property_editor->set_position(button->get_screen_position() + Vector2(0, button->get_size().height)); - property_editor->edit(nullptr, "", value.get_type(), value, 0, ""); - property_editor->popup(); editing_node = p_node; editing_port = p_port; } @@ -4563,9 +4593,9 @@ void VisualShaderEditor::_preview_size_changed() { preview_vbox->set_custom_minimum_size(preview_window->get_size()); } -static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { - RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); - return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt); +static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) { + RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(p_variable); + return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); } void VisualShaderEditor::_update_preview() { @@ -4582,7 +4612,7 @@ void VisualShaderEditor::_update_preview() { info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())); info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())); info.shader_types = ShaderTypes::get_singleton()->get_types(); - info.global_variable_type_func = _get_global_variable_type; + info.global_shader_uniform_type_func = _get_global_shader_uniform_type; ShaderLanguage sl; @@ -4666,13 +4696,13 @@ VisualShaderEditor::VisualShaderEditor() { graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SAMPLER); //graph->add_valid_left_disconnect_type(0); graph->set_v_size_flags(SIZE_EXPAND_FILL); - graph->connect("connection_request", callable_mp(this, &VisualShaderEditor::_connection_request), varray(), CONNECT_DEFERRED); - graph->connect("disconnection_request", callable_mp(this, &VisualShaderEditor::_disconnection_request), varray(), CONNECT_DEFERRED); + graph->connect("connection_request", callable_mp(this, &VisualShaderEditor::_connection_request), CONNECT_DEFERRED); + graph->connect("disconnection_request", callable_mp(this, &VisualShaderEditor::_disconnection_request), CONNECT_DEFERRED); graph->connect("node_selected", callable_mp(this, &VisualShaderEditor::_node_selected)); graph->connect("scroll_offset_changed", callable_mp(this, &VisualShaderEditor::_scroll_changed)); graph->connect("duplicate_nodes_request", callable_mp(this, &VisualShaderEditor::_duplicate_nodes)); - graph->connect("copy_nodes_request", callable_mp(this, &VisualShaderEditor::_copy_nodes), varray(false)); - graph->connect("paste_nodes_request", callable_mp(this, &VisualShaderEditor::_paste_nodes), varray(false, Point2())); + graph->connect("copy_nodes_request", callable_mp(this, &VisualShaderEditor::_copy_nodes).bind(false)); + graph->connect("paste_nodes_request", callable_mp(this, &VisualShaderEditor::_paste_nodes).bind(false, Point2())); graph->connect("delete_nodes_request", callable_mp(this, &VisualShaderEditor::_delete_nodes_request)); graph->connect("gui_input", callable_mp(this, &VisualShaderEditor::_graph_gui_input)); graph->connect("connection_to_empty", callable_mp(this, &VisualShaderEditor::_connection_to_empty)); @@ -4775,7 +4805,7 @@ VisualShaderEditor::VisualShaderEditor() { add_node->set_text(TTR("Add Node...")); graph->get_zoom_hbox()->add_child(add_node); graph->get_zoom_hbox()->move_child(add_node, 0); - add_node->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_members_dialog), varray(false, VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PORT_TYPE_MAX)); + add_node->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_members_dialog).bind(false, VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PORT_TYPE_MAX)); varying_button = memnew(Button); varying_button->set_flat(true); @@ -5147,6 +5177,10 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ViewIndex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_index", "VIEW_INDEX"), { "view_index" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ViewMonoLeft", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_mono_left", "VIEW_MONO_LEFT"), { "view_mono_left" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ViewRight", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_right", "VIEW_RIGHT"), { "view_right" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("NodePositionWorld", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_world", "NODE_POSITION_WORLD"), { "node_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("CameraPositionWorld", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_position_world", "CAMERA_POSITION_WORLD"), { "camera_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("CameraDirectionWorld", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_direction_world", "CAMERA_DIRECTION_WORLD"), { "camera_direction_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("NodePositionView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_view", "NODE_POSITION_VIEW"), { "node_position_view" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal", "BINORMAL"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color", "COLOR"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); @@ -5162,6 +5196,10 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ViewIndex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_index", "VIEW_INDEX"), { "view_index" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ViewMonoLeft", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_mono_left", "VIEW_MONO_LEFT"), { "view_mono_left" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ViewRight", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_right", "VIEW_RIGHT"), { "view_right" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("NodePositionWorld", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_world", "NODE_POSITION_WORLD"), { "node_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("CameraPositionWorld", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_position_world", "CAMERA_POSITION_WORLD"), { "camera_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("CameraDirectionWorld", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_direction_world", "CAMERA_DIRECTION_WORLD"), { "camera_direction_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("NodePositionView", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_view", "NODE_POSITION_VIEW"), { "node_position_view" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo", "ALBEDO"), { "albedo" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "attenuation", "ATTENUATION"), { "attenuation" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); @@ -5539,8 +5577,12 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), { VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), { VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), { VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), {}, VisualShaderNode::PORT_TYPE_VECTOR_4D)); add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); @@ -5636,10 +5678,11 @@ VisualShaderEditor::VisualShaderEditor() { graph_plugin.instantiate(); graph_plugin->set_editor(this); - property_editor = memnew(CustomPropertyEditor); - add_child(property_editor); + property_editor_popup = memnew(PopupPanel); + property_editor_popup->set_min_size(Size2i(180, 0) * EDSCALE); + add_child(property_editor_popup); - property_editor->connect("variant_changed", callable_mp(this, &VisualShaderEditor::_port_edited)); + edited_property_holder.instantiate(); } class VisualShaderNodePluginInputEditor : public OptionButton { @@ -6189,7 +6232,7 @@ void VisualShaderNodePortPreview::_shader_changed() { } if (src_mat && src_mat->get_shader().is_valid()) { List<PropertyInfo> params; - src_mat->get_shader()->get_param_list(¶ms); + src_mat->get_shader()->get_shader_uniform_list(¶ms); for (const PropertyInfo &E : params) { material->set(E.name, src_mat->get(E.name)); } @@ -6210,7 +6253,7 @@ void VisualShaderNodePortPreview::setup(const Ref<VisualShader> &p_shader, Visua } Size2 VisualShaderNodePortPreview::get_minimum_size() const { - int port_preview_size = EditorSettings::get_singleton()->get("editors/visual_editors/visualshader/port_preview_size"); + int port_preview_size = EditorSettings::get_singleton()->get("editors/visual_editors/visual_shader/port_preview_size"); return Size2(port_preview_size, port_preview_size) * EDSCALE; } diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 2feed6108a..b846c34f9e 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -32,16 +32,21 @@ #define VISUAL_SHADER_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" -#include "editor/plugins/curve_editor_plugin.h" -#include "editor/property_editor.h" -#include "scene/gui/button.h" -#include "scene/gui/code_edit.h" -#include "scene/gui/graph_edit.h" -#include "scene/gui/popup.h" -#include "scene/gui/rich_text_label.h" -#include "scene/gui/tree.h" +#include "editor/plugins/editor_resource_conversion_plugin.h" #include "scene/resources/visual_shader.h" +class Button; +class CodeEdit; +class CodeHighlighter; +class CurveEditor; +class GraphEdit; +class GraphNode; +class PopupMenu; +class PopupPanel; +class RichTextLabel; +class TextEdit; +class Tree; + class VisualShaderEditor; class VisualShaderNodePlugin : public RefCounted { @@ -137,13 +142,31 @@ public: ~VisualShaderGraphPlugin(); }; +class VisualShaderEditedProperty : public RefCounted { + GDCLASS(VisualShaderEditedProperty, RefCounted); + +private: + Variant edited_property; + +protected: + static void _bind_methods(); + +public: + void set_edited_property(Variant p_variant); + Variant get_edited_property() const; + + VisualShaderEditedProperty() {} +}; + class VisualShaderEditor : public VBoxContainer { GDCLASS(VisualShaderEditor, VBoxContainer); friend class VisualShaderGraphPlugin; - CustomPropertyEditor *property_editor = nullptr; + PopupPanel *property_editor_popup = nullptr; + EditorProperty *property_editor = nullptr; int editing_node = -1; int editing_port = -1; + Ref<VisualShaderEditedProperty> edited_property_holder; Ref<VisualShader> visual_shader; GraphEdit *graph = nullptr; @@ -358,7 +381,7 @@ class VisualShaderEditor : public VBoxContainer { void _node_changed(int p_id); void _edit_port_default_input(Object *p_button, int p_node, int p_port); - void _port_edited(); + void _port_edited(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing); int to_node = -1; int to_slot = -1; diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp index 6fc6c1ad39..e3b2be33df 100644 --- a/editor/plugins/voxel_gi_editor_plugin.cpp +++ b/editor/plugins/voxel_gi_editor_plugin.cpp @@ -139,7 +139,7 @@ void VoxelGIEditorPlugin::_voxel_gi_save_path_and_bake(const String &p_path) { if (voxel_gi) { voxel_gi->bake(); ERR_FAIL_COND(voxel_gi->get_probe_data().is_null()); - ResourceSaver::save(p_path, voxel_gi->get_probe_data(), ResourceSaver::FLAG_CHANGE_PATH); + ResourceSaver::save(voxel_gi->get_probe_data(), p_path, ResourceSaver::FLAG_CHANGE_PATH); } } diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index 6437e19404..421e56f9a1 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -42,7 +42,8 @@ const int ERROR_CODE = 77; #include "core/templates/hash_map.h" #include "core/templates/list.h" -const int CONVERSION_MAX_FILE_SIZE = 1024 * 1024 * 4; // 4 MB +const uint64_t CONVERSION_MAX_FILE_SIZE_MB = 4; +const uint64_t CONVERSION_MAX_FILE_SIZE = 1024 * 1024 * CONVERSION_MAX_FILE_SIZE_MB; static const char *enum_renames[][2] = { //// constants @@ -120,7 +121,7 @@ static const char *enum_renames[][2] = { { "JOINT_PIN", "JOINT_TYPE_PIN" }, // PhysicsServer2D { "JOINT_SLIDER", "JOINT_TYPE_SLIDER" }, // PhysicsServer3D { "KEY_CONTROL", "KEY_CTRL" }, // Globals - { "LOOP_PING_PONG", "LOOP_PINGPONG" }, //AudioStreamSample + { "LOOP_PING_PONG", "LOOP_PINGPONG" }, // AudioStreamWAV { "MATH_RAND", "MATH_RANDF_RANGE" }, // VisualScriptBuiltinFunc { "MATH_RANDOM", "MATH_RANDI_RANGE" }, // VisualScriptBuiltinFunc { "MATH_STEPIFY", "MATH_STEP_DECIMALS" }, // VisualScriptBuiltinFunc @@ -255,6 +256,7 @@ static const char *gdscript_function_renames[][2] = { { "damped_spring_joint_create", "joint_make_damped_spring" }, // PhysicsServer2D { "damped_string_joint_get_param", "damped_spring_joint_get_param" }, // PhysicsServer2D { "damped_string_joint_set_param", "damped_spring_joint_set_param" }, // PhysicsServer2D + { "dectime", "move_toward" }, // GDScript, Math functions { "delete_char_at_cursor", "delete_char_at_caret" }, // LineEdit { "deselect_items", "deselect_all" }, // FileDialog { "disable_plugin", "_disable_plugin" }, // EditorPlugin @@ -427,6 +429,7 @@ static const char *gdscript_function_renames[][2] = { { "joint_create_slider", "joint_make_slider" }, // PhysicsServer3D { "line_intersects_line_2d", "line_intersects_line" }, // Geometry2D { "load_from_globals", "load_from_project_settings" }, // InputMap + { "load_interactive", "load_threaded_request" }, // ResourceLoader - load_threaded_request is alternative, but is used differently { "make_convex_from_brothers", "make_convex_from_siblings" }, // CollisionShape3D { "make_visible", "_make_visible" }, // EditorPlugin { "merge_polygons_2d", "merge_polygons" }, // Geometry2D @@ -484,6 +487,7 @@ static const char *gdscript_function_renames[][2] = { { "set_enabled_focus_mode", "set_focus_mode" }, // BaseButton { "set_endian_swap", "set_big_endian" }, // File { "set_expand_to_text_length", "set_expand_to_text_length_enabled" }, // LineEdit + { "set_filename", "set_scene_file_path" }, // Node, WARNING, this may be used in a lot of other places { "set_focus_neighbour", "set_focus_neighbor" }, // Control { "set_frame_color", "set_color" }, // ColorRect { "set_global_rate_scale", "set_playback_speed_scale" }, // AudioServer @@ -975,6 +979,7 @@ static const char *gdscript_properties_renames[][2] = { // { "wrap_enabled", "wrap_mode" }, // TextEdit // { "zfar", "far" }, // Camera3D // { "znear", "near" }, // Camera3D + // { "filename", "scene_file_path" }, // Node { "as_normalmap", "as_normal_map" }, // NoiseTexture { "bbcode_text", "text" }, // RichTextLabel { "caret_moving_by_right_click", "caret_move_on_right_click" }, // TextEdit @@ -1250,7 +1255,9 @@ static const char *class_renames[][2] = { { "AnimatedSprite", "AnimatedSprite2D" }, { "AnimationTreePlayer", "AnimationTree" }, { "Area", "Area3D" }, // Be careful, this will be used everywhere + { "AudioStreamOGGVorbis", "AudioStreamOggVorbis" }, { "AudioStreamRandomPitch", "AudioStreamRandomizer" }, + { "AudioStreamSample", "AudioStreamWAV" }, { "BakedLightmap", "LightmapGI" }, { "BakedLightmapData", "LightmapGIData" }, { "BitmapFont", "FontFile" }, @@ -1593,12 +1600,33 @@ static const char *colors_renames[][2] = { { nullptr, nullptr }, }; +class ProjectConverter3To4::RegExContainer { +public: + RegEx reg_is_empty = RegEx("\\bempty\\("); + RegEx reg_super = RegEx("([\t ])\\.([a-zA-Z_])"); + RegEx reg_json_to = RegEx("\\bto_json\\b"); + RegEx reg_json_parse = RegEx("([\t]{0,})([^\n]+)parse_json\\(([^\n]+)"); + RegEx reg_json_non_new = RegEx("([\t]{0,})([^\n]+)JSON\\.parse\\(([^\n]+)"); + RegEx reg_export = RegEx("export\\(([a-zA-Z0-9_]+)\\)[ ]+var[ ]+([a-zA-Z0-9_]+)"); + RegEx reg_export_advanced = RegEx("export\\(([^)^\n]+)\\)[ ]+var[ ]+([a-zA-Z0-9_]+)([^\n]+)"); + RegEx reg_setget_setget = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+([a-zA-Z0-9_]+)[ \t]*,[ \t]*([a-zA-Z0-9_]+)"); + RegEx reg_setget_set = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+([a-zA-Z0-9_]+)[ \t]*[,]*[^a-z^A-Z^0-9^_]*$"); + RegEx reg_setget_get = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+,[ \t]*([a-zA-Z0-9_]+)[ \t]*$"); + RegEx reg_join = RegEx("([\\(\\)a-zA-Z0-9_]+)\\.join\\(([^\n^\\)]+)\\)"); + RegEx reg_mixed_tab_space = RegEx("([\t]+)([ ]+)"); + RegEx reg_image_lock = RegEx("([a-zA-Z0-9_\\.]+)\\.lock\\(\\)"); + RegEx reg_image_unlock = RegEx("([a-zA-Z0-9_\\.]+)\\.unlock\\(\\)"); + RegEx reg_os_fullscreen = RegEx("OS.window_fullscreen[= ]+([^#^\n]+)"); +}; + // Function responsible for converting project int ProjectConverter3To4::convert() { print_line("Starting conversion."); + RegExContainer reg_container = RegExContainer(); + ERR_FAIL_COND_V_MSG(!test_array_names(), ERROR_CODE, "Cannot start converting due to problems with data in arrays."); - ERR_FAIL_COND_V_MSG(!test_conversion(), ERROR_CODE, "Cannot start converting due to problems with converting arrays."); + ERR_FAIL_COND_V_MSG(!test_conversion(reg_container), ERROR_CODE, "Cannot start converting due to problems with converting arrays."); // Checking if folder contains valid Godot 3 project. // Project cannot be converted 2 times @@ -1638,7 +1666,7 @@ int ProjectConverter3To4::convert() { uint64_t start_time = Time::get_singleton()->get_ticks_msec(); if (file_name.ends_with(".shader")) { - DirAccess::remove_file_or_error(file_name); + DirAccess::remove_file_or_error(file_name.trim_prefix("res://")); file_name = file_name.replace(".shader", ".gdshader"); } @@ -1651,7 +1679,7 @@ int ProjectConverter3To4::convert() { rename_enums(file_content); // Require to additional rename rename_common(gdscript_function_renames, file_content); - rename_gdscript_functions(file_content); // Require to additional rename + rename_gdscript_functions(file_content, reg_container, false); // Require to additional rename rename_common(project_settings_renames, file_content); rename_gdscript_keywords(file_content); @@ -1669,7 +1697,7 @@ int ProjectConverter3To4::convert() { rename_enums(file_content); // Require to additional rename rename_common(gdscript_function_renames, file_content); - rename_gdscript_functions(file_content); // Require to additional rename + rename_gdscript_functions(file_content, reg_container, true); // Require to additional rename rename_common(project_settings_renames, file_content); rename_gdscript_keywords(file_content); @@ -1686,6 +1714,7 @@ int ProjectConverter3To4::convert() { rename_common(csharp_properties_renames, file_content); rename_common(csharp_signals_renames, file_content); rename_csharp_functions(file_content); + rename_csharp_attributes(file_content); custom_rename(file_content, "public class ", "public partial class "); } else if (file_name.ends_with(".gdshader") || file_name.ends_with(".shader")) { rename_common(shaders_renames, file_content); @@ -1706,7 +1735,7 @@ int ProjectConverter3To4::convert() { continue; } } else { - reason.append(" ERROR: File has exceeded the maximum size allowed - 500 KB"); + reason.append(" ERROR: File has exceeded the maximum size allowed - " + itos(CONVERSION_MAX_FILE_SIZE_MB) + " MB"); is_ignored = true; } @@ -1716,7 +1745,7 @@ int ProjectConverter3To4::convert() { uint64_t hash_after = file_content.hash64(); // Don't need to save file without any changes // Save if this is a shader, because it was renamed - if (hash_before != hash_after || file_name.find(".gdshader") != -1) { + if (hash_before != hash_after || file_name.ends_with(".gdshader")) { converted_files++; Ref<FileAccess> file = FileAccess::open(file_name, FileAccess::WRITE); @@ -1740,8 +1769,10 @@ int ProjectConverter3To4::convert() { int ProjectConverter3To4::validate_conversion() { print_line("Starting checking if project conversion can be done."); + RegExContainer reg_container = RegExContainer(); + ERR_FAIL_COND_V_MSG(!test_array_names(), ERROR_CODE, "Cannot start converting due to problems with data in arrays."); - ERR_FAIL_COND_V_MSG(!test_conversion(), ERROR_CODE, "Cannot start converting due to problems with converting arrays."); + ERR_FAIL_COND_V_MSG(!test_conversion(reg_container), ERROR_CODE, "Cannot start converting due to problems with converting arrays."); // Checking if folder contains valid Godot 3 project. // Project cannot be converted 2 times @@ -1782,7 +1813,7 @@ int ProjectConverter3To4::validate_conversion() { bool is_ignored = false; uint64_t start_time = Time::get_singleton()->get_ticks_msec(); - if (file_name.ends_with(".sader")) { + if (file_name.ends_with(".shader")) { reason.append("\tFile extension will be renamed from `shader` to `gdshader`."); } @@ -1794,7 +1825,7 @@ int ProjectConverter3To4::validate_conversion() { changed_elements.append_array(check_for_rename_enums(file_content)); changed_elements.append_array(check_for_rename_common(gdscript_function_renames, file_content)); - changed_elements.append_array(check_for_rename_gdscript_functions(file_content)); + changed_elements.append_array(check_for_rename_gdscript_functions(file_content, reg_container, false)); changed_elements.append_array(check_for_rename_common(project_settings_renames, file_content)); changed_elements.append_array(check_for_rename_gdscript_keywords(file_content)); @@ -1812,7 +1843,7 @@ int ProjectConverter3To4::validate_conversion() { changed_elements.append_array(check_for_rename_enums(file_content)); changed_elements.append_array(check_for_rename_common(gdscript_function_renames, file_content)); - changed_elements.append_array(check_for_rename_gdscript_functions(file_content)); + changed_elements.append_array(check_for_rename_gdscript_functions(file_content, reg_container, true)); changed_elements.append_array(check_for_rename_common(project_settings_renames, file_content)); changed_elements.append_array(check_for_rename_gdscript_keywords(file_content)); @@ -1829,6 +1860,7 @@ int ProjectConverter3To4::validate_conversion() { changed_elements.append_array(check_for_rename_common(csharp_properties_renames, file_content)); changed_elements.append_array(check_for_rename_common(csharp_signals_renames, file_content)); changed_elements.append_array(check_for_rename_csharp_functions(file_content)); + changed_elements.append_array(check_for_rename_csharp_attributes(file_content)); changed_elements.append_array(check_for_custom_rename(file_content, "public class ", "public partial class ")); } else if (file_name.ends_with(".gdshader") || file_name.ends_with(".shader")) { changed_elements.append_array(check_for_rename_common(shaders_renames, file_content)); @@ -1849,7 +1881,7 @@ int ProjectConverter3To4::validate_conversion() { continue; } } else { - reason.append("\tERROR: File has exceeded the maximum size allowed - 500 KB"); + reason.append("\tERROR: File has exceeded the maximum size allowed - " + itos(CONVERSION_MAX_FILE_SIZE_MB) + " MB"); is_ignored = true; } @@ -1896,14 +1928,14 @@ Vector<String> ProjectConverter3To4::check_for_files() { continue; } if (dir.current_is_dir()) { - directories_to_check.append(current_dir + file_name + "/"); + directories_to_check.append(current_dir.plus_file(file_name) + "/"); } else { bool proper_extension = false; if (file_name.ends_with(".gd") || file_name.ends_with(".shader") || file_name.ends_with(".tscn") || file_name.ends_with(".tres") || file_name.ends_with(".godot") || file_name.ends_with(".cs") || file_name.ends_with(".csproj")) proper_extension = true; if (proper_extension) { - collected_files.append(current_dir + file_name); + collected_files.append(current_dir.plus_file(file_name)); } } file_name = dir.get_next(); @@ -1926,6 +1958,17 @@ bool ProjectConverter3To4::test_conversion_single_additional(String name, String return true; } +bool ProjectConverter3To4::test_conversion_single_additional_builtin(String name, String expected, void (ProjectConverter3To4::*func)(String &, const RegExContainer &, bool), String what, const RegExContainer ®_container, bool builtin_script) { + String got = name; + (this->*func)(got, reg_container, builtin_script); + if (expected != got) { + ERR_PRINT("Failed to convert " + what + " `" + name + "` to `" + expected + "`, got instead `" + got + "`"); + return false; + } + + return true; +} + bool ProjectConverter3To4::test_conversion_single_normal(String name, String expected, const char *array[][2], String what) { String got = name; rename_common(array, got); @@ -1937,7 +1980,7 @@ bool ProjectConverter3To4::test_conversion_single_normal(String name, String exp } // Validate if conversions are proper -bool ProjectConverter3To4::test_conversion() { +bool ProjectConverter3To4::test_conversion(const RegExContainer ®_container) { bool valid = true; valid = valid & test_conversion_single_normal("Spatial", "Node3D", class_renames, "class"); @@ -1968,26 +2011,37 @@ bool ProjectConverter3To4::test_conversion() { valid = valid & test_conversion_single_additional("(Disconnect(A,B,C) != OK):", "(Disconnect(A,new Callable(B,C)) != OK):", &ProjectConverter3To4::rename_csharp_functions, "custom rename csharp"); valid = valid & test_conversion_single_additional("(IsConnected(A,B,C) != OK):", "(IsConnected(A,new Callable(B,C)) != OK):", &ProjectConverter3To4::rename_csharp_functions, "custom rename"); - valid = valid & test_conversion_single_additional("OS.window_fullscreen = Settings.fullscreen", "ProjectSettings.set(\"display/window/size/fullscreen\", Settings.fullscreen)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); + valid = valid & test_conversion_single_additional("[Remote]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp"); + valid = valid & test_conversion_single_additional("[RemoteSync]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp"); + valid = valid & test_conversion_single_additional("[Sync]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp"); + valid = valid & test_conversion_single_additional("[Slave]", "[RPC]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp"); + valid = valid & test_conversion_single_additional("[Puppet]", "[RPC]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp"); + valid = valid & test_conversion_single_additional("[PuppetSync]", "[RPC(CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp"); + valid = valid & test_conversion_single_additional("[Master]", "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using Multiplayer.GetRemoteSenderId()\n[RPC]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp"); + valid = valid & test_conversion_single_additional("[MasterSync]", "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using Multiplayer.GetRemoteSenderId()\n[RPC(CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp"); - valid = valid & test_conversion_single_additional("\tvar aa = roman(r.move_and_slide( a, b, c, d, e, f )) # Roman", "\tr.set_motion_velocity(a)\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tvar aa = roman(r.move_and_slide()) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("\tvar aa = roman(r.move_and_slide_with_snap( a, g, b, c, d, e, f )) # Roman", "\tr.set_motion_velocity(a)\n\t# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `g`\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tvar aa = roman(r.move_and_slide()) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); + valid = valid & test_conversion_single_additional_builtin("OS.window_fullscreen = Settings.fullscreen", "ProjectSettings.set(\"display/window/size/fullscreen\", Settings.fullscreen)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("OS.window_fullscreen = Settings.fullscreen", "ProjectSettings.set(\\\"display/window/size/fullscreen\\\", Settings.fullscreen)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, true); + valid = valid & test_conversion_single_additional_builtin("OS.get_window_safe_area()", "DisplayServer.get_display_safe_area()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid & test_conversion_single_additional("list_dir_begin( a , b )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("list_dir_begin( a )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("list_dir_begin( )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); + valid = valid & test_conversion_single_additional_builtin("\tvar aa = roman(r.move_and_slide( a, b, c, d, e, f )) # Roman", "\tr.set_motion_velocity(a)\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tvar aa = roman(r.move_and_slide()) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("\tvar aa = roman(r.move_and_slide_with_snap( a, g, b, c, d, e, f )) # Roman", "\tr.set_motion_velocity(a)\n\t# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `g`\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tvar aa = roman(r.move_and_slide()) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid & test_conversion_single_additional("sort_custom( a , b )", "sort_custom(Callable(a,b))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); + valid = valid & test_conversion_single_additional_builtin("list_dir_begin( a , b )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("list_dir_begin( a )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("list_dir_begin( )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid & test_conversion_single_additional("func c(var a, var b)", "func c(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); + valid = valid & test_conversion_single_additional_builtin("sort_custom( a , b )", "sort_custom(Callable(a,b))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid & test_conversion_single_additional("draw_line(1, 2, 3, 4, 5)", "draw_line(1,2,3,4)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); + valid = valid & test_conversion_single_additional_builtin("func c(var a, var b)", "func c(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid & test_conversion_single_additional("\timage.lock()", "\tfalse # image.lock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("\timage.unlock()", "\tfalse # image.unlock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("\troman.image.unlock()", "\tfalse # roman.image.unlock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("\tmtx.lock()", "\tmtx.lock()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("\tmutex.unlock()", "\tmutex.unlock()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); + valid = valid & test_conversion_single_additional_builtin("draw_line(1, 2, 3, 4, 5)", "draw_line(1,2,3,4)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("\timage.lock()", "\tfalse # image.lock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("\timage.unlock()", "\tfalse # image.unlock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("\troman.image.unlock()", "\tfalse # roman.image.unlock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("\tmtx.lock()", "\tmtx.lock()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("\tmutex.unlock()", "\tmutex.unlock()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid & test_conversion_single_additional("\nonready", "\n@onready", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); valid = valid & test_conversion_single_additional("onready", "@onready", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); @@ -2000,82 +2054,88 @@ bool ProjectConverter3To4::test_conversion() { valid = valid & test_conversion_single_additional("tool", "@tool", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); valid = valid & test_conversion_single_additional("\n tool", "\n tool", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); valid = valid & test_conversion_single_additional("\n\ntool", "\n\n@tool", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); - valid = valid & test_conversion_single_additional("\n\nmaster func", "\n\n@rpc(any) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); - valid = valid & test_conversion_single_additional("\n\npuppet func", "\n\n@rpc(auth) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); - valid = valid & test_conversion_single_additional("\n\nremote func", "\n\n@rpc(any) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); - valid = valid & test_conversion_single_additional("\n\nremotesync func", "\n\n@rpc(any,sync) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); - valid = valid & test_conversion_single_additional("\n\nsync func", "\n\n@rpc(any,sync) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); - valid = valid & test_conversion_single_additional("\n\npuppetsync func", "\n\n@rpc(auth,sync) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); - valid = valid & test_conversion_single_additional("\n\nmastersync func", "\n\n@rpc(any,sync) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); - - valid = valid & test_conversion_single_additional("var size : Vector2 = Vector2() setget set_function , get_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Copy here content of get_function\n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("var size : Vector2 = Vector2() setget set_function , ", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Non existent get function \n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("var size : Vector2 = Vector2() setget set_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Non existent get function \n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("var size : Vector2 = Vector2() setget , get_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Copy here content of get_function \n set(mod_value):\n mod_value # TODOConverter40 Non existent set function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("get_node(@", "get_node(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("yield(this, \"timeout\")", "await this.timeout", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional(" Transform.xform(Vector3(a,b,c)) ", " Transform * Vector3(a,b,c) ", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional(" Transform.xform_inv(Vector3(a,b,c)) ", " Vector3(a,b,c) * Transform ", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("export(float) var lifetime = 3.0", "export var lifetime: float = 3.0", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("export(String, 'AnonymousPro', 'CourierPrime') var _font_name = 'AnonymousPro'", "export var _font_name = 'AnonymousPro' # (String, 'AnonymousPro', 'CourierPrime')", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); // TODO, this is only a workaround - valid = valid & test_conversion_single_additional("export(PackedScene) var mob_scene", "export var mob_scene: PackedScene", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("var d = parse_json(roman(sfs))", "var test_json_conv = JSON.new()\ntest_json_conv.parse(roman(sfs))\nvar d = test_json_conv.get_data()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("to_json( AA ) szon", "JSON.new().stringify( AA ) szon", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("s to_json", "s JSON.new().stringify", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("AF to_json2", "AF to_json2", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("var rr = JSON.parse(a)", "var test_json_conv = JSON.new()\ntest_json_conv.parse(a)\nvar rr = test_json_conv.get_data()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("empty()", "is_empty()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional(".empty", ".empty", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional(").roman(", ").roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("\t.roman(", "\tsuper.roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional(" .roman(", " super.roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional(".1", ".1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional(" .1", " .1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("'.'", "'.'", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("'.a'", "'.a'", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("\t._input(_event)", "\tsuper._input(_event)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("(start(A,B,C,D,E,F,G) != OK):", "(start(A,Callable(B,C),D,E,F,G) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("(connect(A,B,C,D,E,F,G) != OK):", "(connect(A,Callable(B,C),D,E,F,G) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("(connect(A,B,C) != OK):", "(connect(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("disconnect(A,B,C) != OK):", "disconnect(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("is_connected(A,B,C) != OK):", "is_connected(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("is_connected(A,B,C))", "is_connected(A,Callable(B,C)))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("func _init(p_x:int)->void:", "func _init(p_x:int):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("q_PackedDataContainer._iter_init(variable1)", "q_PackedDataContainer._iter_init(variable1)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("assert(speed < 20, str(randi()%10))", "assert(speed < 20) #,str(randi()%10))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("assert(speed < 2)", "assert(speed < 2)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("assert(false, \"Missing type --\" + str(argument.type) + \"--, needs to be added to project\")", "assert(false) #,\"Missing type --\" + str(argument.type) + \"--, needs to be added to project\")", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("create_from_image(aa, bb)", "create_from_image(aa) #,bb", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("q_ImageTexture.create_from_image(variable1, variable2)", "q_ImageTexture.create_from_image(variable1) #,variable2", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("set_cell_item(a, b, c, d ,e) # AA", "set_cell_item( Vector3(a,b,c) ,d,e) # AA", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("set_cell_item(a, b)", "set_cell_item(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("get_cell_item_orientation(a, b,c)", "get_cell_item_orientation(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("get_cell_item(a, b,c)", "get_cell_item(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("map_to_world(a, b,c)", "map_to_world(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("PackedStringArray(req_godot).join('.')", "'.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("=PackedStringArray(req_godot).join('.')", "='.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional(" aa", " aa", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("\taa", "\taa", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("\t aa", "\taa", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional(" \taa", " \taa", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - - valid = valid & test_conversion_single_additional("apply_force(position, impulse)", "apply_force(impulse, position)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); - valid = valid & test_conversion_single_additional("apply_impulse(position, impulse)", "apply_impulse(impulse, position)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename"); + valid = valid & test_conversion_single_additional("\n\nremote func", "\n\n@rpc(any_peer) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); + valid = valid & test_conversion_single_additional("\n\nremotesync func", "\n\n@rpc(any_peer, call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); + valid = valid & test_conversion_single_additional("\n\nsync func", "\n\n@rpc(any_peer, call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); + valid = valid & test_conversion_single_additional("\n\nslave func", "\n\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); + valid = valid & test_conversion_single_additional("\n\npuppet func", "\n\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); + valid = valid & test_conversion_single_additional("\n\npuppetsync func", "\n\n@rpc(call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); + valid = valid & test_conversion_single_additional("\n\nmaster func", "\n\nThe master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); + valid = valid & test_conversion_single_additional("\n\nmastersync func", "\n\nThe master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n@rpc(call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword"); + + valid = valid & test_conversion_single_additional_builtin("var size : Vector2 = Vector2() setget set_function , get_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Copy here content of get_function\n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("var size : Vector2 = Vector2() setget set_function , ", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Non existent get function \n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("var size : Vector2 = Vector2() setget set_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Non existent get function \n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("var size : Vector2 = Vector2() setget , get_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Copy here content of get_function \n set(mod_value):\n mod_value # TODOConverter40 Non existent set function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("get_node(@", "get_node(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("yield(this, \"timeout\")", "await this.timeout", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("yield(this, \"timeout\")", "await this.\"timeout\"", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, true); + + valid = valid & test_conversion_single_additional_builtin(" Transform.xform(Vector3(a,b,c)) ", " Transform * Vector3(a,b,c) ", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin(" Transform.xform_inv(Vector3(a,b,c)) ", " Vector3(a,b,c) * Transform ", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("export(float) var lifetime = 3.0", "export var lifetime: float = 3.0", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("export(String, 'AnonymousPro', 'CourierPrime') var _font_name = 'AnonymousPro'", "export var _font_name = 'AnonymousPro' # (String, 'AnonymousPro', 'CourierPrime')", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); // TODO, this is only a workaround + valid = valid & test_conversion_single_additional_builtin("export(PackedScene) var mob_scene", "export var mob_scene: PackedScene", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("var d = parse_json(roman(sfs))", "var test_json_conv = JSON.new()\ntest_json_conv.parse(roman(sfs))\nvar d = test_json_conv.get_data()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("to_json( AA ) szon", "JSON.new().stringify( AA ) szon", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("s to_json", "s JSON.new().stringify", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("AF to_json2", "AF to_json2", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("var rr = JSON.parse(a)", "var test_json_conv = JSON.new()\ntest_json_conv.parse(a)\nvar rr = test_json_conv.get_data()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("empty()", "is_empty()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin(".empty", ".empty", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin(").roman(", ").roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("\t.roman(", "\tsuper.roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin(" .roman(", " super.roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin(".1", ".1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin(" .1", " .1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("'.'", "'.'", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("'.a'", "'.a'", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("\t._input(_event)", "\tsuper._input(_event)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("(connect(A,B,C) != OK):", "(connect(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("(connect(A,B,C,D) != OK):", "(connect(A,Callable(B,C).bind(D)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("(connect(A,B,C,[D]) != OK):", "(connect(A,Callable(B,C).bind(D)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("(connect(A,B,C,D,E) != OK):", "(connect(A,Callable(B,C).bind(D),E) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("(start(A,B) != OK):", "(start(Callable(A,B)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("(start(A,B,C,D,E,F,G) != OK):", "(start(Callable(A,B).bind(C),D,E,F,G) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("disconnect(A,B,C) != OK):", "disconnect(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("is_connected(A,B,C) != OK):", "is_connected(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("is_connected(A,B,C))", "is_connected(A,Callable(B,C)))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("func _init(p_x:int)->void:", "func _init(p_x:int):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("q_PackedDataContainer._iter_init(variable1)", "q_PackedDataContainer._iter_init(variable1)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("assert(speed < 20, str(randi()%10))", "assert(speed < 20) #,str(randi()%10))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("assert(speed < 2)", "assert(speed < 2)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("assert(false, \"Missing type --\" + str(argument.type) + \"--, needs to be added to project\")", "assert(false) #,\"Missing type --\" + str(argument.type) + \"--, needs to be added to project\")", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("create_from_image(aa, bb)", "create_from_image(aa) #,bb", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("q_ImageTexture.create_from_image(variable1, variable2)", "q_ImageTexture.create_from_image(variable1) #,variable2", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("set_cell_item(a, b, c, d ,e) # AA", "set_cell_item( Vector3(a,b,c) ,d,e) # AA", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("set_cell_item(a, b)", "set_cell_item(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("get_cell_item_orientation(a, b,c)", "get_cell_item_orientation(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("get_cell_item(a, b,c)", "get_cell_item(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("map_to_world(a, b,c)", "map_to_world(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("PackedStringArray(req_godot).join('.')", "'.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("=PackedStringArray(req_godot).join('.')", "='.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin(" aa", " aa", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("\taa", "\taa", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("\t aa", "\taa", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin(" \taa", " \taa", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + + valid = valid & test_conversion_single_additional_builtin("apply_force(position, impulse)", "apply_force(impulse, position)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid & test_conversion_single_additional_builtin("apply_impulse(position, impulse)", "apply_impulse(impulse, position)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid & test_conversion_single_additional("AAA Color.white AF", "AAA Color.WHITE AF", &ProjectConverter3To4::rename_enums, "custom rename"); @@ -2517,7 +2577,7 @@ Vector<String> ProjectConverter3To4::check_for_rename_enums(Vector<String> &file int current_line = 1; for (String &line : file_content) { - Array reg_match = reg.search_all(line); + TypedArray<RegExMatch> reg_match = reg.search_all(line); if (reg_match.size() > 0) { found_things.append(line_formatter(current_line, colors_renames[current_index][0], colors_renames[current_index][1], line)); } @@ -2533,7 +2593,7 @@ Vector<String> ProjectConverter3To4::check_for_rename_enums(Vector<String> &file void ProjectConverter3To4::rename_classes(String &file_content) { int current_index = 0; - // TODO Maybe it is better way to not rename gd, tscn and other files which are named are classes + // TODO Maybe it is better way to not rename gd, tscn and other files which are named as classes while (class_renames[current_index][0]) { // Begin renaming workaround `Resource.gd` -> `RefCounter.gd` RegEx reg_before = RegEx(String("\\b") + class_renames[current_index][0] + ".tscn\\b"); @@ -2594,7 +2654,7 @@ Vector<String> ProjectConverter3To4::check_for_rename_classes(Vector<String> &fi line = reg_before.sub(line, "TEMP_RENAMED_CLASS.tscn", true); line = reg_before2.sub(line, "TEMP_RENAMED_CLASS.gd", true); - Array reg_match = reg.search_all(line); + TypedArray<RegExMatch> reg_match = reg.search_all(line); if (reg_match.size() > 0) { found_things.append(line_formatter(current_line, class_renames[current_index][0], class_renames[current_index][1], line)); } @@ -2623,432 +2683,11 @@ Vector<String> ProjectConverter3To4::check_for_rename_classes(Vector<String> &fi return found_things; } -void ProjectConverter3To4::rename_gdscript_functions(String &file_content) { - // Custom renaming, each rule needs to be set manually - // Don't forget to put validate each rule in validate_conversion function +void ProjectConverter3To4::rename_gdscript_functions(String &file_content, const RegExContainer ®_container, bool builtin) { Vector<String> lines = file_content.split("\n"); - RegEx reg_is_empty = RegEx("\\bempty\\("); - RegEx reg_super = RegEx("([\t ])\\.([a-zA-Z_])"); - RegEx reg_json_to = RegEx("\\bto_json\\b"); - RegEx reg_json_parse = RegEx("([\t]{0,})([^\n]+)parse_json\\(([^\n]+)"); - RegEx reg_json_non_new = RegEx("([\t]{0,})([^\n]+)JSON\\.parse\\(([^\n]+)"); - RegEx reg_export = RegEx("export\\(([a-zA-Z0-9_]+)\\)[ ]+var[ ]+([a-zA-Z0-9_]+)"); - RegEx reg_export_advanced = RegEx("export\\(([^)^\n]+)\\)[ ]+var[ ]+([a-zA-Z0-9_]+)([^\n]+)"); - RegEx reg_setget_setget = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+([a-zA-Z0-9_]+)[ \t]*,[ \t]*([a-zA-Z0-9_]+)"); - RegEx reg_setget_set = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+([a-zA-Z0-9_]+)[ \t]*[,]*[^a-z^A-Z^0-9^_]*$"); - RegEx reg_setget_get = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+,[ \t]*([a-zA-Z0-9_]+)[ \t]*$"); - RegEx reg_join = RegEx("([\\(\\)a-zA-Z0-9_]+)\\.join\\(([^\n^\\)]+)\\)"); - RegEx reg_mixed_tab_space = RegEx("([\t]+)([ ]+)"); - RegEx reg_image_lock = RegEx("([a-zA-Z0-9_\\.]+)\\.lock\\(\\)"); - RegEx reg_image_unlock = RegEx("([a-zA-Z0-9_\\.]+)\\.unlock\\(\\)"); - RegEx reg_os_fullscreen = RegEx("OS.window_fullscreen[= ]+([^#^\n]+)"); - - CRASH_COND(!reg_is_empty.is_valid()); - CRASH_COND(!reg_super.is_valid()); - CRASH_COND(!reg_json_to.is_valid()); - CRASH_COND(!reg_json_parse.is_valid()); - CRASH_COND(!reg_json_non_new.is_valid()); - CRASH_COND(!reg_export.is_valid()); - CRASH_COND(!reg_export_advanced.is_valid()); - CRASH_COND(!reg_setget_setget.is_valid()); - CRASH_COND(!reg_setget_set.is_valid()); - CRASH_COND(!reg_setget_get.is_valid()); - CRASH_COND(!reg_join.is_valid()); - CRASH_COND(!reg_mixed_tab_space.is_valid()); - CRASH_COND(!reg_image_lock.is_valid()); - CRASH_COND(!reg_image_unlock.is_valid()); - CRASH_COND(!reg_os_fullscreen.is_valid()); - for (String &line : lines) { - if (line.find("mtx") == -1 && line.find("mutex") == -1 && line.find("Mutex") == -1) { - line = reg_image_lock.sub(line, "false # $1.lock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", true); - line = reg_image_unlock.sub(line, "false # $1.unlock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", true); - } - - // Mixed use of spaces and tabs - tabs as first - TODO, this probably is problem problem, but not sure - line = reg_mixed_tab_space.sub(line, "$1", true); - - // PackedStringArray(req_godot).join('.') -> '.'.join(PackedStringArray(req_godot)) PoolStringArray - line = reg_join.sub(line, "$2.join($1)", true); - - // -- empty() -> is_empty() Pool*Array - line = reg_is_empty.sub(line, "is_empty(", true); - - // -- \t.func() -> \tsuper.func() Object - line = reg_super.sub(line, "$1super.$2", true); // TODO, not sure if possible, but for now this brake String text e.g. "Choosen .gitignore" -> "Choosen super.gitignore" - - // -- JSON.parse(a) -> JSON.new().parse(a) etc. JSON - line = reg_json_non_new.sub(line, "$1var test_json_conv = JSON.new()\n$1test_json_conv.parse($3\n$1$2test_json_conv.get_data()", true); - - // -- to_json(a) -> JSON.new().stringify(a) Object - line = reg_json_to.sub(line, "JSON.new().stringify", true); - - // -- parse_json(a) -> JSON.get_data() etc. Object - line = reg_json_parse.sub(line, "$1var test_json_conv = JSON.new()\n$1test_json_conv.parse($3\n$1$2test_json_conv.get_data()", true); - - // -- get_node(@ -> get_node( Node - line = line.replace("get_node(@", "get_node("); - - // export(float) var lifetime = 3.0 -> export var lifetime: float = 3.0 GDScript - line = reg_export.sub(line, "export var $2: $1"); - - // export(String, 'AnonymousPro', 'CourierPrime') var _font_name = 'AnonymousPro' -> export var _font_name = 'AnonymousPro' #(String, 'AnonymousPro', 'CourierPrime') GDScript - line = reg_export_advanced.sub(line, "export var $2$3 # ($1)"); - - // Setget Setget - line = reg_setget_setget.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Copy here content of $4\n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Copy here content of $3", true); - - // Setget set - line = reg_setget_set.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Non existent get function \n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Copy here content of $3", true); - - // Setget get - line = reg_setget_get.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Copy here content of $3 \n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Non existent set function", true); - - // OS.window_fullscreen = true -> ProjectSettings.set("display/window/size/fullscreen",true) - line = reg_os_fullscreen.sub(line, "ProjectSettings.set(\"display/window/size/fullscreen\", $1)", true); - - // -- r.move_and_slide( a, b, c, d, e ) -> r.set_motion_velocity(a) ... r.move_and_slide() KinematicBody - if (line.find("move_and_slide(") != -1) { - int start = line.find("move_and_slide("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - String base_obj = get_object_of_execution(line.substr(0, start)); - String starting_space = get_starting_space(line); - - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() >= 1) { - String line_new; - - // motion_velocity - line_new += starting_space + base_obj + "set_motion_velocity(" + parts[0] + ")\n"; - - // up_direction - if (parts.size() >= 2) { - line_new += starting_space + base_obj + "set_up_direction(" + parts[1] + ")\n"; - } - - // stop_on_slope - if (parts.size() >= 3) { - line_new += starting_space + base_obj + "set_floor_stop_on_slope_enabled(" + parts[2] + ")\n"; - } - - // max_slides - if (parts.size() >= 4) { - line_new += starting_space + base_obj + "set_max_slides(" + parts[3] + ")\n"; - } - - // floor_max_angle - if (parts.size() >= 5) { - line_new += starting_space + base_obj + "set_floor_max_angle(" + parts[4] + ")\n"; - } - - // infiinite_interia - if (parts.size() >= 6) { - line_new += starting_space + "# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `" + parts[5] + "`\n"; - } - - line = line_new + line.substr(0, start) + "move_and_slide()" + line.substr(end + start); - } - } - } - - // -- r.move_and_slide_with_snap( a, b, c, d, e ) -> r.set_motion_velocity(a) ... r.move_and_slide() KinematicBody - if (line.find("move_and_slide_with_snap(") != -1) { - int start = line.find("move_and_slide_with_snap("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - String base_obj = get_object_of_execution(line.substr(0, start)); - String starting_space = get_starting_space(line); - - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() >= 1) { - String line_new; - - // motion_velocity - line_new += starting_space + base_obj + "set_motion_velocity(" + parts[0] + ")\n"; - - // snap - if (parts.size() >= 2) { - line_new += starting_space + "# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `" + parts[1] + "`\n"; - } - - // up_direction - if (parts.size() >= 3) { - line_new += starting_space + base_obj + "set_up_direction(" + parts[2] + ")\n"; - } - - // stop_on_slope - if (parts.size() >= 4) { - line_new += starting_space + base_obj + "set_floor_stop_on_slope_enabled(" + parts[3] + ")\n"; - } - - // max_slides - if (parts.size() >= 5) { - line_new += starting_space + base_obj + "set_max_slides(" + parts[4] + ")\n"; - } - - // floor_max_angle - if (parts.size() >= 6) { - line_new += starting_space + base_obj + "set_floor_max_angle(" + parts[5] + ")\n"; - } - - // infiinite_interia - if (parts.size() >= 7) { - line_new += starting_space + "# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `" + parts[6] + "`\n"; - } - - line = line_new + line.substr(0, start) + "move_and_slide()" + line.substr(end + start); - } - } - } - - // -- sort_custom( a , b ) -> sort_custom(Callable( a , b )) Object - if (line.find("sort_custom(") != -1) { - int start = line.find("sort_custom("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "sort_custom(Callable(" + parts[0] + "," + parts[1] + "))" + line.substr(end + start); - } - } - } - - // -- list_dir_begin( ) -> list_dir_begin() Object - if (line.find("list_dir_begin(") != -1) { - int start = line.find("list_dir_begin("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - line = line.substr(0, start) + "list_dir_begin() " + line.substr(end + start) + "# TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547"; - } - } - - // -- draw_line(1,2,3,4,5) -> draw_line(1,2,3,4) CanvasItem - if (line.find("draw_line(") != -1) { - int start = line.find("draw_line("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 5) { - line = line.substr(0, start) + "draw_line(" + parts[0] + "," + parts[1] + "," + parts[2] + "," + parts[3] + ")" + line.substr(end + start); - } - } - } - - // -- func c(var a, var b) -> func c(a, b) - if (line.find("func ") != -1 && line.find("var ") != -1) { - int start = line.find("func "); - start = line.substr(start).find("(") + start; - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - - String start_string = line.substr(0, start) + "("; - for (int i = 0; i < parts.size(); i++) { - start_string += parts[i].strip_edges().trim_prefix("var "); - if (i != parts.size() - 1) { - start_string += ", "; - } - } - line = start_string + ")" + line.substr(end + start); - } - } - - // -- yield(this, \"timeout\") -> await this.timeout GDScript - if (line.find("yield(") != -1) { - int start = line.find("yield("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "await " + parts[0] + "." + parts[1].replace("\"", "").replace("\'", "").replace(" ", "") + line.substr(end + start); - } - } - } - - // -- parse_json( AA ) -> TODO Object - if (line.find("parse_json(") != -1) { - int start = line.find("parse_json("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - line = line.substr(0, start) + "JSON.new().stringify(" + connect_arguments(parts, 0) + ")" + line.substr(end + start); - } - } - - // -- .xform(Vector3(a,b,c)) -> * Vector3(a,b,c) Transform - if (line.find(".xform(") != -1) { - int start = line.find(".xform("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 1) { - line = line.substr(0, start) + " * " + parts[0] + line.substr(end + start); - } - } - } - - // -- .xform_inv(Vector3(a,b,c)) -> * Vector3(a,b,c) Transform - if (line.find(".xform_inv(") != -1) { - int start = line.find(".xform_inv("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - String object_exec = get_object_of_execution(line.substr(0, start)); - if (line.find(object_exec + ".xform") != -1) { - int start2 = line.find(object_exec + ".xform"); - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 1) { - line = line.substr(0, start2) + parts[0] + " * " + object_exec + line.substr(end + start); - } - } - } - } - - // -- connect(,,,things) -> connect(,Callable(,),things) Object - if (line.find("connect(") != -1) { - int start = line.find("connect("); - // Protection from disconnect - if (start == 0 || line.get(start - 1) != 's') { - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() >= 3) { - line = line.substr(0, start) + "connect(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + ")" + connect_arguments(parts, 3) + ")" + line.substr(end + start); - } - } - } - } - // -- disconnect(a,b,c) -> disconnect(a,Callable(b,c)) Object - if (line.find("disconnect(") != -1) { - int start = line.find("disconnect("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "disconnect(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } - } - } - // -- is_connected(a,b,c) -> is_connected(a,Callable(b,c)) Object - if (line.find("is_connected(") != -1) { - int start = line.find("is_connected("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "is_connected(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } - } - } - // -- start(a,b,c) -> start(a,Callable(b,c)) Thread - if (line.find("start(") != -1) { - int start = line.find("start("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() >= 3) { - line = line.substr(0, start) + "start(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + ")" + connect_arguments(parts, 3) + ")" + line.substr(end + start); - } - } - } - // -- func _init(p_x:int)->void: -> func _init(p_x:int): Object # https://github.com/godotengine/godot/issues/50589 - if (line.find(" _init(") != -1) { - int start = line.find(" _init("); - int end = line.rfind(":") + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - line = line.substr(0, start) + " _init(" + connect_arguments(parts, 0) + "):" + line.substr(end + start); - } - } - // assert(speed < 20, str(randi()%10)) -> assert(speed < 20) #,str(randi()%10)) GDScript - GDScript bug constant message - if (line.find("assert(") != -1) { - int start = line.find("assert("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "assert(" + parts[0] + ") " + line.substr(end + start) + "#," + parts[1] + ")"; - } - } - } - // create_from_image(aa, bb) -> create_from_image(aa) #, bb ImageTexture - if (line.find("create_from_image(") != -1) { - int start = line.find("create_from_image("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "create_from_image(" + parts[0] + ") " + "#," + parts[1] + line.substr(end + start); - } - } - } - // set_cell_item(a, b, c, d ,e) -> set_cell_item(Vector3(a, b, c), d ,e) - if (line.find("set_cell_item(") != -1) { - int start = line.find("set_cell_item("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() > 2) { - line = line.substr(0, start) + "set_cell_item( Vector3(" + parts[0] + "," + parts[1] + "," + parts[2] + ") " + connect_arguments(parts, 3) + ")" + line.substr(end + start); - } - } - } - // get_cell_item(a, b, c) -> get_cell_item(Vector3i(a, b, c)) - if (line.find("get_cell_item(") != -1) { - int start = line.find("get_cell_item("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "get_cell_item(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } - } - } - // get_cell_item_orientation(a, b, c) -> get_cell_item_orientation(Vector3i(a, b, c)) - if (line.find("get_cell_item_orientation(") != -1) { - int start = line.find("get_cell_item_orientation("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "get_cell_item_orientation(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } - } - } - // apply_impulse(A, B) -> apply_impulse(B, A) - if (line.find("apply_impulse(") != -1) { - int start = line.find("apply_impulse("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "apply_impulse(" + parts[1] + ", " + parts[0] + ")" + line.substr(end + start); - } - } - } - // apply_force(A, B) -> apply_force(B, A) - if (line.find("apply_force(") != -1) { - int start = line.find("apply_force("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "apply_force(" + parts[1] + ", " + parts[0] + ")" + line.substr(end + start); - } - } - } - // map_to_world(a, b, c) -> map_to_world(Vector3i(a, b, c)) - if (line.find("map_to_world(") != -1) { - int start = line.find("map_to_world("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "map_to_world(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } - } - } + process_gdscript_line(line, reg_container, builtin); } // Collect vector to string @@ -3062,478 +2701,484 @@ void ProjectConverter3To4::rename_gdscript_functions(String &file_content) { } }; -// This is almost 1:1 copy of function which rename gdscript functions -Vector<String> ProjectConverter3To4::check_for_rename_gdscript_functions(Vector<String> &file_content) { +Vector<String> ProjectConverter3To4::check_for_rename_gdscript_functions(Vector<String> &file_content, const RegExContainer ®_container, bool builtin) { int current_line = 1; Vector<String> found_things; - RegEx reg_is_empty = RegEx("\\bempty\\("); - RegEx reg_super = RegEx("([\t ])\\.([a-zA-Z_])"); - RegEx reg_json_to = RegEx("\\bto_json\\b"); - RegEx reg_json_parse = RegEx("([\t]{0,})([^\n]+)parse_json\\(([^\n]+)"); - RegEx reg_json_non_new = RegEx("([\t]{0,})([^\n]+)JSON\\.parse\\(([^\n]+)"); - RegEx reg_export = RegEx("export\\(([a-zA-Z0-9_]+)\\)[ ]+var[ ]+([a-zA-Z0-9_]+)"); - RegEx reg_export_advanced = RegEx("export\\(([^)^\n]+)\\)[ ]+var[ ]+([a-zA-Z0-9_]+)([^\n]+)"); - RegEx reg_setget_setget = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+([a-zA-Z0-9_]+)[ \t]*,[ \t]*([a-zA-Z0-9_]+)"); - RegEx reg_setget_set = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+([a-zA-Z0-9_]+)[ \t]*[,]*[^a-z^A-Z^0-9^_]*$"); - RegEx reg_setget_get = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+,[ \t]*([a-zA-Z0-9_]+)[ \t]*$"); - RegEx reg_join = RegEx("([\\(\\)a-zA-Z0-9_]+)\\.join\\(([^\n^\\)]+)\\)"); - RegEx reg_mixed_tab_space = RegEx("([\t]+)([ ]+)"); - RegEx reg_image_lock = RegEx("([a-zA-Z0-9_\\.]+)\\.lock\\(\\)"); - RegEx reg_image_unlock = RegEx("([a-zA-Z0-9_\\.]+)\\.unlock\\(\\)"); - RegEx reg_os_fullscreen = RegEx("OS.window_fullscreen[= ]+([^#^\n]+)"); - - CRASH_COND(!reg_is_empty.is_valid()); - CRASH_COND(!reg_super.is_valid()); - CRASH_COND(!reg_json_to.is_valid()); - CRASH_COND(!reg_json_parse.is_valid()); - CRASH_COND(!reg_json_non_new.is_valid()); - CRASH_COND(!reg_export.is_valid()); - CRASH_COND(!reg_export_advanced.is_valid()); - CRASH_COND(!reg_setget_setget.is_valid()); - CRASH_COND(!reg_setget_set.is_valid()); - CRASH_COND(!reg_setget_get.is_valid()); - CRASH_COND(!reg_join.is_valid()); - CRASH_COND(!reg_mixed_tab_space.is_valid()); - CRASH_COND(!reg_image_lock.is_valid()); - CRASH_COND(!reg_image_unlock.is_valid()); - CRASH_COND(!reg_os_fullscreen.is_valid()); - for (String &line : file_content) { String old_line = line; - - if (line.find("mtx") == -1 && line.find("mutex") == -1 && line.find("Mutex") == -1) { - line = reg_image_lock.sub(line, "false # $1.lock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", true); - line = reg_image_unlock.sub(line, "false # $1.unlock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", true); + process_gdscript_line(line, reg_container, builtin); + if (old_line != line) { + found_things.append(simple_line_formatter(current_line, old_line, line)); } + } - // Mixed use of spaces and tabs - tabs as first - TODO, this probably is problem problem, but not sure - line = reg_mixed_tab_space.sub(line, "$1", true); + return found_things; +} +void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContainer ®_container, bool builtin) { + if (line.find("mtx") == -1 && line.find("mutex") == -1 && line.find("Mutex") == -1) { + line = reg_container.reg_image_lock.sub(line, "false # $1.lock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", true); + line = reg_container.reg_image_unlock.sub(line, "false # $1.unlock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", true); + } - // PackedStringArray(req_godot).join('.') -> '.'.join(PackedStringArray(req_godot)) PoolStringArray - line = reg_join.sub(line, "$2.join($1)", true); + // Mixed use of spaces and tabs - tabs as first - TODO, this probably is problem problem, but not sure + line = reg_container.reg_mixed_tab_space.sub(line, "$1", true); - // -- empty() -> is_empty() Pool*Array - line = reg_is_empty.sub(line, "is_empty(", true); + // PackedStringArray(req_godot).join('.') -> '.'.join(PackedStringArray(req_godot)) PoolStringArray + line = reg_container.reg_join.sub(line, "$2.join($1)", true); - // -- \t.func() -> \tsuper.func() Object - line = reg_super.sub(line, "$1super.$2", true); // TODO, not sure if possible, but for now this brake String text e.g. "Choosen .gitignore" -> "Choosen super.gitignore" + // -- empty() -> is_empty() Pool*Array + line = reg_container.reg_is_empty.sub(line, "is_empty(", true); - // -- JSON.parse(a) -> JSON.new().parse(a) etc. JSON - line = reg_json_non_new.sub(line, "$1var test_json_conv = JSON.new()\n$1test_json_conv.parse($3\n$1$2test_json_conv.get_data()", true); + // -- \t.func() -> \tsuper.func() Object + line = reg_container.reg_super.sub(line, "$1super.$2", true); // TODO, not sure if possible, but for now this brake String text e.g. "Choosen .gitignore" -> "Choosen super.gitignore" - // -- to_json(a) -> JSON.new().stringify(a) Object - line = reg_json_to.sub(line, "JSON.new().stringify", true); + // -- JSON.parse(a) -> JSON.new().parse(a) etc. JSON + line = reg_container.reg_json_non_new.sub(line, "$1var test_json_conv = JSON.new()\n$1test_json_conv.parse($3\n$1$2test_json_conv.get_data()", true); - // -- parse_json(a) -> JSON.get_data() etc. Object - line = reg_json_parse.sub(line, "$1var test_json_conv = JSON.new()\n$1test_json_conv.parse($3\n$1$2test_json_conv.get_data()", true); + // -- to_json(a) -> JSON.new().stringify(a) Object + line = reg_container.reg_json_to.sub(line, "JSON.new().stringify", true); - // -- get_node(@ -> get_node( Node - line = line.replace("get_node(@", "get_node("); + // -- parse_json(a) -> JSON.get_data() etc. Object + line = reg_container.reg_json_parse.sub(line, "$1var test_json_conv = JSON.new()\n$1test_json_conv.parse($3\n$1$2test_json_conv.get_data()", true); - // export(float) var lifetime = 3.0 -> export var lifetime: float = 3.0 GDScript - line = reg_export.sub(line, "export var $2: $1"); + // -- get_node(@ -> get_node( Node + line = line.replace("get_node(@", "get_node("); - // export(String, 'AnonymousPro', 'CourierPrime') var _font_name = 'AnonymousPro' -> export var _font_name = 'AnonymousPro' #(String, 'AnonymousPro', 'CourierPrime') GDScript - line = reg_export_advanced.sub(line, "export var $2$3 # ($1)"); + // export(float) var lifetime = 3.0 -> export var lifetime: float = 3.0 GDScript + line = reg_container.reg_export.sub(line, "export var $2: $1"); - // Setget Setget - line = reg_setget_setget.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Copy here content of $4\n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Copy here content of $3", true); + // export(String, 'AnonymousPro', 'CourierPrime') var _font_name = 'AnonymousPro' -> export var _font_name = 'AnonymousPro' #(String, 'AnonymousPro', 'CourierPrime') GDScript + line = reg_container.reg_export_advanced.sub(line, "export var $2$3 # ($1)"); - // Setget set - line = reg_setget_set.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Non existent get function \n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Copy here content of $3", true); + // Setget Setget + line = reg_container.reg_setget_setget.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Copy here content of $4\n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Copy here content of $3", true); - // Setget get - line = reg_setget_get.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Copy here content of $3 \n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Non existent set function", true); + // Setget set + line = reg_container.reg_setget_set.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Non existent get function \n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Copy here content of $3", true); - // OS.window_fullscreen = true -> ProjectSettings.set("display/window/size/fullscreen",true) - line = reg_os_fullscreen.sub(line, "ProjectSettings.set(\"display/window/size/fullscreen\", $1)", true); + // Setget get + line = reg_container.reg_setget_get.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Copy here content of $3 \n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Non existent set function", true); - // -- r.move_and_slide( a, b, c, d, e ) -> r.set_motion_velocity(a) ... r.move_and_slide() KinematicBody - if (line.find("move_and_slide(") != -1) { - int start = line.find("move_and_slide("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - String base_obj = get_object_of_execution(line.substr(0, start)); - String starting_space = get_starting_space(line); + // OS.window_fullscreen = true -> ProjectSettings.set("display/window/size/fullscreen",true) + if (builtin) { + line = reg_container.reg_os_fullscreen.sub(line, "ProjectSettings.set(\\\"display/window/size/fullscreen\\\", $1)", true); + } else { + line = reg_container.reg_os_fullscreen.sub(line, "ProjectSettings.set(\"display/window/size/fullscreen\", $1)", true); + } - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() >= 1) { - String line_new; + // -- r.move_and_slide( a, b, c, d, e ) -> r.set_motion_velocity(a) ... r.move_and_slide() KinematicBody + if (line.find("move_and_slide(") != -1) { + int start = line.find("move_and_slide("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + String base_obj = get_object_of_execution(line.substr(0, start)); + String starting_space = get_starting_space(line); - // motion_velocity - line_new += starting_space + base_obj + "set_motion_velocity(" + parts[0] + ")\n"; + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() >= 1) { + String line_new; - // up_direction - if (parts.size() >= 2) { - line_new += starting_space + base_obj + "set_up_direction(" + parts[1] + ")\n"; - } + // motion_velocity + line_new += starting_space + base_obj + "set_motion_velocity(" + parts[0] + ")\n"; - // stop_on_slope - if (parts.size() >= 3) { - line_new += starting_space + base_obj + "set_floor_stop_on_slope_enabled(" + parts[2] + ")\n"; - } + // up_direction + if (parts.size() >= 2) { + line_new += starting_space + base_obj + "set_up_direction(" + parts[1] + ")\n"; + } - // max_slides - if (parts.size() >= 4) { - line_new += starting_space + base_obj + "set_max_slides(" + parts[3] + ")\n"; - } + // stop_on_slope + if (parts.size() >= 3) { + line_new += starting_space + base_obj + "set_floor_stop_on_slope_enabled(" + parts[2] + ")\n"; + } - // floor_max_angle - if (parts.size() >= 5) { - line_new += starting_space + base_obj + "set_floor_max_angle(" + parts[4] + ")\n"; - } + // max_slides + if (parts.size() >= 4) { + line_new += starting_space + base_obj + "set_max_slides(" + parts[3] + ")\n"; + } - // infiinite_interia - if (parts.size() >= 6) { - line_new += starting_space + "# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `" + parts[5] + "`\n"; - } + // floor_max_angle + if (parts.size() >= 5) { + line_new += starting_space + base_obj + "set_floor_max_angle(" + parts[4] + ")\n"; + } - line = line_new + line.substr(0, start) + "move_and_slide()" + line.substr(end + start); + // infiinite_interia + if (parts.size() >= 6) { + line_new += starting_space + "# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `" + parts[5] + "`\n"; } + + line = line_new + line.substr(0, start) + "move_and_slide()" + line.substr(end + start); } } + } - // -- r.move_and_slide_with_snap( a, b, c, d, e ) -> r.set_motion_velocity(a) ... r.move_and_slide() KinematicBody - if (line.find("move_and_slide_with_snap(") != -1) { - int start = line.find("move_and_slide_with_snap("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - String base_obj = get_object_of_execution(line.substr(0, start)); - String starting_space = get_starting_space(line); - - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() >= 1) { - String line_new; + // -- r.move_and_slide_with_snap( a, b, c, d, e ) -> r.set_motion_velocity(a) ... r.move_and_slide() KinematicBody + if (line.find("move_and_slide_with_snap(") != -1) { + int start = line.find("move_and_slide_with_snap("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + String base_obj = get_object_of_execution(line.substr(0, start)); + String starting_space = get_starting_space(line); - // motion_velocity - line_new += starting_space + base_obj + "set_motion_velocity(" + parts[0] + ")\n"; + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() >= 1) { + String line_new; - // snap - if (parts.size() >= 2) { - line_new += starting_space + "# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `" + parts[1] + "`\n"; - } + // motion_velocity + line_new += starting_space + base_obj + "set_motion_velocity(" + parts[0] + ")\n"; - // up_direction - if (parts.size() >= 3) { - line_new += starting_space + base_obj + "set_up_direction(" + parts[2] + ")\n"; - } + // snap + if (parts.size() >= 2) { + line_new += starting_space + "# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `" + parts[1] + "`\n"; + } - // stop_on_slope - if (parts.size() >= 4) { - line_new += starting_space + base_obj + "set_floor_stop_on_slope_enabled(" + parts[3] + ")\n"; - } + // up_direction + if (parts.size() >= 3) { + line_new += starting_space + base_obj + "set_up_direction(" + parts[2] + ")\n"; + } - // max_slides - if (parts.size() >= 5) { - line_new += starting_space + base_obj + "set_max_slides(" + parts[4] + ")\n"; - } + // stop_on_slope + if (parts.size() >= 4) { + line_new += starting_space + base_obj + "set_floor_stop_on_slope_enabled(" + parts[3] + ")\n"; + } - // floor_max_angle - if (parts.size() >= 6) { - line_new += starting_space + base_obj + "set_floor_max_angle(" + parts[5] + ")\n"; - } + // max_slides + if (parts.size() >= 5) { + line_new += starting_space + base_obj + "set_max_slides(" + parts[4] + ")\n"; + } - // infiinite_interia - if (parts.size() >= 7) { - line_new += starting_space + "# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `" + parts[6] + "`\n"; - } + // floor_max_angle + if (parts.size() >= 6) { + line_new += starting_space + base_obj + "set_floor_max_angle(" + parts[5] + ")\n"; + } - line = line_new + line.substr(0, start) + "move_and_slide()" + line.substr(end + start); + // infiinite_interia + if (parts.size() >= 7) { + line_new += starting_space + "# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `" + parts[6] + "`\n"; } + + line = line_new + line.substr(0, start) + "move_and_slide()" + line.substr(end + start); } } + } - // -- sort_custom( a , b ) -> sort_custom(Callable( a , b )) Object - if (line.find("sort_custom(") != -1) { - int start = line.find("sort_custom("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "sort_custom(Callable(" + parts[0] + "," + parts[1] + "))" + line.substr(end + start); - } + // -- sort_custom( a , b ) -> sort_custom(Callable( a , b )) Object + if (line.find("sort_custom(") != -1) { + int start = line.find("sort_custom("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 2) { + line = line.substr(0, start) + "sort_custom(Callable(" + parts[0] + "," + parts[1] + "))" + line.substr(end + start); } } + } - // -- draw_line(1,2,3,4,5) -> draw_line(1,2,3,4) CanvasItem - if (line.find("draw_line(") != -1) { - int start = line.find("draw_line("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 5) { - line = line.substr(0, start) + "draw_line(" + parts[0] + "," + parts[1] + "," + parts[2] + "," + parts[3] + ")" + line.substr(end + start); - } - } + // -- list_dir_begin( ) -> list_dir_begin() Object + if (line.find("list_dir_begin(") != -1) { + int start = line.find("list_dir_begin("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + line = line.substr(0, start) + "list_dir_begin() " + line.substr(end + start) + "# TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547"; } + } - // -- func c(var a, var b) -> func c(a, b) - if (line.find("func ") != -1 && line.find("var ") != -1) { - int start = line.find("func "); - start = line.substr(start).find("(") + start; - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); + // -- draw_line(1,2,3,4,5) -> draw_line(1,2,3,4) CanvasItem + if (line.find("draw_line(") != -1) { + int start = line.find("draw_line("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 5) { + line = line.substr(0, start) + "draw_line(" + parts[0] + "," + parts[1] + "," + parts[2] + "," + parts[3] + ")" + line.substr(end + start); + } + } + } - String start_string = line.substr(0, start) + "("; - for (int i = 0; i < parts.size(); i++) { - start_string += parts[i].strip_edges().trim_prefix("var "); - if (i != parts.size() - 1) { - start_string += ", "; - } + // -- func c(var a, var b) -> func c(a, b) + if (line.find("func ") != -1 && line.find("var ") != -1) { + int start = line.find("func "); + start = line.substr(start).find("(") + start; + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + + String start_string = line.substr(0, start) + "("; + for (int i = 0; i < parts.size(); i++) { + start_string += parts[i].strip_edges().trim_prefix("var "); + if (i != parts.size() - 1) { + start_string += ", "; } - line = start_string + ")" + line.substr(end + start); } + line = start_string + ")" + line.substr(end + start); } + } - // -- yield(this, \"timeout\") -> await this.timeout GDScript - if (line.find("yield(") != -1) { - int start = line.find("yield("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { + // -- yield(this, \"timeout\") -> await this.timeout GDScript + if (line.find("yield(") != -1) { + int start = line.find("yield("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 2) { + if (builtin) { + line = line.substr(0, start) + "await " + parts[0] + "." + parts[1].replace(" ", "") + line.substr(end + start); + } else { line = line.substr(0, start) + "await " + parts[0] + "." + parts[1].replace("\"", "").replace("\'", "").replace(" ", "") + line.substr(end + start); } } } + } - // -- parse_json( AA ) -> TODO Object - if (line.find("parse_json(") != -1) { - int start = line.find("parse_json("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - line = line.substr(0, start) + "JSON.new().stringify(" + connect_arguments(parts, 0) + ")" + line.substr(end + start); - } + // -- parse_json( AA ) -> TODO Object + if (line.find("parse_json(") != -1) { + int start = line.find("parse_json("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + line = line.substr(0, start) + "JSON.new().stringify(" + connect_arguments(parts, 0) + ")" + line.substr(end + start); } + } - // -- .xform(Vector3(a,b,c)) -> * Vector3(a,b,c) Transform - if (line.find(".xform(") != -1) { - int start = line.find(".xform("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 1) { - line = line.substr(0, start) + " * " + parts[0] + line.substr(end + start); - } + // -- .xform(Vector3(a,b,c)) -> * Vector3(a,b,c) Transform + if (line.find(".xform(") != -1) { + int start = line.find(".xform("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 1) { + line = line.substr(0, start) + " * " + parts[0] + line.substr(end + start); } } + } - // -- .xform_inv(Vector3(a,b,c)) -> / Vector3(a,b,c) Transform - if (line.find(".xform_inv(") != -1) { - int start = line.find(".xform_inv("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { + // -- .xform_inv(Vector3(a,b,c)) -> * Vector3(a,b,c) Transform + if (line.find(".xform_inv(") != -1) { + int start = line.find(".xform_inv("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + String object_exec = get_object_of_execution(line.substr(0, start)); + if (line.find(object_exec + ".xform") != -1) { + int start2 = line.find(object_exec + ".xform"); Vector<String> parts = parse_arguments(line.substr(start, end)); if (parts.size() == 1) { - line = line.substr(0, start) + " / " + parts[0] + line.substr(end + start); + line = line.substr(0, start2) + parts[0] + " * " + object_exec + line.substr(end + start); } } } + } - // -- connect(,,,things) -> connect(,Callable(,),things) Object - if (line.find("connect(") != -1) { - int start = line.find("connect("); - // Protection from disconnect - if (start == 0 || line.get(start - 1) != 's') { - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() >= 3) { - line = line.substr(0, start) + "connect(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + ")" + connect_arguments(parts, 3) + ")" + line.substr(end + start); - } - } - } - } - // -- disconnect(a,b,c) -> disconnect(a,Callable(b,c)) Object - if (line.find("disconnect(") != -1) { - int start = line.find("disconnect("); + // -- "(connect(A,B,C,D,E) != OK):", "(connect(A,Callable(B,C).bind(D),E) Object + if (line.find("connect(") != -1) { + int start = line.find("connect("); + // Protection from disconnect + if (start == 0 || line.get(start - 1) != 's') { int end = get_end_parenthess(line.substr(start)) + 1; if (end > -1) { Vector<String> parts = parse_arguments(line.substr(start, end)); if (parts.size() == 3) { - line = line.substr(0, start) + "disconnect(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); + line = line.substr(0, start) + "connect(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); + } else if (parts.size() >= 4) { + line = line.substr(0, start) + "connect(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + ").bind(" + parts[3].lstrip("[").rstrip("]") + ")" + connect_arguments(parts, 4) + ")" + line.substr(end + start); } } } - // -- is_connected(a,b,c) -> is_connected(a,Callable(b,c)) Object - if (line.find("is_connected(") != -1) { - int start = line.find("is_connected("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "is_connected(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } + } + // -- disconnect(a,b,c) -> disconnect(a,Callable(b,c)) Object + if (line.find("disconnect(") != -1) { + int start = line.find("disconnect("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 3) { + line = line.substr(0, start) + "disconnect(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); } } - // -- start(a,b,c) -> start(a,Callable(b,c)) Thread - if (line.find("start(") != -1) { - int start = line.find("start("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() >= 3) { - line = line.substr(0, start) + "start(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + ")" + connect_arguments(parts, 3) + ")" + line.substr(end + start); - } + } + // -- is_connected(a,b,c) -> is_connected(a,Callable(b,c)) Object + if (line.find("is_connected(") != -1) { + int start = line.find("is_connected("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 3) { + line = line.substr(0, start) + "is_connected(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); } } - // -- func _init(p_x:int)->void: -> func _init(p_x:int): Object # https://github.com/godotengine/godot/issues/50589 - if (line.find(" _init(") != -1) { - int start = line.find(" _init("); - int end = line.rfind(":") + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - line = line.substr(0, start) + " _init(" + connect_arguments(parts, 0) + "):" + line.substr(end + start); + } + // -- start(a,b) -> start(Callable(a,b)) Thread + // -- start(a,b,c,d) -> start(Callable(a,b).bind(c),d) Thread + if (line.find("start(") != -1) { + int start = line.find("start("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 2) { + line = line.substr(0, start) + "start(Callable(" + parts[0] + "," + parts[1] + "))" + line.substr(end + start); + } else if (parts.size() >= 3) { + line = line.substr(0, start) + "start(Callable(" + parts[0] + "," + parts[1] + ").bind(" + parts[2] + ")" + connect_arguments(parts, 3) + ")" + line.substr(end + start); } } - // assert(speed < 20, str(randi()%10)) -> assert(speed < 20) #,str(randi()%10)) GDScript - GDScript bug constant message - if (line.find("assert(") != -1) { - int start = line.find("assert("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "assert(" + parts[0] + ") " + line.substr(end + start) + "#," + parts[1] + ")"; - } + } + // -- func _init(p_x:int)->void: -> func _init(p_x:int): Object # https://github.com/godotengine/godot/issues/50589 + if (line.find(" _init(") != -1) { + int start = line.find(" _init("); + int end = line.rfind(":") + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + line = line.substr(0, start) + " _init(" + connect_arguments(parts, 0) + "):" + line.substr(end + start); + } + } + // assert(speed < 20, str(randi()%10)) -> assert(speed < 20) #,str(randi()%10)) GDScript - GDScript bug constant message + if (line.find("assert(") != -1) { + int start = line.find("assert("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 2) { + line = line.substr(0, start) + "assert(" + parts[0] + ") " + line.substr(end + start) + "#," + parts[1] + ")"; } } - // create_from_image(aa, bb) -> create_from_image(aa) #, bb ImageTexture - if (line.find("create_from_image(") != -1) { - int start = line.find("create_from_image("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "create_from_image(" + parts[0] + ") " + "#," + parts[1] + line.substr(end + start); - } + } + // create_from_image(aa, bb) -> create_from_image(aa) #, bb ImageTexture + if (line.find("create_from_image(") != -1) { + int start = line.find("create_from_image("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 2) { + line = line.substr(0, start) + "create_from_image(" + parts[0] + ") " + "#," + parts[1] + line.substr(end + start); } } - // set_cell_item(a, b, c, d ,e) -> set_cell_item(Vector3(a, b, c), d ,e) - if (line.find("set_cell_item(") != -1) { - int start = line.find("set_cell_item("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() > 2) { - line = line.substr(0, start) + "set_cell_item( Vector3(" + parts[0] + "," + parts[1] + "," + parts[2] + ") " + connect_arguments(parts, 3) + ")" + line.substr(end + start); - } + } + // set_cell_item(a, b, c, d ,e) -> set_cell_item(Vector3(a, b, c), d ,e) + if (line.find("set_cell_item(") != -1) { + int start = line.find("set_cell_item("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() > 2) { + line = line.substr(0, start) + "set_cell_item( Vector3(" + parts[0] + "," + parts[1] + "," + parts[2] + ") " + connect_arguments(parts, 3) + ")" + line.substr(end + start); } } - // get_cell_item(a, b, c) -> get_cell_item(Vector3i(a, b, c)) - if (line.find("get_cell_item(") != -1) { - int start = line.find("get_cell_item("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "get_cell_item(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } + } + // get_cell_item(a, b, c) -> get_cell_item(Vector3i(a, b, c)) + if (line.find("get_cell_item(") != -1) { + int start = line.find("get_cell_item("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 3) { + line = line.substr(0, start) + "get_cell_item(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start); } } - // get_cell_item_orientation(a, b, c) -> get_cell_item_orientation(Vector3i(a, b, c)) - if (line.find("get_cell_item_orientation(") != -1) { - int start = line.find("get_cell_item_orientation("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "get_cell_item_orientation(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } + } + // get_cell_item_orientation(a, b, c) -> get_cell_item_orientation(Vector3i(a, b, c)) + if (line.find("get_cell_item_orientation(") != -1) { + int start = line.find("get_cell_item_orientation("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 3) { + line = line.substr(0, start) + "get_cell_item_orientation(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start); } } - - // apply_impulse(A, B) -> apply_impulse(B, A) - if (line.find("apply_impulse(") != -1) { - int start = line.find("apply_impulse("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "apply_impulse(" + parts[1] + ", " + parts[0] + ")" + line.substr(end + start); - } + } + // apply_impulse(A, B) -> apply_impulse(B, A) + if (line.find("apply_impulse(") != -1) { + int start = line.find("apply_impulse("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 2) { + line = line.substr(0, start) + "apply_impulse(" + parts[1] + ", " + parts[0] + ")" + line.substr(end + start); } } - // apply_force(A, B) -> apply_force(B, A) - if (line.find("apply_force(") != -1) { - int start = line.find("apply_force("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 2) { - line = line.substr(0, start) + "apply_force(" + parts[1] + ", " + parts[0] + ")" + line.substr(end + start); - } + } + // apply_force(A, B) -> apply_force(B, A) + if (line.find("apply_force(") != -1) { + int start = line.find("apply_force("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 2) { + line = line.substr(0, start) + "apply_force(" + parts[1] + ", " + parts[0] + ")" + line.substr(end + start); } } - // map_to_world(a, b, c) -> map_to_world(Vector3i(a, b, c)) - if (line.find("map_to_world(") != -1) { - int start = line.find("get_cell_item_orientation("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "map_to_world(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } + } + // map_to_world(a, b, c) -> map_to_world(Vector3i(a, b, c)) + if (line.find("map_to_world(") != -1) { + int start = line.find("map_to_world("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 3) { + line = line.substr(0, start) + "map_to_world(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start); } } - - if (old_line != line) { - found_things.append(simple_line_formatter(current_line, old_line, line)); + } + // OS.get_window_safe_area() -> DisplayServer.get_display_safe_area() + if (line.find("OS.get_window_safe_area(") != -1) { + int start = line.find("OS.get_window_safe_area("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 0) { + line = line.substr(0, start) + "DisplayServer.get_display_safe_area()" + line.substr(end + start); + } } } - - return found_things; } -void ProjectConverter3To4::rename_csharp_functions(String &file_content) { - // Custom renaming, each rule needs to be set manually - // Don't forget to put validate each rule in validate_conversion function - Vector<String> lines = file_content.split("\n"); +void ProjectConverter3To4::process_csharp_line(String &line) { + // TODO maybe this can be changed to normal rule + line = line.replace("OS.GetWindowSafeArea()", "DisplayServer.ScreenGetUsableRect()"); - for (String &line : lines) { - // TODO maybe this can be changed to normal rule - line = line.replace("OS.GetWindowSafeArea()", "DisplayServer.ScreenGetUsableRect()"); - - // -- Connect(,,,things) -> Connect(,Callable(,),things) Object - if (line.find("Connect(") != -1) { - int start = line.find("Connect("); - // Protection from disconnect - if (start == 0 || line.get(start - 1) != 's') { - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() >= 3) { - line = line.substr(0, start) + "Connect(" + parts[0] + ",new Callable(" + parts[1] + "," + parts[2] + ")" + connect_arguments(parts, 3) + ")" + line.substr(end + start); - } - } - } - } - // -- Disconnect(a,b,c) -> Disconnect(a,Callable(b,c)) Object - if (line.find("Disconnect(") != -1) { - int start = line.find("Disconnect("); + // -- Connect(,,,things) -> Connect(,Callable(,),things) Object + if (line.find("Connect(") != -1) { + int start = line.find("Connect("); + // Protection from disconnect + if (start == 0 || line.get(start - 1) != 's') { int end = get_end_parenthess(line.substr(start)) + 1; if (end > -1) { Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "Disconnect(" + parts[0] + ",new Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); + if (parts.size() >= 3) { + line = line.substr(0, start) + "Connect(" + parts[0] + ",new Callable(" + parts[1] + "," + parts[2] + ")" + connect_arguments(parts, 3) + ")" + line.substr(end + start); } } } - // -- IsConnected(a,b,c) -> IsConnected(a,Callable(b,c)) Object - if (line.find("IsConnected(") != -1) { - int start = line.find("IsConnected("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "IsConnected(" + parts[0] + ",new Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } + } + // -- Disconnect(a,b,c) -> Disconnect(a,Callable(b,c)) Object + if (line.find("Disconnect(") != -1) { + int start = line.find("Disconnect("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 3) { + line = line.substr(0, start) + "Disconnect(" + parts[0] + ",new Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); } } } + // -- IsConnected(a,b,c) -> IsConnected(a,Callable(b,c)) Object + if (line.find("IsConnected(") != -1) { + int start = line.find("IsConnected("); + int end = get_end_parenthess(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 3) { + line = line.substr(0, start) + "IsConnected(" + parts[0] + ",new Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); + } + } + } +} + +void ProjectConverter3To4::rename_csharp_functions(String &file_content) { + Vector<String> lines = file_content.split("\n"); + + for (String &line : lines) { + process_csharp_line(line); + } // Collect vector to string file_content = ""; @@ -3554,47 +3199,7 @@ Vector<String> ProjectConverter3To4::check_for_rename_csharp_functions(Vector<St for (String &line : file_content) { String old_line = line; - - // TODO maybe this can be changed to normal rule - line = line.replace("OS.GetWindowSafeArea()", "DisplayServer.ScreenGetUsableRect()"); - - // -- Connect(,,,things) -> connect(,Callable(,),things) Object - if (line.find("Connect(") != -1) { - int start = line.find("Connect("); - // Protection from disconnect - if (start == 0 || line.get(start - 1) != 's') { - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() >= 3) { - line = line.substr(0, start) + "Connect(" + parts[0] + ",new Callable(" + parts[1] + "," + parts[2] + ")" + connect_arguments(parts, 3) + ")" + line.substr(end + start); - } - } - } - } - // -- Disconnect(a,b,c) -> Disconnect(a,Callable(b,c)) Object - if (line.find("Disconnect(") != -1) { - int start = line.find("Disconnect("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "Disconnect(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } - } - } - // -- IsConnected(a,b,c) -> IsConnected(a,Callable(b,c)) Object - if (line.find("IsConnected(") != -1) { - int start = line.find("IsConnected("); - int end = get_end_parenthess(line.substr(start)) + 1; - if (end > -1) { - Vector<String> parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 3) { - line = line.substr(0, start) + "IsConnected(" + parts[0] + ",Callable(" + parts[1] + "," + parts[2] + "))" + line.substr(end + start); - } - } - } - + process_csharp_line(line); if (old_line != line) { found_things.append(simple_line_formatter(current_line, old_line, line)); } @@ -3603,88 +3208,205 @@ Vector<String> ProjectConverter3To4::check_for_rename_csharp_functions(Vector<St return found_things; } -void ProjectConverter3To4::rename_gdscript_keywords(String &file_content){ - { RegEx reg_tool = RegEx("([\n]+)tool"); -CRASH_COND(!reg_tool.is_valid()); -file_content = reg_tool.sub(file_content, "$1@tool", true); -RegEx reg_tool2 = RegEx("^tool"); -CRASH_COND(!reg_tool2.is_valid()); -file_content = reg_tool2.sub(file_content, "@tool", true); -} -{ - RegEx reg_export = RegEx("([\n\t]+)export\\b"); - CRASH_COND(!reg_export.is_valid()); - file_content = reg_export.sub(file_content, "$1@export", true); - RegEx reg_export2 = RegEx("^export"); - CRASH_COND(!reg_export2.is_valid()); - file_content = reg_export2.sub(file_content, "@export", true); -} -{ - RegEx reg_onready = RegEx("([\n]+)onready"); - CRASH_COND(!reg_onready.is_valid()); - file_content = reg_onready.sub(file_content, "$1@onready", true); - RegEx reg_onready2 = RegEx("^onready"); - CRASH_COND(!reg_onready2.is_valid()); - file_content = reg_onready2.sub(file_content, "@onready", true); -} -{ - RegEx reg_master = RegEx("([\n]+)master func"); - CRASH_COND(!reg_master.is_valid()); - file_content = reg_master.sub(file_content, "$1@rpc(any) func", true); - RegEx reg_master2 = RegEx("^master func"); - CRASH_COND(!reg_master2.is_valid()); - file_content = reg_master2.sub(file_content, "@rpc(any) func", true); -} -{ - RegEx reg_puppet = RegEx("([\n]+)puppet func"); - CRASH_COND(!reg_puppet.is_valid()); - file_content = reg_puppet.sub(file_content, "$1@rpc(auth) func", true); - RegEx reg_puppet2 = RegEx("^puppet func"); - CRASH_COND(!reg_puppet2.is_valid()); - file_content = reg_puppet2.sub(file_content, "@rpc(auth) func", true); -} -{ - RegEx reg_remote = RegEx("([\n]+)remote func"); - CRASH_COND(!reg_remote.is_valid()); - file_content = reg_remote.sub(file_content, "$1@rpc(any) func", true); - RegEx reg_remote2 = RegEx("^remote func"); - CRASH_COND(!reg_remote2.is_valid()); - file_content = reg_remote2.sub(file_content, "@rpc(any) func", true); -} -{ - RegEx reg_remotesync = RegEx("([\n]+)remotesync func"); - CRASH_COND(!reg_remotesync.is_valid()); - file_content = reg_remotesync.sub(file_content, "$1@rpc(any,sync) func", true); - RegEx reg_remotesync2 = RegEx("^remotesync func"); - CRASH_COND(!reg_remotesync2.is_valid()); - file_content = reg_remotesync2.sub(file_content, "@rpc(any,sync) func", true); -} -{ - RegEx reg_sync = RegEx("([\n]+)sync func"); - CRASH_COND(!reg_sync.is_valid()); - file_content = reg_sync.sub(file_content, "$1@rpc(any,sync) func", true); - RegEx reg_sync2 = RegEx("^sync func"); - CRASH_COND(!reg_sync2.is_valid()); - file_content = reg_sync2.sub(file_content, "@rpc(any,sync) func", true); -} -{ - RegEx reg_puppetsync = RegEx("([\n]+)puppetsync func"); - CRASH_COND(!reg_puppetsync.is_valid()); - file_content = reg_puppetsync.sub(file_content, "$1@rpc(auth,sync) func", true); - RegEx reg_puppetsync2 = RegEx("^puppetsync func"); - CRASH_COND(!reg_puppetsync2.is_valid()); - file_content = reg_puppetsync2.sub(file_content, "@rpc(auth,sync) func", true); +void ProjectConverter3To4::rename_csharp_attributes(String &file_content) { + // -- [Remote] -> [RPC(MultiplayerAPI.RPCMode.AnyPeer)] + { + RegEx reg_remote = RegEx("\\[Remote(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!reg_remote.is_valid()); + file_content = reg_remote.sub(file_content, "[RPC(MultiplayerAPI.RPCMode.AnyPeer)]", true); + } + // -- [RemoteSync] -> [RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)] + { + RegEx reg_remotesync = RegEx("\\[(Remote)?Sync(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!reg_remotesync.is_valid()); + file_content = reg_remotesync.sub(file_content, "[RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)]", true); + } + // -- [Puppet] -> [RPC] + { + RegEx reg_puppet = RegEx("\\[(Puppet|Slave)(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!reg_puppet.is_valid()); + file_content = reg_puppet.sub(file_content, "[RPC]", true); + } + // -- [PuppetSync] -> [RPC(CallLocal = true)] + { + RegEx reg_puppetsync = RegEx("\\[PuppetSync(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!reg_puppetsync.is_valid()); + file_content = reg_puppetsync.sub(file_content, "[RPC(CallLocal = true)]", true); + } + String error_message = "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using Multiplayer.GetRemoteSenderId()\n"; + // -- [Master] -> [RPC] + { + RegEx reg_remote = RegEx("\\[Master(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!reg_remote.is_valid()); + file_content = reg_remote.sub(file_content, error_message + "[RPC]", true); + } + // -- [MasterSync] -> [RPC(CallLocal = true)] + { + RegEx reg_remote = RegEx("\\[MasterSync(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!reg_remote.is_valid()); + file_content = reg_remote.sub(file_content, error_message + "[RPC(CallLocal = true)]", true); + } } -{ - RegEx reg_mastersync = RegEx("([\n]+)mastersync func"); - CRASH_COND(!reg_mastersync.is_valid()); - file_content = reg_mastersync.sub(file_content, "$1@rpc(any,sync) func", true); - RegEx reg_mastersync2 = RegEx("^mastersync func"); - CRASH_COND(!reg_mastersync2.is_valid()); - file_content = reg_mastersync2.sub(file_content, "@rpc(any,sync) func", true); + +Vector<String> ProjectConverter3To4::check_for_rename_csharp_attributes(Vector<String> &file_content) { + int current_line = 1; + + Vector<String> found_things; + + for (String &line : file_content) { + String old; + old = line; + { + RegEx regex = RegEx("\\[Remote(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "[RPC(MultiplayerAPI.RPCMode.AnyPeer)]", true); + } + if (old != line) { + found_things.append(line_formatter(current_line, "[Remote]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer)]", line)); + } + old = line; + { + RegEx regex = RegEx("\\[(Remote)?Sync(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "[RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)]", true); + } + if (old != line) { + found_things.append(line_formatter(current_line, "[RemoteSync]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)]", line)); + } + old = line; + { + RegEx regex = RegEx("\\[Puppet(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "[RPC]", true); + } + if (old != line) { + found_things.append(line_formatter(current_line, "[Puppet]", "[RPC]", line)); + } + old = line; + { + RegEx regex = RegEx("\\[(Puppet|Slave)Sync(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "[RPC(CallLocal = true)]", true); + } + if (old != line) { + found_things.append(line_formatter(current_line, "[PuppetSync]", "[RPC(CallLocal = true)]", line)); + } + old = line; + { + RegEx regex = RegEx("\\[Master(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "[RPC]", true); + } + if (old != line) { + found_things.append(line_formatter(current_line, "[Master]", "[RPC]", line)); + } + old = line; + { + RegEx regex = RegEx("\\[MasterSync(Attribute)?(\\(\\))?\\]"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "[RPC(CallLocal = true)]", true); + } + if (old != line) { + found_things.append(line_formatter(current_line, "[MasterSync]", "[RPC(CallLocal = true)]", line)); + } + + current_line++; + } + + return found_things; } + +void ProjectConverter3To4::rename_gdscript_keywords(String &file_content) { + { + RegEx reg_first = RegEx("([\n]+)tool"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1@tool", true); + RegEx reg_second = RegEx("^tool"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, "@tool", true); + } + { + RegEx reg_first = RegEx("([\n\t]+)export\\b"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1@export", true); + RegEx reg_second = RegEx("^export"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, "@export", true); + } + { + RegEx reg_first = RegEx("([\n]+)onready"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1@onready", true); + RegEx reg_second = RegEx("^onready"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, "@onready", true); + } + { + RegEx reg_first = RegEx("([\n]+)remote func"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1@rpc(any_peer) func", true); + RegEx reg_second = RegEx("^remote func"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, "@rpc(any_peer) func", true); + } + { + RegEx reg_first = RegEx("([\n]+)remotesync func"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1@rpc(any_peer, call_local) func", true); + RegEx reg_second = RegEx("^remotesync func"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, "@rpc(any_peer, call_local) func", true); + } + { + RegEx reg_first = RegEx("([\n]+)sync func"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1@rpc(any_peer, call_local) func", true); + RegEx reg_second = RegEx("^sync func"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, "@rpc(any_peer, call_local) func", true); + } + { + RegEx reg_first = RegEx("([\n]+)slave func"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1@rpc func", true); + RegEx reg_second = RegEx("^slave func"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, "@rpc func", true); + } + { + RegEx reg_first = RegEx("([\n]+)puppet func"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1@rpc func", true); + RegEx reg_second = RegEx("^puppet func"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, "@rpc func", true); + } + { + RegEx reg_first = RegEx("([\n]+)puppetsync func"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1@rpc(call_local) func", true); + RegEx reg_second = RegEx("^puppetsync func"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, "@rpc(call_local) func", true); + } + String error_message = "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n"; + { + RegEx reg_first = RegEx("([\n]+)master func"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1" + error_message + "@rpc func", true); + RegEx reg_second = RegEx("^master func"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, error_message + "@rpc func", true); + } + { + RegEx reg_first = RegEx("([\n]+)mastersync func"); + CRASH_COND(!reg_first.is_valid()); + file_content = reg_first.sub(file_content, "$1" + error_message + "@rpc(call_local) func", true); + RegEx reg_second = RegEx("^mastersync func"); + CRASH_COND(!reg_second.is_valid()); + file_content = reg_second.sub(file_content, error_message + "@rpc(call_local) func", true); + } } -; Vector<String> ProjectConverter3To4::check_for_rename_gdscript_keywords(Vector<String> &file_content) { Vector<String> found_things; @@ -3695,96 +3417,105 @@ Vector<String> ProjectConverter3To4::check_for_rename_gdscript_keywords(Vector<S String old; old = line; { - RegEx reg_tool2 = RegEx("^tool"); - CRASH_COND(!reg_tool2.is_valid()); - line = reg_tool2.sub(line, "@tool", true); + RegEx reg_first = RegEx("^tool"); + CRASH_COND(!reg_first.is_valid()); + line = reg_first.sub(line, "@tool", true); } if (old != line) { found_things.append(line_formatter(current_line, "tool", "@tool", line)); } old = line; { - RegEx reg_export = RegEx("([\t]+)export\\b"); - CRASH_COND(!reg_export.is_valid()); - line = reg_export.sub(line, "$1@export", true); - RegEx reg_export2 = RegEx("^export"); - CRASH_COND(!reg_export2.is_valid()); - line = reg_export2.sub(line, "@export", true); + RegEx reg_first = RegEx("([\t]+)export\\b"); + CRASH_COND(!reg_first.is_valid()); + line = reg_first.sub(line, "$1@export", true); + RegEx reg_second = RegEx("^export"); + CRASH_COND(!reg_second.is_valid()); + line = reg_second.sub(line, "@export", true); } if (old != line) { found_things.append(line_formatter(current_line, "export", "@export", line)); } old = line; { - RegEx reg_onready2 = RegEx("^onready"); - CRASH_COND(!reg_onready2.is_valid()); - line = reg_onready2.sub(line, "@onready", true); + RegEx reg_first = RegEx("^onready"); + CRASH_COND(!reg_first.is_valid()); + line = reg_first.sub(line, "@onready", true); } if (old != line) { found_things.append(line_formatter(current_line, "onready", "@onready", line)); } old = line; { - RegEx reg_master2 = RegEx("^master func"); - CRASH_COND(!reg_master2.is_valid()); - line = reg_master2.sub(line, "@rpc(any) func", true); + RegEx regex = RegEx("^remote func"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "@rpc(any_peer) func", true); + } + if (old != line) { + found_things.append(line_formatter(current_line, "remote func", "@rpc(any_peer) func", line)); + } + old = line; + { + RegEx regex = RegEx("^remotesync func"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "@rpc(any_peer, call_local)) func", true); } if (old != line) { - found_things.append(line_formatter(current_line, "master func", "@rpc(any) func", line)); + found_things.append(line_formatter(current_line, "remotesync func", "@rpc(any_peer, call_local)) func", line)); } old = line; { - RegEx reg_puppet2 = RegEx("^puppet func"); - CRASH_COND(!reg_puppet2.is_valid()); - line = reg_puppet2.sub(line, "@rpc(auth) func", true); + RegEx regex = RegEx("^sync func"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "@rpc(any_peer, call_local)) func", true); } if (old != line) { - found_things.append(line_formatter(current_line, "puppet func", "@rpc(auth) func", line)); + found_things.append(line_formatter(current_line, "sync func", "@rpc(any_peer, call_local)) func", line)); } old = line; { - RegEx reg_remote2 = RegEx("^remote func"); - CRASH_COND(!reg_remote2.is_valid()); - line = reg_remote2.sub(line, "@rpc(any) func", true); + RegEx regex = RegEx("^slave func"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "@rpc func", true); } if (old != line) { - found_things.append(line_formatter(current_line, "remote func", "@rpc(any) func", line)); + found_things.append(line_formatter(current_line, "slave func", "@rpc func", line)); } old = line; { - RegEx reg_remotesync2 = RegEx("^remotesync func"); - CRASH_COND(!reg_remotesync2.is_valid()); - line = reg_remotesync2.sub(line, "@rpc(any,sync) func", true); + RegEx regex = RegEx("^puppet func"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "@rpc func", true); } if (old != line) { - found_things.append(line_formatter(current_line, "remotesync func", "@rpc(any,sync) func", line)); + found_things.append(line_formatter(current_line, "puppet func", "@rpc func", line)); } old = line; { - RegEx reg_sync2 = RegEx("^sync func"); - CRASH_COND(!reg_sync2.is_valid()); - line = reg_sync2.sub(line, "@rpc(any,sync) func", true); + RegEx regex = RegEx("^puppetsync func"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "@rpc(call_local) func", true); } if (old != line) { - found_things.append(line_formatter(current_line, "sync func", "@rpc(any,sync) func", line)); + found_things.append(line_formatter(current_line, "puppetsync func", "@rpc(call_local) func", line)); } old = line; { - RegEx reg_puppetsync2 = RegEx("^puppetsync func"); - CRASH_COND(!reg_puppetsync2.is_valid()); - line = reg_puppetsync2.sub(line, "@rpc(auth,sync) func", true); + RegEx regex = RegEx("^master func"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "@rpc func", true); } if (old != line) { - found_things.append(line_formatter(current_line, "puppetsync func", "@rpc(any,sync) func", line)); + found_things.append(line_formatter(current_line, "master func", "@rpc func", line)); } old = line; { - RegEx reg_mastersync2 = RegEx("^mastersync func"); - CRASH_COND(!reg_mastersync2.is_valid()); - line = reg_mastersync2.sub(line, "@rpc(any,sync) func", true); + RegEx regex = RegEx("^mastersync func"); + CRASH_COND(!regex.is_valid()); + line = regex.sub(line, "@rpc(call_local) func", true); } if (old != line) { - found_things.append(line_formatter(current_line, "mastersync", "@rpc(any,sync) func", line)); + found_things.append(line_formatter(current_line, "mastersync func", "@rpc(call_local) func", line)); } old = line; @@ -3808,7 +3539,7 @@ Vector<String> ProjectConverter3To4::check_for_custom_rename(Vector<String> &fil int current_line = 1; for (String &line : file_content) { - Array reg_match = reg.search_all(line); + TypedArray<RegExMatch> reg_match = reg.search_all(line); if (reg_match.size() > 0) { found_things.append(line_formatter(current_line, from.replace("\\.", "."), to, line)); // Without replacing it will print "\.shader" instead ".shader" } @@ -3839,7 +3570,7 @@ Vector<String> ProjectConverter3To4::check_for_rename_common(const char *array[] int current_line = 1; for (String &line : file_content) { - Array reg_match = reg.search_all(line); + TypedArray<RegExMatch> reg_match = reg.search_all(line); if (reg_match.size() > 0) { found_things.append(line_formatter(current_line, array[current_index][0], array[current_index][1], line)); } diff --git a/editor/project_converter_3_to_4.h b/editor/project_converter_3_to_4.h index 95239666e0..8526e2ceb9 100644 --- a/editor/project_converter_3_to_4.h +++ b/editor/project_converter_3_to_4.h @@ -37,17 +37,26 @@ #include "core/string/ustring.h" class ProjectConverter3To4 { +public: + class RegExContainer; + +private: void rename_enums(String &file_content); Vector<String> check_for_rename_enums(Vector<String> &file_content); void rename_classes(String &file_content); Vector<String> check_for_rename_classes(Vector<String> &file_content); - void rename_gdscript_functions(String &file_content); - Vector<String> check_for_rename_gdscript_functions(Vector<String> &file_content); + void rename_gdscript_functions(String &file_content, const RegExContainer ®_container, bool builtin); + Vector<String> check_for_rename_gdscript_functions(Vector<String> &file_content, const RegExContainer ®_container, bool builtin); + void process_gdscript_line(String &line, const RegExContainer ®_container, bool builtin); void rename_csharp_functions(String &file_content); Vector<String> check_for_rename_csharp_functions(Vector<String> &file_content); + void process_csharp_line(String &line); + + void rename_csharp_attributes(String &file_content); + Vector<String> check_for_rename_csharp_attributes(Vector<String> &file_content); void rename_gdscript_keywords(String &file_content); Vector<String> check_for_rename_gdscript_keywords(Vector<String> &file_content); @@ -71,9 +80,10 @@ class ProjectConverter3To4 { bool test_single_array(const char *array[][2], bool ignore_second_check = false); bool test_conversion_single_additional(String name, String expected, void (ProjectConverter3To4::*func)(String &), String what); + bool test_conversion_single_additional_builtin(String name, String expected, void (ProjectConverter3To4::*func)(String &, const RegExContainer &, bool), String what, const RegExContainer ®_container, bool builtin); bool test_conversion_single_normal(String name, String expected, const char *array[][2], String what); bool test_array_names(); - bool test_conversion(); + bool test_conversion(const RegExContainer ®_container); public: int validate_conversion(); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 327ff6bb2d..21891e381b 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -42,6 +42,7 @@ #include "core/string/translation.h" #include "core/version.h" #include "editor/editor_file_dialog.h" +#include "editor/editor_paths.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_themes.h" @@ -57,10 +58,6 @@ #include "servers/navigation_server_3d.h" #include "servers/physics_server_2d.h" -static inline String get_project_key_from_path(const String &dir) { - return dir.replace("/", "::"); -} - class ProjectDialog : public ConfirmationDialog { GDCLASS(ProjectDialog, ConfirmationDialog); @@ -491,7 +488,7 @@ private: if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("project.godot"), initial_settings, Vector<String>(), false) != OK) { set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR); } else { - ResourceSaver::save(dir.plus_file("icon.png"), create_unscaled_default_project_icon()); + ResourceSaver::save(create_unscaled_default_project_icon(), dir.plus_file("icon.png")); EditorVCSInterface::create_vcs_metadata_files(EditorVCSInterface::VCSMetadata(vcs_metadata_selection->get_selected()), dir); } } else if (mode == MODE_INSTALL) { @@ -600,9 +597,6 @@ private: if (dir.ends_with("/")) { dir = dir.substr(0, dir.length() - 1); } - String proj = get_project_key_from_path(dir); - EditorSettings::get_singleton()->set("projects/" + proj, dir); - EditorSettings::get_singleton()->save(); hide(); emit_signal(SNAME("project_created"), dir); @@ -646,14 +640,6 @@ private: protected: static void _bind_methods() { - ClassDB::bind_method("_browse_path", &ProjectDialog::_browse_path); - ClassDB::bind_method("_create_folder", &ProjectDialog::_create_folder); - ClassDB::bind_method("_text_changed", &ProjectDialog::_text_changed); - ClassDB::bind_method("_path_text_changed", &ProjectDialog::_path_text_changed); - ClassDB::bind_method("_path_selected", &ProjectDialog::_path_selected); - ClassDB::bind_method("_file_selected", &ProjectDialog::_file_selected); - ClassDB::bind_method("_install_path_selected", &ProjectDialog::_install_path_selected); - ClassDB::bind_method("_browse_install_path", &ProjectDialog::_browse_install_path); ADD_SIGNAL(MethodInfo("project_created")); ADD_SIGNAL(MethodInfo("projects_updated")); } @@ -997,7 +983,6 @@ public: // Can often be passed by copy struct Item { - String project_key; String project_name; String description; String path; @@ -1014,8 +999,7 @@ public: Item() {} - Item(const String &p_project, - const String &p_name, + Item(const String &p_name, const String &p_description, const String &p_path, const String &p_icon, @@ -1026,7 +1010,6 @@ public: bool p_grayed, bool p_missing, int p_version) { - project_key = p_project; project_name = p_name; description = p_description; path = p_path; @@ -1042,7 +1025,7 @@ public: } _FORCE_INLINE_ bool operator==(const Item &l) const { - return project_key == l.project_key; + return path == l.path; } }; @@ -1055,6 +1038,7 @@ public: void _global_menu_open_project(const Variant &p_tag); void update_dock_menu(); + void migrate_config(); void load_projects(); void set_search_term(String p_search_term); void set_order_option(int p_option); @@ -1070,6 +1054,8 @@ public: bool is_any_project_missing() const; void erase_missing_projects(); int refresh_project(const String &dir_path); + void add_project(const String &dir_path, bool favorite); + void save_config(); private: static void _bind_methods(); @@ -1090,12 +1076,15 @@ private: String _search_term; FilterOption _order_option; - HashSet<String> _selected_project_keys; + HashSet<String> _selected_project_paths; String _last_clicked; // Project key VBoxContainer *_scroll_children; int _icon_load_index; Vector<Item> _projects; + + ConfigFile _config; + String _config_path; }; struct ProjectListComparator { @@ -1111,7 +1100,7 @@ struct ProjectListComparator { } switch (order_option) { case PATH: - return a.project_key < b.project_key; + return a.path < b.path; case EDIT_DATE: return a.last_edited > b.last_edited; default: @@ -1128,6 +1117,7 @@ ProjectList::ProjectList() { _icon_load_index = 0; project_opening_initiated = false; + _config_path = EditorPaths::get_singleton()->get_data_dir().plus_file("projects.cfg"); } ProjectList::~ProjectList() { @@ -1179,9 +1169,8 @@ void ProjectList::load_project_icon(int p_index) { } // Load project data from p_property_key and return it in a ProjectList::Item. p_favorite is passed directly into the Item. -ProjectList::Item ProjectList::load_project_data(const String &p_property_key, bool p_favorite) { - String path = EditorSettings::get_singleton()->get(p_property_key); - String conf = path.plus_file("project.godot"); +ProjectList::Item ProjectList::load_project_data(const String &p_path, bool p_favorite) { + String conf = p_path.plus_file("project.godot"); bool grayed = false; bool missing = false; @@ -1217,7 +1206,7 @@ ProjectList::Item ProjectList::load_project_data(const String &p_property_key, b // when editing a project (but not when running it). last_edited = FileAccess::get_modified_time(conf); - String fscache = path.plus_file(".fscache"); + String fscache = p_path.plus_file(".fscache"); if (FileAccess::exists(fscache)) { uint64_t cache_modified = FileAccess::get_modified_time(fscache); if (cache_modified > last_edited) { @@ -1230,9 +1219,38 @@ ProjectList::Item ProjectList::load_project_data(const String &p_property_key, b print_line("Project is missing: " + conf); } - const String project_key = p_property_key.get_slice("/", 1); + return Item(project_name, description, p_path, icon, main_scene, unsupported_features, last_edited, p_favorite, grayed, missing, config_version); +} + +void ProjectList::migrate_config() { + // Proposal #1637 moved the project list from editor settings to a separate config file + // If the new config file doesn't exist, populate it from EditorSettings + if (FileAccess::exists(_config_path)) { + return; + } + print_line("Migrating legacy project list"); + + List<PropertyInfo> properties; + EditorSettings::get_singleton()->get_property_list(&properties); - return Item(project_key, project_name, description, path, icon, main_scene, unsupported_features, last_edited, p_favorite, grayed, missing, config_version); + for (const PropertyInfo &E : properties) { + // This is actually something like "projects/C:::Documents::Godot::Projects::MyGame" + String property_key = E.name; + if (!property_key.begins_with("projects/")) { + continue; + } + + String path = EditorSettings::get_singleton()->get(property_key); + String favoriteKey = "favorite_projects/" + property_key.get_slice("/", 1); + bool favorite = EditorSettings::get_singleton()->has_setting(favoriteKey); + add_project(path, favorite); + if (favorite) { + EditorSettings::get_singleton()->erase(favoriteKey); + } + EditorSettings::get_singleton()->erase(property_key); + } + + save_config(); } void ProjectList::load_projects() { @@ -1247,37 +1265,15 @@ void ProjectList::load_projects() { } _projects.clear(); _last_clicked = ""; - _selected_project_keys.clear(); - - // Load data - // TODO Would be nice to change how projects and favourites are stored... it complicates things a bit. - // Use a dictionary associating project path to metadata (like is_favorite). - - List<PropertyInfo> properties; - EditorSettings::get_singleton()->get_property_list(&properties); - - HashSet<String> favorites; - // Find favourites... - for (const PropertyInfo &E : properties) { - String property_key = E.name; - if (property_key.begins_with("favorite_projects/")) { - favorites.insert(property_key); - } - } - - for (const PropertyInfo &E : properties) { - // This is actually something like "projects/C:::Documents::Godot::Projects::MyGame" - String property_key = E.name; - if (!property_key.begins_with("projects/")) { - continue; - } - - String project_key = property_key.get_slice("/", 1); - bool favorite = favorites.has("favorite_projects/" + project_key); + _selected_project_paths.clear(); - Item item = load_project_data(property_key, favorite); + List<String> sections; + _config.load(_config_path); + _config.get_sections(§ions); - _projects.push_back(item); + for (const String &path : sections) { + bool favorite = _config.get_value(path, "favorite", false); + _projects.push_back(load_project_data(path, favorite)); } // Create controls @@ -1348,8 +1344,8 @@ void ProjectList::create_project_item_control(int p_index) { Color font_color = get_theme_color(SNAME("font_color"), SNAME("Tree")); ProjectListItemControl *hb = memnew(ProjectListItemControl); - hb->connect("draw", callable_mp(this, &ProjectList::_panel_draw), varray(hb)); - hb->connect("gui_input", callable_mp(this, &ProjectList::_panel_input), varray(hb)); + hb->connect("draw", callable_mp(this, &ProjectList::_panel_draw).bind(hb)); + hb->connect("gui_input", callable_mp(this, &ProjectList::_panel_input).bind(hb)); hb->add_theme_constant_override("separation", 10 * EDSCALE); hb->set_tooltip(item.description); @@ -1360,7 +1356,7 @@ void ProjectList::create_project_item_control(int p_index) { favorite->set_normal_texture(favorite_icon); // This makes the project's "hover" style display correctly when hovering the favorite icon. favorite->set_mouse_filter(MOUSE_FILTER_PASS); - favorite->connect("pressed", callable_mp(this, &ProjectList::_favorite_pressed), varray(hb)); + favorite->connect("pressed", callable_mp(this, &ProjectList::_favorite_pressed).bind(hb)); favorite_box->add_child(favorite); favorite_box->set_alignment(BoxContainer::ALIGNMENT_CENTER); hb->add_child(favorite_box); @@ -1433,7 +1429,7 @@ void ProjectList::create_project_item_control(int p_index) { path_hb->add_child(show); if (!item.missing) { - show->connect("pressed", callable_mp(this, &ProjectList::_show_project), varray(item.path)); + show->connect("pressed", callable_mp(this, &ProjectList::_show_project).bind(item.path)); show->set_tooltip(TTR("Show in File Manager")); } else { show->set_tooltip(TTR("Error: Project is missing on the filesystem.")); @@ -1504,19 +1500,19 @@ void ProjectList::sort_projects() { const HashSet<String> &ProjectList::get_selected_project_keys() const { // Faster if that's all you need - return _selected_project_keys; + return _selected_project_paths; } Vector<ProjectList::Item> ProjectList::get_selected_projects() const { Vector<Item> items; - if (_selected_project_keys.size() == 0) { + if (_selected_project_paths.size() == 0) { return items; } - items.resize(_selected_project_keys.size()); + items.resize(_selected_project_paths.size()); int j = 0; for (int i = 0; i < _projects.size(); ++i) { const Item &item = _projects[i]; - if (_selected_project_keys.has(item.project_key)) { + if (_selected_project_paths.has(item.path)) { items.write[j++] = item; } } @@ -1530,41 +1526,40 @@ void ProjectList::ensure_project_visible(int p_index) { } int ProjectList::get_single_selected_index() const { - if (_selected_project_keys.size() == 0) { + if (_selected_project_paths.size() == 0) { // Default selection return 0; } String key; - if (_selected_project_keys.size() == 1) { + if (_selected_project_paths.size() == 1) { // Only one selected - key = *_selected_project_keys.begin(); + key = *_selected_project_paths.begin(); } else { // Multiple selected, consider the last clicked one as "main" key = _last_clicked; } for (int i = 0; i < _projects.size(); ++i) { - if (_projects[i].project_key == key) { + if (_projects[i].path == key) { return i; } } return 0; } -void ProjectList::remove_project(int p_index, bool p_update_settings) { +void ProjectList::remove_project(int p_index, bool p_update_config) { const Item item = _projects[p_index]; // Take a copy - _selected_project_keys.erase(item.project_key); + _selected_project_paths.erase(item.path); - if (_last_clicked == item.project_key) { + if (_last_clicked == item.path) { _last_clicked = ""; } memdelete(item.control); _projects.remove_at(p_index); - if (p_update_settings) { - EditorSettings::get_singleton()->erase("projects/" + item.project_key); - EditorSettings::get_singleton()->erase("favorite_projects/" + item.project_key); + if (p_update_config) { + _config.erase_section(item.path); // Not actually saving the file, in case you are doing more changes to settings } @@ -1602,41 +1597,19 @@ void ProjectList::erase_missing_projects() { } print_line("Removed " + itos(deleted_count) + " projects from the list, remaining " + itos(remaining_count) + " projects"); - - EditorSettings::get_singleton()->save(); + save_config(); } int ProjectList::refresh_project(const String &dir_path) { - // Reads editor settings and reloads information about a specific project. + // Reloads information about a specific project. // If it wasn't loaded and should be in the list, it is added (i.e new project). // If it isn't in the list anymore, it is removed. // If it is in the list but doesn't exist anymore, it is marked as missing. - String project_key = get_project_key_from_path(dir_path); - - // Read project manager settings - bool is_favourite = false; - bool should_be_in_list = false; - String property_key = "projects/" + project_key; - { - List<PropertyInfo> properties; - EditorSettings::get_singleton()->get_property_list(&properties); - String favorite_property_key = "favorite_projects/" + project_key; - - bool found = false; - for (const PropertyInfo &E : properties) { - String prop = E.name; - if (!found && prop == property_key) { - found = true; - } else if (!is_favourite && prop == favorite_property_key) { - is_favourite = true; - } - } - - should_be_in_list = found; - } + bool should_be_in_list = _config.has_section(dir_path); + bool is_favourite = _config.get_value(dir_path, "favorite", false); - bool was_selected = _selected_project_keys.has(project_key); + bool was_selected = _selected_project_paths.has(dir_path); // Remove item in any case for (int i = 0; i < _projects.size(); ++i) { @@ -1651,7 +1624,7 @@ int ProjectList::refresh_project(const String &dir_path) { if (should_be_in_list) { // Recreate it with updated info - Item item = load_project_data(property_key, is_favourite); + Item item = load_project_data(dir_path, is_favourite); _projects.push_back(item); create_project_item_control(_projects.size() - 1); @@ -1659,7 +1632,7 @@ int ProjectList::refresh_project(const String &dir_path) { sort_projects(); for (int i = 0; i < _projects.size(); ++i) { - if (_projects[i].project_key == project_key) { + if (_projects[i].path == dir_path) { if (was_selected) { select_project(i); ensure_project_visible(i); @@ -1675,13 +1648,23 @@ int ProjectList::refresh_project(const String &dir_path) { return index; } +void ProjectList::add_project(const String &dir_path, bool favorite) { + if (!_config.has_section(dir_path)) { + _config.set_value(dir_path, "favorite", favorite); + } +} + +void ProjectList::save_config() { + _config.save(_config_path); +} + int ProjectList::get_project_count() const { return _projects.size(); } void ProjectList::select_project(int p_index) { Vector<Item> previous_selected_items = get_selected_projects(); - _selected_project_keys.clear(); + _selected_project_paths.clear(); for (int i = 0; i < previous_selected_items.size(); ++i) { previous_selected_items[i].control->update(); @@ -1703,7 +1686,7 @@ void ProjectList::select_first_visible_project() { if (!found) { // Deselect all projects if there are no visible projects in the list. - _selected_project_keys.clear(); + _selected_project_paths.clear(); } } @@ -1725,24 +1708,23 @@ void ProjectList::select_range(int p_begin, int p_end) { void ProjectList::toggle_select(int p_index) { Item &item = _projects.write[p_index]; - if (_selected_project_keys.has(item.project_key)) { - _selected_project_keys.erase(item.project_key); + if (_selected_project_paths.has(item.path)) { + _selected_project_paths.erase(item.path); } else { - _selected_project_keys.insert(item.project_key); + _selected_project_paths.insert(item.path); } item.control->update(); } void ProjectList::erase_selected_projects(bool p_delete_project_contents) { - if (_selected_project_keys.size() == 0) { + if (_selected_project_paths.size() == 0) { return; } for (int i = 0; i < _projects.size(); ++i) { Item &item = _projects.write[i]; - if (_selected_project_keys.has(item.project_key) && item.control->is_visible()) { - EditorSettings::get_singleton()->erase("projects/" + item.project_key); - EditorSettings::get_singleton()->erase("favorite_projects/" + item.project_key); + if (_selected_project_paths.has(item.path) && item.control->is_visible()) { + _config.erase_section(item.path); if (p_delete_project_contents) { OS::get_singleton()->move_to_trash(item.path); @@ -1754,9 +1736,8 @@ void ProjectList::erase_selected_projects(bool p_delete_project_contents) { } } - EditorSettings::get_singleton()->save(); - - _selected_project_keys.clear(); + save_config(); + _selected_project_paths.clear(); _last_clicked = ""; update_dock_menu(); @@ -1772,9 +1753,9 @@ void ProjectList::_panel_draw(Node *p_hb) { hb->draw_line(Point2(0, hb->get_size().y + 1), Point2(hb->get_size().x, hb->get_size().y + 1), get_theme_color(SNAME("guide_color"), SNAME("Tree"))); } - String key = _projects[p_hb->get_index()].project_key; + String key = _projects[p_hb->get_index()].path; - if (_selected_project_keys.has(key)) { + if (_selected_project_paths.has(key)) { hb->draw_style_box(get_theme_stylebox(SNAME("selected"), SNAME("Tree")), Rect2(Point2(), hb->get_size())); } } @@ -1786,11 +1767,11 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) { const Item &clicked_project = _projects[clicked_index]; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { - if (mb->is_shift_pressed() && _selected_project_keys.size() > 0 && !_last_clicked.is_empty() && clicked_project.project_key != _last_clicked) { + if (mb->is_shift_pressed() && _selected_project_paths.size() > 0 && !_last_clicked.is_empty() && clicked_project.path != _last_clicked) { int anchor_index = -1; for (int i = 0; i < _projects.size(); ++i) { const Item &p = _projects[i]; - if (p.project_key == _last_clicked) { + if (p.path == _last_clicked) { anchor_index = p.control->get_index(); break; } @@ -1802,7 +1783,7 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) { toggle_select(clicked_index); } else { - _last_clicked = clicked_project.project_key; + _last_clicked = clicked_project.path; select_project(clicked_index); } @@ -1824,12 +1805,8 @@ void ProjectList::_favorite_pressed(Node *p_hb) { item.favorite = !item.favorite; - if (item.favorite) { - EditorSettings::get_singleton()->set("favorite_projects/" + item.project_key, item.path); - } else { - EditorSettings::get_singleton()->erase("favorite_projects/" + item.project_key); - } - EditorSettings::get_singleton()->save(); + _config.set_value(item.path, "favorite", item.favorite); + save_config(); _projects.write[index] = item; @@ -1839,7 +1816,7 @@ void ProjectList::_favorite_pressed(Node *p_hb) { if (item.favorite) { for (int i = 0; i < _projects.size(); ++i) { - if (_projects[i].project_key == item.project_key) { + if (_projects[i].path == item.path) { ensure_project_visible(i); break; } @@ -2097,6 +2074,8 @@ void ProjectManager::_on_projects_updated() { } void ProjectManager::_on_project_created(const String &dir) { + _project_list->add_project(dir, false); + _project_list->save_config(); search_box->clear(); int i = _project_list->refresh_project(dir); _project_list->select_project(i); @@ -2117,9 +2096,7 @@ void ProjectManager::_open_selected_projects() { const HashSet<String> &selected_list = _project_list->get_selected_project_keys(); - for (const String &E : selected_list) { - const String &selected = E; - String path = EditorSettings::get_singleton()->get("projects/" + selected); + for (const String &path : selected_list) { String conf = path.plus_file("project.godot"); if (!FileAccess::exists(conf)) { @@ -2128,7 +2105,7 @@ void ProjectManager::_open_selected_projects() { return; } - print_line("Editing project: " + path + " (" + selected + ")"); + print_line("Editing project: " + path); List<String> args; @@ -2252,8 +2229,7 @@ void ProjectManager::_run_project_confirm() { continue; } - const String &selected = selected_list[i].project_key; - String path = EditorSettings::get_singleton()->get("projects/" + selected); + const String &path = selected_list[i].path; // `.substr(6)` on `ProjectSettings::get_singleton()->get_imported_files_path()` strips away the leading "res://". if (!DirAccess::exists(path.plus_file(ProjectSettings::get_singleton()->get_imported_files_path().substr(6)))) { @@ -2262,7 +2238,7 @@ void ProjectManager::_run_project_confirm() { continue; } - print_line("Running project: " + path + " (" + selected + ")"); + print_line("Running project: " + path); List<String> args; @@ -2293,7 +2269,7 @@ void ProjectManager::_run_project() { } } -void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) { +void ProjectManager::_scan_dir(const String &path) { Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); Error error = da->change_dir(path); ERR_FAIL_COND_MSG(error != OK, "Could not scan directory at: " + path); @@ -2301,26 +2277,18 @@ void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) { String n = da->get_next(); while (!n.is_empty()) { if (da->current_is_dir() && !n.begins_with(".")) { - _scan_dir(da->get_current_dir().plus_file(n), r_projects); + _scan_dir(da->get_current_dir().plus_file(n)); } else if (n == "project.godot") { - r_projects->push_back(da->get_current_dir()); + _project_list->add_project(da->get_current_dir(), false); } n = da->get_next(); } da->list_dir_end(); } - void ProjectManager::_scan_begin(const String &p_base) { print_line("Scanning projects at: " + p_base); - List<String> projects; - _scan_dir(p_base, &projects); - print_line("Found " + itos(projects.size()) + " projects."); - - for (const String &E : projects) { - String proj = get_project_key_from_path(E); - EditorSettings::get_singleton()->set("projects/" + proj, E); - } - EditorSettings::get_singleton()->save(); + _scan_dir(p_base); + _project_list->save_config(); _load_recent_projects(); } @@ -2346,9 +2314,7 @@ void ProjectManager::_rename_project() { } for (const String &E : selected_list) { - const String &selected = E; - String path = EditorSettings::get_singleton()->get("projects/" + selected); - npdialog->set_project_path(path); + npdialog->set_project_path(E); npdialog->set_mode(ProjectDialog::MODE_RENAME); npdialog->show_dialog(); } @@ -2451,7 +2417,7 @@ void ProjectManager::_files_dropped(PackedStringArray p_files) { } if (confirm) { multi_scan_ask->get_ok_button()->disconnect("pressed", callable_mp(this, &ProjectManager::_scan_multiple_folders)); - multi_scan_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_scan_multiple_folders), varray(folders)); + multi_scan_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_scan_multiple_folders).bind(folders)); multi_scan_ask->set_text( vformat(TTR("Are you sure to scan %s folders for existing Godot projects?\nThis could take a while."), folders.size())); multi_scan_ask->popup_centered(); @@ -2879,6 +2845,7 @@ ProjectManager::ProjectManager() { _build_icon_type_cache(get_theme()); } + _project_list->migrate_config(); _load_recent_projects(); Ref<DirAccess> dir_access = DirAccess::create(DirAccess::AccessType::ACCESS_FILESYSTEM); diff --git a/editor/project_manager.h b/editor/project_manager.h index 28383e4142..10bf25c048 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -125,7 +125,7 @@ class ProjectManager : public Control { void _on_projects_updated(); void _scan_multiple_folders(PackedStringArray p_files); void _scan_begin(const String &p_base); - void _scan_dir(const String &path, List<String> *r_projects); + void _scan_dir(const String &path); void _install_project(const String &p_zip_path, const String &p_title); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 49707355a0..ca5eeaa787 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -31,14 +31,18 @@ #include "project_settings_editor.h" #include "core/config/project_settings.h" -#include "editor/editor_export.h" #include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "servers/movie_writer/movie_writer.h" ProjectSettingsEditor *ProjectSettingsEditor::singleton = nullptr; +void ProjectSettingsEditor::connect_filesystem_dock_signals(FileSystemDock *p_fs_dock) { + localization_editor->connect_filesystem_dock_signals(p_fs_dock); +} + void ProjectSettingsEditor::popup_project_settings() { // Restore valid window bounds or pop up at default size. Rect2 saved_size = EditorSettings::get_singleton()->get_project_metadata("dialog_bounds", "project_settings", Rect2()); @@ -75,8 +79,13 @@ void ProjectSettingsEditor::_setting_edited(const String &p_name) { queue_save(); } +void ProjectSettingsEditor::_update_advanced(bool p_is_advanced) { + custom_properties->set_visible(p_is_advanced); +} + void ProjectSettingsEditor::_advanced_toggled(bool p_button_pressed) { EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", p_button_pressed); + _update_advanced(p_button_pressed); general_settings_inspector->set_restrict_to_basic_settings(!p_button_pressed); } @@ -585,35 +594,35 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { advanced->connect("toggled", callable_mp(this, &ProjectSettingsEditor::_advanced_toggled)); search_bar->add_child(advanced); - HBoxContainer *header = memnew(HBoxContainer); - general_editor->add_child(header); + custom_properties = memnew(HBoxContainer); + general_editor->add_child(custom_properties); property_box = memnew(LineEdit); property_box->set_placeholder(TTR("Select a Setting or Type its Name")); property_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); property_box->connect("text_changed", callable_mp(this, &ProjectSettingsEditor::_property_box_changed)); - header->add_child(property_box); + custom_properties->add_child(property_box); feature_box = memnew(OptionButton); feature_box->set_custom_minimum_size(Size2(120, 0) * EDSCALE); feature_box->connect("item_selected", callable_mp(this, &ProjectSettingsEditor::_feature_selected)); - header->add_child(feature_box); + custom_properties->add_child(feature_box); type_box = memnew(OptionButton); type_box->set_custom_minimum_size(Size2(120, 0) * EDSCALE); - header->add_child(type_box); + custom_properties->add_child(type_box); add_button = memnew(Button); add_button->set_text(TTR("Add")); add_button->set_disabled(true); add_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_add_setting)); - header->add_child(add_button); + custom_properties->add_child(add_button); del_button = memnew(Button); del_button->set_text(TTR("Delete")); del_button->set_disabled(true); del_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_delete_setting)); - header->add_child(del_button); + custom_properties->add_child(del_button); general_settings_inspector = memnew(SectionedInspector); general_settings_inspector->get_inspector()->set_undo_redo(EditorNode::get_singleton()->get_undo_redo()); @@ -670,10 +679,10 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { autoload_settings->connect("autoload_changed", callable_mp(this, &ProjectSettingsEditor::queue_save)); tab_container->add_child(autoload_settings); - shaders_global_variables_editor = memnew(ShaderGlobalsEditor); - shaders_global_variables_editor->set_name(TTR("Shader Globals")); - shaders_global_variables_editor->connect("globals_changed", callable_mp(this, &ProjectSettingsEditor::queue_save)); - tab_container->add_child(shaders_global_variables_editor); + shaders_global_shader_uniforms_editor = memnew(ShaderGlobalsEditor); + shaders_global_shader_uniforms_editor->set_name(TTR("Shader Globals")); + shaders_global_shader_uniforms_editor->connect("globals_changed", callable_mp(this, &ProjectSettingsEditor::queue_save)); + tab_container->add_child(shaders_global_shader_uniforms_editor); plugin_settings = memnew(EditorPluginSettings); plugin_settings->set_name(TTR("Plugins")); @@ -694,6 +703,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { advanced->set_pressed(true); } + _update_advanced(use_advanced); general_settings_inspector->set_restrict_to_basic_settings(!use_advanced); import_defaults_editor = memnew(ImportDefaultsEditor); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index 24d61db443..c2d2c2d8f4 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -43,6 +43,8 @@ #include "editor/shader_globals_editor.h" #include "scene/gui/tab_container.h" +class FileSystemDock; + class ProjectSettingsEditor : public AcceptDialog { GDCLASS(ProjectSettingsEditor, AcceptDialog); @@ -55,12 +57,13 @@ class ProjectSettingsEditor : public AcceptDialog { ActionMapEditor *action_map_editor = nullptr; LocalizationEditor *localization_editor = nullptr; EditorAutoloadSettings *autoload_settings = nullptr; - ShaderGlobalsEditor *shaders_global_variables_editor = nullptr; + ShaderGlobalsEditor *shaders_global_shader_uniforms_editor = nullptr; EditorPluginSettings *plugin_settings = nullptr; LineEdit *search_box = nullptr; CheckButton *advanced = nullptr; + HBoxContainer *custom_properties = nullptr; LineEdit *property_box = nullptr; OptionButton *feature_box = nullptr; OptionButton *type_box = nullptr; @@ -77,6 +80,7 @@ class ProjectSettingsEditor : public AcceptDialog { UndoRedo *undo_redo = nullptr; void _advanced_toggled(bool p_button_pressed); + void _update_advanced(bool p_is_advanced); void _property_box_changed(const String &p_text); void _update_property_box(); void _feature_selected(int p_index); @@ -118,6 +122,7 @@ public: TabContainer *get_tabs() { return tab_container; } void queue_save(); + void connect_filesystem_dock_signals(FileSystemDock *p_fs_dock); ProjectSettingsEditor(EditorData *p_data); }; diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp deleted file mode 100644 index 488a084903..0000000000 --- a/editor/property_editor.cpp +++ /dev/null @@ -1,1901 +0,0 @@ -/*************************************************************************/ -/* property_editor.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "property_editor.h" - -#include "core/config/project_settings.h" -#include "core/input/input.h" -#include "core/io/image_loader.h" -#include "core/io/marshalls.h" -#include "core/io/resource_loader.h" -#include "core/math/expression.h" -#include "core/object/class_db.h" -#include "core/os/keyboard.h" -#include "core/string/print_string.h" -#include "core/templates/pair.h" -#include "editor/array_property_edit.h" -#include "editor/create_dialog.h" -#include "editor/dictionary_property_edit.h" -#include "editor/editor_export.h" -#include "editor/editor_file_dialog.h" -#include "editor/editor_file_system.h" -#include "editor/editor_help.h" -#include "editor/editor_node.h" -#include "editor/editor_scale.h" -#include "editor/editor_settings.h" -#include "editor/filesystem_dock.h" -#include "editor/multi_node_edit.h" -#include "editor/property_selector.h" -#include "editor/scene_tree_dock.h" -#include "scene/gui/label.h" -#include "scene/main/window.h" -#include "scene/resources/font.h" -#include "scene/resources/packed_scene.h" -#include "scene/scene_string_names.h" - -void EditorResourceConversionPlugin::_bind_methods() { - GDVIRTUAL_BIND(_converts_to); - GDVIRTUAL_BIND(_handles, "resource"); - GDVIRTUAL_BIND(_convert, "resource"); -} - -String EditorResourceConversionPlugin::converts_to() const { - String ret; - if (GDVIRTUAL_CALL(_converts_to, ret)) { - return ret; - } - - return ""; -} - -bool EditorResourceConversionPlugin::handles(const Ref<Resource> &p_resource) const { - bool ret; - if (GDVIRTUAL_CALL(_handles, p_resource, ret)) { - return ret; - } - - return false; -} - -Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) const { - Ref<Resource> ret; - if (GDVIRTUAL_CALL(_convert, p_resource, ret)) { - return ret; - } - - return Ref<Resource>(); -} - -void CustomPropertyEditor::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_WM_CLOSE_REQUEST: { - hide(); - } break; - } -} - -void CustomPropertyEditor::_menu_option(int p_which) { - switch (type) { - case Variant::INT: { - if (hint == PROPERTY_HINT_FLAGS) { - int idx = menu->get_item_index(p_which); - uint32_t item_value = menu->get_item_metadata(idx); - uint32_t value = v; - // If the item wasn't previously checked it means it was pressed, - // otherwise it was unpressed. - if (!menu->is_item_checked(idx)) { - v = value | item_value; - } else { - v = value & ~item_value; - } - emit_signal(SNAME("variant_changed")); - } else if (hint == PROPERTY_HINT_ENUM) { - v = menu->get_item_metadata(p_which); - emit_signal(SNAME("variant_changed")); - } - } break; - case Variant::STRING: { - if (hint == PROPERTY_HINT_ENUM) { - v = hint_text.get_slice(",", p_which); - emit_signal(SNAME("variant_changed")); - } - } break; - case Variant::OBJECT: { - switch (p_which) { - case OBJ_MENU_LOAD: { - file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - String type = (hint == PROPERTY_HINT_RESOURCE_TYPE) ? hint_text : String(); - - List<String> extensions; - for (int i = 0; i < type.get_slice_count(","); i++) { - ResourceLoader::get_recognized_extensions_for_type(type.get_slice(",", i), &extensions); - } - - HashSet<String> valid_extensions; - for (const String &E : extensions) { - valid_extensions.insert(E); - } - - file->clear_filters(); - for (const String &E : valid_extensions) { - file->add_filter("*." + E, E.to_upper()); - } - - file->popup_file_dialog(); - } break; - - case OBJ_MENU_EDIT: { - Ref<RefCounted> r = v; - - if (!r.is_null()) { - emit_signal(SNAME("resource_edit_request")); - hide(); - } - } break; - case OBJ_MENU_CLEAR: { - v = Variant(); - emit_signal(SNAME("variant_changed")); - hide(); - } break; - - case OBJ_MENU_MAKE_UNIQUE: { - Ref<Resource> res_orig = v; - if (res_orig.is_null()) { - return; - } - - List<PropertyInfo> property_list; - res_orig->get_property_list(&property_list); - List<Pair<String, Variant>> propvalues; - - for (const PropertyInfo &pi : property_list) { - Pair<String, Variant> p; - if (pi.usage & PROPERTY_USAGE_STORAGE) { - p.first = pi.name; - p.second = res_orig->get(pi.name); - } - - propvalues.push_back(p); - } - - String orig_type = res_orig->get_class(); - - Object *inst = ClassDB::instantiate(orig_type); - - Ref<Resource> res = Ref<Resource>(Object::cast_to<Resource>(inst)); - - ERR_FAIL_COND(res.is_null()); - - for (const Pair<String, Variant> &p : propvalues) { - res->set(p.first, p.second); - } - - v = res; - emit_signal(SNAME("variant_changed")); - hide(); - } break; - - case OBJ_MENU_COPY: { - EditorSettings::get_singleton()->set_resource_clipboard(v); - - } break; - case OBJ_MENU_PASTE: { - v = EditorSettings::get_singleton()->get_resource_clipboard(); - emit_signal(SNAME("variant_changed")); - - } break; - case OBJ_MENU_NEW_SCRIPT: { - if (Object::cast_to<Node>(owner)) { - SceneTreeDock::get_singleton()->open_script_dialog(Object::cast_to<Node>(owner), false); - } - - } break; - case OBJ_MENU_EXTEND_SCRIPT: { - if (Object::cast_to<Node>(owner)) { - SceneTreeDock::get_singleton()->open_script_dialog(Object::cast_to<Node>(owner), true); - } - - } break; - case OBJ_MENU_SHOW_IN_FILE_SYSTEM: { - Ref<Resource> r = v; - FileSystemDock *file_system_dock = FileSystemDock::get_singleton(); - file_system_dock->navigate_to_path(r->get_path()); - // Ensure that the FileSystem dock is visible. - TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); - tab_container->set_current_tab(tab_container->get_tab_idx_from_control(file_system_dock)); - } break; - default: { - if (p_which >= CONVERT_BASE_ID) { - int to_type = p_which - CONVERT_BASE_ID; - - Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(Ref<Resource>(v)); - - ERR_FAIL_INDEX(to_type, conversions.size()); - - Ref<Resource> new_res = conversions[to_type]->convert(v); - - v = new_res; - emit_signal(SNAME("variant_changed")); - break; - } - ERR_FAIL_COND(inheritors_array.is_empty()); - - String intype = inheritors_array[p_which - TYPE_BASE_ID]; - - if (intype == "ViewportTexture") { - scene_tree->set_title(TTR("Pick a Viewport")); - scene_tree->popup_scenetree_dialog(); - picking_viewport = true; - return; - } - - Variant obj = ClassDB::instantiate(intype); - - if (!obj) { - if (ScriptServer::is_global_class(intype)) { - obj = EditorNode::get_editor_data().script_class_instance(intype); - } else { - obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); - } - } - - ERR_BREAK(!obj); - Resource *res = Object::cast_to<Resource>(obj); - ERR_BREAK(!res); - if (owner && hint == PROPERTY_HINT_RESOURCE_TYPE && hint_text == "Script") { - //make visual script the right type - res->call("set_instance_base_type", owner->get_class()); - } - - EditorNode::get_editor_data().instantiate_object_properties(obj); - v = obj; - - emit_signal(SNAME("variant_changed")); - - } break; - } - - } break; - default: { - } - } -} - -void CustomPropertyEditor::hide_menu() { - menu->hide(); -} - -Variant CustomPropertyEditor::get_variant() const { - return v; -} - -String CustomPropertyEditor::get_name() const { - return name; -} - -bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::Type p_type, const Variant &p_variant, int p_hint, String p_hint_text) { - owner = p_owner; - updating = true; - name = p_name; - v = p_variant; - field_names.clear(); - hint = p_hint; - hint_text = p_hint_text; - type_button->hide(); - if (color_picker) { - color_picker->hide(); - } - texture_preview->hide(); - inheritors_array.clear(); - text_edit->hide(); - easing_draw->hide(); - spinbox->hide(); - slider->hide(); - menu->clear(); - menu->reset_size(); - - for (int i = 0; i < MAX_VALUE_EDITORS; i++) { - if (i < MAX_VALUE_EDITORS / 4) { - value_hboxes[i]->hide(); - } - value_editor[i]->hide(); - value_label[i]->hide(); - if (i < 4) { - scroll[i]->hide(); - } - } - - for (int i = 0; i < MAX_ACTION_BUTTONS; i++) { - action_buttons[i]->hide(); - } - - checks20gc->hide(); - for (int i = 0; i < 20; i++) { - checks20[i]->hide(); - } - - type = (p_variant.get_type() != Variant::NIL && p_variant.get_type() != Variant::RID && p_type != Variant::OBJECT) ? p_variant.get_type() : p_type; - - switch (type) { - case Variant::BOOL: { - checks20gc->show(); - - CheckBox *c = checks20[0]; - c->set_text("True"); - checks20gc->set_position(Vector2(4, 4) * EDSCALE); - c->set_pressed(v); - c->show(); - - checks20gc->set_size(checks20gc->get_minimum_size()); - set_size(checks20gc->get_position() + checks20gc->get_size() + c->get_size() + Vector2(4, 4) * EDSCALE); - - } break; - case Variant::INT: - case Variant::FLOAT: { - if (hint == PROPERTY_HINT_RANGE) { - int c = hint_text.get_slice_count(","); - float min = 0, max = 100, step = type == Variant::FLOAT ? .01 : 1; - if (c >= 1) { - if (!hint_text.get_slice(",", 0).is_empty()) { - min = hint_text.get_slice(",", 0).to_float(); - } - } - if (c >= 2) { - if (!hint_text.get_slice(",", 1).is_empty()) { - max = hint_text.get_slice(",", 1).to_float(); - } - } - - if (c >= 3) { - if (!hint_text.get_slice(",", 2).is_empty()) { - step = hint_text.get_slice(",", 2).to_float(); - } - } - - if (c >= 4 && hint_text.get_slice(",", 3) == "slider") { - slider->set_min(min); - slider->set_max(max); - slider->set_step(step); - slider->set_value(v); - slider->show(); - set_size(Size2(110, 30) * EDSCALE); - } else { - spinbox->set_min(min); - spinbox->set_max(max); - spinbox->set_step(step); - spinbox->set_value(v); - spinbox->show(); - set_size(Size2(70, 35) * EDSCALE); - } - - } else if (hint == PROPERTY_HINT_ENUM) { - Vector<String> options = hint_text.split(","); - int current_val = 0; - for (int i = 0; i < options.size(); i++) { - Vector<String> text_split = options[i].split(":"); - if (text_split.size() != 1) { - current_val = text_split[1].to_int(); - } - menu->add_item(text_split[0]); - menu->set_item_metadata(i, current_val); - current_val += 1; - } - menu->set_position(get_position()); - menu->popup(); - hide(); - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || - hint == PROPERTY_HINT_LAYERS_2D_RENDER || - hint == PROPERTY_HINT_LAYERS_2D_NAVIGATION || - hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || - hint == PROPERTY_HINT_LAYERS_3D_RENDER || - hint == PROPERTY_HINT_LAYERS_3D_NAVIGATION) { - String basename; - switch (hint) { - case PROPERTY_HINT_LAYERS_2D_RENDER: - basename = "layer_names/2d_render"; - break; - case PROPERTY_HINT_LAYERS_2D_PHYSICS: - basename = "layer_names/2d_physics"; - break; - case PROPERTY_HINT_LAYERS_2D_NAVIGATION: - basename = "layer_names/2d_navigation"; - break; - case PROPERTY_HINT_LAYERS_3D_RENDER: - basename = "layer_names/3d_render"; - break; - case PROPERTY_HINT_LAYERS_3D_PHYSICS: - basename = "layer_names/3d_physics"; - break; - case PROPERTY_HINT_LAYERS_3D_NAVIGATION: - basename = "layer_names/3d_navigation"; - break; - } - - checks20gc->show(); - uint32_t flgs = v; - for (int i = 0; i < 2; i++) { - Point2 ofs(4, 4); - ofs.y += 22 * i; - for (int j = 0; j < 10; j++) { - int idx = i * 10 + j; - CheckBox *c = checks20[idx]; - c->set_text(ProjectSettings::get_singleton()->get(basename + "/layer_" + itos(idx + 1))); - c->set_pressed(flgs & (1 << (i * 10 + j))); - c->show(); - } - } - - show(); - - checks20gc->set_position(Vector2(4, 4) * EDSCALE); - checks20gc->set_size(checks20gc->get_minimum_size()); - - set_size(Vector2(4, 4) * EDSCALE + checks20gc->get_position() + checks20gc->get_size()); - - } else if (hint == PROPERTY_HINT_EXP_EASING) { - easing_draw->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 5 * EDSCALE); - easing_draw->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -5 * EDSCALE); - easing_draw->set_anchor_and_offset(SIDE_TOP, Control::ANCHOR_BEGIN, 5 * EDSCALE); - easing_draw->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_END, -30 * EDSCALE); - type_button->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 3 * EDSCALE); - type_button->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -3 * EDSCALE); - type_button->set_anchor_and_offset(SIDE_TOP, Control::ANCHOR_END, -25 * EDSCALE); - type_button->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_END, -7 * EDSCALE); - type_button->set_text(TTR("Preset...")); - type_button->get_popup()->clear(); - type_button->get_popup()->add_item(TTR("Linear"), EASING_LINEAR); - type_button->get_popup()->add_item(TTR("Ease In"), EASING_EASE_IN); - type_button->get_popup()->add_item(TTR("Ease Out"), EASING_EASE_OUT); - if (hint_text != "attenuation") { - type_button->get_popup()->add_item(TTR("Zero"), EASING_ZERO); - type_button->get_popup()->add_item(TTR("Easing In-Out"), EASING_IN_OUT); - type_button->get_popup()->add_item(TTR("Easing Out-In"), EASING_OUT_IN); - } - - type_button->show(); - easing_draw->show(); - set_size(Size2(200, 150) * EDSCALE); - } else if (hint == PROPERTY_HINT_FLAGS) { - Vector<String> flags = hint_text.split(","); - uint32_t value = v; - for (int i = 0; i < flags.size(); i++) { - uint32_t current_val; - Vector<String> text_split = flags[i].split(":"); - if (text_split.size() != 1) { - current_val = text_split[1].to_int(); - } else { - current_val = 1 << i; - } - menu->add_check_item(text_split[0], current_val); - menu->set_item_metadata(i, current_val); - if ((value & current_val) == current_val) { - menu->set_item_checked(menu->get_item_index(current_val), true); - } - } - menu->set_position(get_position()); - menu->popup(); - hide(); - updating = false; - return false; - - } else { - List<String> names; - names.push_back("value:"); - config_value_editors(1, 1, 50, names); - value_editor[0]->set_text(TS->format_number(String::num(v))); - } - - } break; - case Variant::STRING: { - if (hint == PROPERTY_HINT_LOCALE_ID) { - List<String> names; - names.push_back(TTR("Locale...")); - names.push_back(TTR("Clear")); - config_action_buttons(names); - } else if (hint == PROPERTY_HINT_FILE || hint == PROPERTY_HINT_GLOBAL_FILE) { - List<String> names; - names.push_back(TTR("File...")); - names.push_back(TTR("Clear")); - config_action_buttons(names); - } else if (hint == PROPERTY_HINT_DIR || hint == PROPERTY_HINT_GLOBAL_DIR) { - List<String> names; - names.push_back(TTR("Dir...")); - names.push_back(TTR("Clear")); - config_action_buttons(names); - } else if (hint == PROPERTY_HINT_ENUM) { - Vector<String> options = hint_text.split(","); - for (int i = 0; i < options.size(); i++) { - menu->add_item(options[i], i); - } - menu->set_position(get_position()); - menu->popup(); - hide(); - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_MULTILINE_TEXT) { - text_edit->show(); - text_edit->set_text(v); - text_edit->deselect(); - - int button_margin = text_edit->get_theme_constant(SNAME("button_margin"), SNAME("Dialogs")); - int margin = text_edit->get_theme_constant(SNAME("margin"), SNAME("Dialogs")); - - action_buttons[0]->set_anchor(SIDE_LEFT, Control::ANCHOR_END); - action_buttons[0]->set_anchor(SIDE_TOP, Control::ANCHOR_END); - action_buttons[0]->set_anchor(SIDE_RIGHT, Control::ANCHOR_END); - action_buttons[0]->set_anchor(SIDE_BOTTOM, Control::ANCHOR_END); - action_buttons[0]->set_begin(Point2(-70 * EDSCALE, -button_margin + 5 * EDSCALE)); - action_buttons[0]->set_end(Point2(-margin, -margin)); - action_buttons[0]->set_text(TTR("Close")); - action_buttons[0]->show(); - - } else if (hint == PROPERTY_HINT_TYPE_STRING) { - if (!create_dialog) { - create_dialog = memnew(CreateDialog); - create_dialog->connect("create", callable_mp(this, &CustomPropertyEditor::_create_dialog_callback)); - add_child(create_dialog); - } - - if (!hint_text.is_empty()) { - create_dialog->set_base_type(hint_text); - } else { - create_dialog->set_base_type("Object"); - } - - create_dialog->popup_create(false); - hide(); - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_METHOD_OF_VARIANT_TYPE) { -#define MAKE_PROPSELECT \ - if (!property_select) { \ - property_select = memnew(PropertySelector); \ - property_select->connect("selected", callable_mp(this, &CustomPropertyEditor::_create_selected_property)); \ - add_child(property_select); \ - } \ - hide(); - - MAKE_PROPSELECT; - - Variant::Type type = Variant::NIL; - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (hint_text == Variant::get_type_name(Variant::Type(i))) { - type = Variant::Type(i); - } - } - if (type != Variant::NIL) { - property_select->select_method_from_basic_type(type, v); - } - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_METHOD_OF_BASE_TYPE) { - MAKE_PROPSELECT - - property_select->select_method_from_base_type(hint_text, v); - - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_METHOD_OF_INSTANCE) { - MAKE_PROPSELECT - - Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int())); - if (instance) { - property_select->select_method_from_instance(instance, v); - } - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_METHOD_OF_SCRIPT) { - MAKE_PROPSELECT - - Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int())); - if (Object::cast_to<Script>(obj)) { - property_select->select_method_from_script(Object::cast_to<Script>(obj), v); - } - - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE) { - MAKE_PROPSELECT - Variant::Type type = Variant::NIL; - String tname = hint_text; - if (tname.contains(".")) { - tname = tname.get_slice(".", 0); - } - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (tname == Variant::get_type_name(Variant::Type(i))) { - type = Variant::Type(Variant::Type(i)); - } - } - - if (type != Variant::NIL) { - property_select->select_property_from_basic_type(type, v); - } - - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_PROPERTY_OF_BASE_TYPE) { - MAKE_PROPSELECT - - property_select->select_property_from_base_type(hint_text, v); - - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_PROPERTY_OF_INSTANCE) { - MAKE_PROPSELECT - - Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int())); - if (instance) { - property_select->select_property_from_instance(instance, v); - } - - updating = false; - return false; - - } else if (hint == PROPERTY_HINT_PROPERTY_OF_SCRIPT) { - MAKE_PROPSELECT - - Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int())); - if (Object::cast_to<Script>(obj)) { - property_select->select_property_from_script(Object::cast_to<Script>(obj), v); - } - - updating = false; - return false; - - } else { - List<String> names; - names.push_back("string:"); - config_value_editors(1, 1, 50, names); - value_editor[0]->set_text(v); - } - - } break; - case Variant::VECTOR2: { - field_names.push_back("x"); - field_names.push_back("y"); - config_value_editors(2, 2, 10, field_names); - Vector2 vec = v; - value_editor[0]->set_text(String::num(vec.x)); - value_editor[1]->set_text(String::num(vec.y)); - } break; - case Variant::RECT2: { - field_names.push_back("x"); - field_names.push_back("y"); - field_names.push_back("w"); - field_names.push_back("h"); - config_value_editors(4, 4, 10, field_names); - Rect2 r = v; - value_editor[0]->set_text(String::num(r.position.x)); - value_editor[1]->set_text(String::num(r.position.y)); - value_editor[2]->set_text(String::num(r.size.x)); - value_editor[3]->set_text(String::num(r.size.y)); - } break; - case Variant::VECTOR3: { - field_names.push_back("x"); - field_names.push_back("y"); - field_names.push_back("z"); - config_value_editors(3, 3, 10, field_names); - Vector3 vec = v; - value_editor[0]->set_text(String::num(vec.x)); - value_editor[1]->set_text(String::num(vec.y)); - value_editor[2]->set_text(String::num(vec.z)); - } break; - case Variant::PLANE: { - field_names.push_back("x"); - field_names.push_back("y"); - field_names.push_back("z"); - field_names.push_back("d"); - config_value_editors(4, 4, 10, field_names); - Plane plane = v; - value_editor[0]->set_text(String::num(plane.normal.x)); - value_editor[1]->set_text(String::num(plane.normal.y)); - value_editor[2]->set_text(String::num(plane.normal.z)); - value_editor[3]->set_text(String::num(plane.d)); - - } break; - case Variant::QUATERNION: { - field_names.push_back("x"); - field_names.push_back("y"); - field_names.push_back("z"); - field_names.push_back("w"); - config_value_editors(4, 4, 10, field_names); - Quaternion q = v; - value_editor[0]->set_text(String::num(q.x)); - value_editor[1]->set_text(String::num(q.y)); - value_editor[2]->set_text(String::num(q.z)); - value_editor[3]->set_text(String::num(q.w)); - - } break; - case Variant::AABB: { - field_names.push_back("px"); - field_names.push_back("py"); - field_names.push_back("pz"); - field_names.push_back("sx"); - field_names.push_back("sy"); - field_names.push_back("sz"); - config_value_editors(6, 3, 16, field_names); - - AABB aabb = v; - value_editor[0]->set_text(String::num(aabb.position.x)); - value_editor[1]->set_text(String::num(aabb.position.y)); - value_editor[2]->set_text(String::num(aabb.position.z)); - value_editor[3]->set_text(String::num(aabb.size.x)); - value_editor[4]->set_text(String::num(aabb.size.y)); - value_editor[5]->set_text(String::num(aabb.size.z)); - - } break; - case Variant::TRANSFORM2D: { - field_names.push_back("xx"); - field_names.push_back("xy"); - field_names.push_back("yx"); - field_names.push_back("yy"); - field_names.push_back("ox"); - field_names.push_back("oy"); - config_value_editors(6, 2, 16, field_names); - - Transform2D basis = v; - for (int i = 0; i < 6; i++) { - value_editor[i]->set_text(String::num(basis.columns[i / 2][i % 2])); - } - - } break; - case Variant::BASIS: { - field_names.push_back("xx"); - field_names.push_back("xy"); - field_names.push_back("xz"); - field_names.push_back("yx"); - field_names.push_back("yy"); - field_names.push_back("yz"); - field_names.push_back("zx"); - field_names.push_back("zy"); - field_names.push_back("zz"); - config_value_editors(9, 3, 16, field_names); - - Basis basis = v; - for (int i = 0; i < 9; i++) { - value_editor[i]->set_text(String::num(basis.rows[i / 3][i % 3])); - } - - } break; - case Variant::TRANSFORM3D: { - field_names.push_back("xx"); - field_names.push_back("xy"); - field_names.push_back("xz"); - field_names.push_back("xo"); - field_names.push_back("yx"); - field_names.push_back("yy"); - field_names.push_back("yz"); - field_names.push_back("yo"); - field_names.push_back("zx"); - field_names.push_back("zy"); - field_names.push_back("zz"); - field_names.push_back("zo"); - config_value_editors(12, 4, 16, field_names); - - Transform3D tr = v; - for (int i = 0; i < 9; i++) { - value_editor[(i / 3) * 4 + i % 3]->set_text(String::num(tr.basis.rows[i / 3][i % 3])); - } - - value_editor[3]->set_text(String::num(tr.origin.x)); - value_editor[7]->set_text(String::num(tr.origin.y)); - value_editor[11]->set_text(String::num(tr.origin.z)); - - } break; - case Variant::COLOR: { - if (!color_picker) { - //late init for performance - color_picker = memnew(ColorPicker); - color_picker->set_deferred_mode(true); - value_vbox->add_child(color_picker); - color_picker->hide(); - color_picker->connect("color_changed", callable_mp(this, &CustomPropertyEditor::_color_changed)); - color_picker->connect("show", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(color_picker)); - } - - color_picker->show(); - color_picker->set_edit_alpha(hint != PROPERTY_HINT_COLOR_NO_ALPHA); - color_picker->set_pick_color(v); - color_picker->set_focus_on_line_edit(); - - } break; - - case Variant::NODE_PATH: { - List<String> names; - names.push_back(TTR("Assign")); - names.push_back(TTR("Clear")); - - if (owner && owner->is_class("Node") && (v.get_type() == Variant::NODE_PATH) && Object::cast_to<Node>(owner)->has_node(v)) { - names.push_back(TTR("Select Node")); - } - - config_action_buttons(names); - - } break; - case Variant::OBJECT: { - if (hint != PROPERTY_HINT_RESOURCE_TYPE) { - break; - } - - if (p_name == "script" && hint_text == "Script" && Object::cast_to<Node>(owner)) { - menu->add_item(TTR("New Script"), OBJ_MENU_NEW_SCRIPT); - menu->add_separator(); - } else if (!hint_text.is_empty()) { - int idx = 0; - - Vector<EditorData::CustomType> custom_resources; - - if (EditorNode::get_editor_data().get_custom_types().has("Resource")) { - custom_resources = EditorNode::get_editor_data().get_custom_types()["Resource"]; - } - - for (int i = 0; i < hint_text.get_slice_count(","); i++) { - String base = hint_text.get_slice(",", i); - - HashSet<String> valid_inheritors; - valid_inheritors.insert(base); - List<StringName> inheritors; - ClassDB::get_inheriters_from_class(base.strip_edges(), &inheritors); - - for (int j = 0; j < custom_resources.size(); j++) { - inheritors.push_back(custom_resources[j].name); - } - - List<StringName>::Element *E = inheritors.front(); - while (E) { - valid_inheritors.insert(E->get()); - E = E->next(); - } - - for (const String &j : valid_inheritors) { - const String &t = j; - - bool is_custom_resource = false; - Ref<Texture2D> icon; - if (!custom_resources.is_empty()) { - for (int k = 0; k < custom_resources.size(); k++) { - if (custom_resources[k].name == t) { - is_custom_resource = true; - if (custom_resources[k].icon.is_valid()) { - icon = custom_resources[k].icon; - } - break; - } - } - } - - if (!is_custom_resource && (!ClassDB::can_instantiate(t) || ClassDB::is_virtual(t))) { - continue; - } - - inheritors_array.push_back(t); - - int id = TYPE_BASE_ID + idx; - - menu->add_item(vformat(TTR("New %s"), t), id); - - idx++; - } - } - - if (menu->get_item_count()) { - menu->add_separator(); - } - } - - menu->add_item(TTR("Load"), OBJ_MENU_LOAD); - - if (!Ref<Resource>(v).is_null()) { - menu->add_item(TTR("Edit"), OBJ_MENU_EDIT); - menu->add_item(TTR("Clear"), OBJ_MENU_CLEAR); - menu->add_item(TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE); - - Ref<Resource> r = v; - if (r.is_valid() && r->get_path().is_resource_file()) { - menu->add_separator(); - menu->add_item(TTR("Show in FileSystem"), OBJ_MENU_SHOW_IN_FILE_SYSTEM); - } - } - - Ref<Resource> cb = EditorSettings::get_singleton()->get_resource_clipboard(); - bool paste_valid = false; - if (cb.is_valid()) { - if (hint_text.is_empty()) { - paste_valid = true; - } else { - for (int i = 0; i < hint_text.get_slice_count(","); i++) { - if (ClassDB::is_parent_class(cb->get_class(), hint_text.get_slice(",", i))) { - paste_valid = true; - break; - } - } - } - } - - if (!Ref<Resource>(v).is_null() || paste_valid) { - menu->add_separator(); - - if (!Ref<Resource>(v).is_null()) { - menu->add_item(TTR("Copy"), OBJ_MENU_COPY); - } - - if (paste_valid) { - menu->add_item(TTR("Paste"), OBJ_MENU_PASTE); - } - } - - if (!Ref<Resource>(v).is_null()) { - Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(Ref<Resource>(v)); - if (conversions.size()) { - menu->add_separator(); - } - for (int i = 0; i < conversions.size(); i++) { - String what = conversions[i]->converts_to(); - menu->add_item(vformat(TTR("Convert to %s"), what), CONVERT_BASE_ID + i); - } - } - - menu->set_position(get_position()); - menu->popup(); - hide(); - updating = false; - return false; - } break; - case Variant::DICTIONARY: { - } break; - case Variant::PACKED_BYTE_ARRAY: { - } break; - case Variant::PACKED_INT32_ARRAY: { - } break; - case Variant::PACKED_FLOAT32_ARRAY: { - } break; - case Variant::PACKED_INT64_ARRAY: { - } break; - case Variant::PACKED_FLOAT64_ARRAY: { - } break; - case Variant::PACKED_STRING_ARRAY: { - } break; - case Variant::PACKED_VECTOR3_ARRAY: { - } break; - case Variant::PACKED_COLOR_ARRAY: { - } break; - default: { - } - } - - updating = false; - return true; -} - -void CustomPropertyEditor::_file_selected(String p_file) { - switch (type) { - case Variant::STRING: { - if (hint == PROPERTY_HINT_FILE || hint == PROPERTY_HINT_DIR) { - v = ProjectSettings::get_singleton()->localize_path(p_file); - emit_signal(SNAME("variant_changed")); - hide(); - } - - if (hint == PROPERTY_HINT_GLOBAL_FILE || hint == PROPERTY_HINT_GLOBAL_DIR) { - v = p_file; - emit_signal(SNAME("variant_changed")); - hide(); - } - - } break; - case Variant::OBJECT: { - String type = (hint == PROPERTY_HINT_RESOURCE_TYPE) ? hint_text : String(); - - Ref<Resource> res = ResourceLoader::load(p_file, type); - if (res.is_null()) { - error->set_text(TTR("Error loading file: Not a resource!")); - error->popup_centered(); - break; - } - v = res; - emit_signal(SNAME("variant_changed")); - hide(); - } break; - default: { - } - } -} - -void CustomPropertyEditor::_locale_selected(String p_locale) { - if (type == Variant::STRING && hint == PROPERTY_HINT_LOCALE_ID) { - v = p_locale; - emit_signal(SNAME("variant_changed")); - hide(); - } -} - -void CustomPropertyEditor::_type_create_selected(int p_idx) { - if (type == Variant::INT || type == Variant::FLOAT) { - float newval = 0; - switch (p_idx) { - case EASING_LINEAR: { - newval = 1; - } break; - case EASING_EASE_IN: { - newval = 2.0; - } break; - case EASING_EASE_OUT: { - newval = 0.5; - } break; - case EASING_ZERO: { - newval = 0; - } break; - case EASING_IN_OUT: { - newval = -0.5; - } break; - case EASING_OUT_IN: { - newval = -2.0; - } break; - } - - v = newval; - emit_signal(SNAME("variant_changed")); - easing_draw->update(); - - } else if (type == Variant::OBJECT) { - ERR_FAIL_INDEX(p_idx, inheritors_array.size()); - - String intype = inheritors_array[p_idx]; - - Variant obj = ClassDB::instantiate(intype); - - if (!obj) { - if (ScriptServer::is_global_class(intype)) { - obj = EditorNode::get_editor_data().script_class_instance(intype); - } else { - obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); - } - } - - ERR_FAIL_COND(!obj); - ERR_FAIL_COND(!Object::cast_to<Resource>(obj)); - - EditorNode::get_editor_data().instantiate_object_properties(obj); - v = obj; - - emit_signal(SNAME("variant_changed")); - hide(); - } -} - -void CustomPropertyEditor::_color_changed(const Color &p_color) { - v = p_color; - emit_signal(SNAME("variant_changed")); -} - -void CustomPropertyEditor::_node_path_selected(NodePath p_path) { - if (picking_viewport) { - Node *to_node = get_node(p_path); - if (!Object::cast_to<Viewport>(to_node)) { - EditorNode::get_singleton()->show_warning(TTR("Selected node is not a Viewport!")); - return; - } - - Ref<ViewportTexture> vt; - vt.instantiate(); - vt->set_viewport_path_in_scene(get_tree()->get_edited_scene_root()->get_path_to(to_node)); - vt->setup_local_to_scene(); - v = vt; - emit_signal(SNAME("variant_changed")); - return; - } - - if (hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && !hint_text.is_empty()) { - Node *node = get_node(hint_text); - if (node) { - Node *tonode = node->get_node(p_path); - if (tonode) { - p_path = node->get_path_to(tonode); - } - } - - } else if (owner) { - Node *node = nullptr; - - if (owner->is_class("Node")) { - node = Object::cast_to<Node>(owner); - } else if (owner->is_class("ArrayPropertyEdit")) { - node = Object::cast_to<ArrayPropertyEdit>(owner)->get_node(); - } else if (owner->is_class("DictionaryPropertyEdit")) { - node = Object::cast_to<DictionaryPropertyEdit>(owner)->get_node(); - } - if (!node) { - v = p_path; - emit_signal(SNAME("variant_changed")); - call_deferred(SNAME("hide")); //to not mess with dialogs - return; - } - - Node *tonode = node->get_node(p_path); - if (tonode) { - p_path = node->get_path_to(tonode); - } - } - - v = p_path; - emit_signal(SNAME("variant_changed")); - call_deferred(SNAME("hide")); //to not mess with dialogs -} - -void CustomPropertyEditor::_action_pressed(int p_which) { - if (updating) { - return; - } - - switch (type) { - case Variant::BOOL: { - v = checks20[0]->is_pressed(); - emit_signal(SNAME("variant_changed")); - } break; - case Variant::INT: { - if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || - hint == PROPERTY_HINT_LAYERS_2D_RENDER || - hint == PROPERTY_HINT_LAYERS_2D_NAVIGATION || - hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || - hint == PROPERTY_HINT_LAYERS_3D_RENDER || - hint == PROPERTY_HINT_LAYERS_3D_NAVIGATION) { - uint32_t f = v; - if (checks20[p_which]->is_pressed()) { - f |= (1 << p_which); - } else { - f &= ~(1 << p_which); - } - - v = f; - emit_signal(SNAME("variant_changed")); - } - - } break; - case Variant::STRING: { - if (hint == PROPERTY_HINT_MULTILINE_TEXT) { - hide(); - } else if (hint == PROPERTY_HINT_LOCALE_ID) { - locale->popup_locale_dialog(); - } else if (hint == PROPERTY_HINT_FILE || hint == PROPERTY_HINT_GLOBAL_FILE) { - if (p_which == 0) { - if (hint == PROPERTY_HINT_FILE) { - file->set_access(EditorFileDialog::ACCESS_RESOURCES); - } else { - file->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - } - - file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - file->clear_filters(); - - file->clear_filters(); - - if (!hint_text.is_empty()) { - Vector<String> extensions = hint_text.split(","); - for (int i = 0; i < extensions.size(); i++) { - String filter = extensions[i]; - if (filter.begins_with(".")) { - filter = "*" + extensions[i]; - } else if (!filter.begins_with("*")) { - filter = "*." + extensions[i]; - } - - file->add_filter(filter, extensions[i].to_upper()); - } - } - file->popup_file_dialog(); - } else { - v = ""; - emit_signal(SNAME("variant_changed")); - hide(); - } - - } else if (hint == PROPERTY_HINT_DIR || hint == PROPERTY_HINT_GLOBAL_DIR) { - if (p_which == 0) { - if (hint == PROPERTY_HINT_DIR) { - file->set_access(EditorFileDialog::ACCESS_RESOURCES); - } else { - file->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - } - file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR); - file->clear_filters(); - file->popup_file_dialog(); - } else { - v = ""; - emit_signal(SNAME("variant_changed")); - hide(); - } - } - - } break; - case Variant::NODE_PATH: { - if (p_which == 0) { - picking_viewport = false; - scene_tree->set_title(TTR("Pick a Node")); - scene_tree->popup_scenetree_dialog(); - - } else if (p_which == 1) { - v = NodePath(); - emit_signal(SNAME("variant_changed")); - hide(); - } else if (p_which == 2) { - if (owner->is_class("Node") && (v.get_type() == Variant::NODE_PATH) && Object::cast_to<Node>(owner)->has_node(v)) { - Node *target_node = Object::cast_to<Node>(owner)->get_node(v); - EditorNode::get_singleton()->get_editor_selection()->clear(); - SceneTreeDock::get_singleton()->set_selected(target_node); - } - - hide(); - } - - } break; - case Variant::OBJECT: { - if (p_which == 0) { - ERR_FAIL_COND(inheritors_array.is_empty()); - - String intype = inheritors_array[0]; - - if (hint == PROPERTY_HINT_RESOURCE_TYPE) { - Variant obj = ClassDB::instantiate(intype); - - if (!obj) { - if (ScriptServer::is_global_class(intype)) { - obj = EditorNode::get_editor_data().script_class_instance(intype); - } else { - obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); - } - } - - ERR_BREAK(!obj); - ERR_BREAK(!Object::cast_to<Resource>(obj)); - - EditorNode::get_editor_data().instantiate_object_properties(obj); - v = obj; - - emit_signal(SNAME("variant_changed")); - hide(); - } - } else if (p_which == 1) { - file->set_access(EditorFileDialog::ACCESS_RESOURCES); - file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - List<String> extensions; - String type = (hint == PROPERTY_HINT_RESOURCE_TYPE) ? hint_text : String(); - - ResourceLoader::get_recognized_extensions_for_type(type, &extensions); - file->clear_filters(); - for (const String &E : extensions) { - file->add_filter("*." + E, E.to_upper()); - } - - file->popup_file_dialog(); - - } else if (p_which == 2) { - Ref<Resource> r = v; - - if (!r.is_null()) { - emit_signal(SNAME("resource_edit_request")); - hide(); - } - - } else if (p_which == 3) { - v = Variant(); - emit_signal(SNAME("variant_changed")); - hide(); - } else if (p_which == 4) { - Ref<Resource> res_orig = v; - if (res_orig.is_null()) { - return; - } - - List<PropertyInfo> property_list; - res_orig->get_property_list(&property_list); - List<Pair<String, Variant>> propvalues; - - for (const PropertyInfo &pi : property_list) { - Pair<String, Variant> p; - if (pi.usage & PROPERTY_USAGE_STORAGE) { - p.first = pi.name; - p.second = res_orig->get(pi.name); - } - - propvalues.push_back(p); - } - - Ref<Resource> res = Ref<Resource>(ClassDB::instantiate(res_orig->get_class())); - - ERR_FAIL_COND(res.is_null()); - - for (const Pair<String, Variant> &p : propvalues) { - res->set(p.first, p.second); - } - - v = res; - emit_signal(SNAME("variant_changed")); - hide(); - } - - } break; - - default: { - }; - } -} - -void CustomPropertyEditor::_drag_easing(const Ref<InputEvent> &p_ev) { - Ref<InputEventMouseMotion> mm = p_ev; - - if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { - float rel = mm->get_relative().x; - if (rel == 0) { - return; - } - - bool flip = hint_text == "attenuation"; - - if (flip) { - rel = -rel; - } - - float val = v; - if (val == 0) { - return; - } - bool sg = val < 0; - val = Math::absf(val); - - val = Math::log(val) / Math::log((float)2.0); - //logspace - val += rel * 0.05; - - val = Math::pow(2.0f, val); - if (sg) { - val = -val; - } - - v = val; - easing_draw->update(); - emit_signal(SNAME("variant_changed")); - } -} - -void CustomPropertyEditor::_draw_easing() { - RID ci = easing_draw->get_canvas_item(); - - Size2 s = easing_draw->get_size(); - Rect2 r(Point2(), s); - r = r.grow(3); - easing_draw->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))->draw(ci, r); - - int points = 48; - - float prev = 1.0; - float exp = v; - bool flip = hint_text == "attenuation"; - - Ref<Font> f = easing_draw->get_theme_font(SNAME("font"), SNAME("Label")); - int font_size = easing_draw->get_theme_font_size(SNAME("font_size"), SNAME("Label")); - Color color = easing_draw->get_theme_color(SNAME("font_color"), SNAME("Label")); - - for (int i = 1; i <= points; i++) { - float ifl = i / float(points); - float iflp = (i - 1) / float(points); - - float h = 1.0 - Math::ease(ifl, exp); - - if (flip) { - ifl = 1.0 - ifl; - iflp = 1.0 - iflp; - } - - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(iflp * s.width, prev * s.height), Point2(ifl * s.width, h * s.height), color); - prev = h; - } - - f->draw_string(ci, Point2(10, 10 + f->get_ascent(font_size)), String::num(exp, 2), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color); -} - -void CustomPropertyEditor::_text_edit_changed() { - v = text_edit->get_text(); - emit_signal(SNAME("variant_changed")); -} - -void CustomPropertyEditor::_create_dialog_callback() { - v = create_dialog->get_selected_type(); - emit_signal(SNAME("variant_changed")); -} - -void CustomPropertyEditor::_create_selected_property(const String &p_prop) { - v = p_prop; - emit_signal(SNAME("variant_changed")); -} - -void CustomPropertyEditor::_modified(String p_string) { - if (updating) { - return; - } - - Variant prev_v = v; - - updating = true; - switch (type) { - case Variant::INT: { - String text = TS->parse_number(value_editor[0]->get_text()); - Ref<Expression> expr; - expr.instantiate(); - Error err = expr->parse(text); - if (err != OK) { - v = value_editor[0]->get_text().to_int(); - return; - } else { - v = expr->execute(Array(), nullptr, false, false); - } - - if (v != prev_v) { - emit_signal(SNAME("variant_changed")); - } - } break; - case Variant::FLOAT: { - if (hint != PROPERTY_HINT_EXP_EASING) { - String text = TS->parse_number(value_editor[0]->get_text()); - v = _parse_real_expression(text); - if (v != prev_v) { - emit_signal(SNAME("variant_changed")); - } - } - - } break; - case Variant::STRING: { - v = value_editor[0]->get_text(); - emit_signal(SNAME("variant_changed")); - } break; - case Variant::VECTOR2: { - Vector2 vec; - vec.x = _parse_real_expression(value_editor[0]->get_text()); - vec.y = _parse_real_expression(value_editor[1]->get_text()); - v = vec; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::RECT2: { - Rect2 r2; - - r2.position.x = _parse_real_expression(value_editor[0]->get_text()); - r2.position.y = _parse_real_expression(value_editor[1]->get_text()); - r2.size.x = _parse_real_expression(value_editor[2]->get_text()); - r2.size.y = _parse_real_expression(value_editor[3]->get_text()); - v = r2; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - - case Variant::VECTOR3: { - Vector3 vec; - vec.x = _parse_real_expression(value_editor[0]->get_text()); - vec.y = _parse_real_expression(value_editor[1]->get_text()); - vec.z = _parse_real_expression(value_editor[2]->get_text()); - v = vec; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::PLANE: { - Plane pl; - pl.normal.x = _parse_real_expression(value_editor[0]->get_text()); - pl.normal.y = _parse_real_expression(value_editor[1]->get_text()); - pl.normal.z = _parse_real_expression(value_editor[2]->get_text()); - pl.d = _parse_real_expression(value_editor[3]->get_text()); - v = pl; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::QUATERNION: { - Quaternion q; - q.x = _parse_real_expression(value_editor[0]->get_text()); - q.y = _parse_real_expression(value_editor[1]->get_text()); - q.z = _parse_real_expression(value_editor[2]->get_text()); - q.w = _parse_real_expression(value_editor[3]->get_text()); - v = q; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::AABB: { - Vector3 pos; - Vector3 size; - - pos.x = _parse_real_expression(value_editor[0]->get_text()); - pos.y = _parse_real_expression(value_editor[1]->get_text()); - pos.z = _parse_real_expression(value_editor[2]->get_text()); - size.x = _parse_real_expression(value_editor[3]->get_text()); - size.y = _parse_real_expression(value_editor[4]->get_text()); - size.z = _parse_real_expression(value_editor[5]->get_text()); - v = AABB(pos, size); - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::TRANSFORM2D: { - Transform2D m; - for (int i = 0; i < 6; i++) { - m.columns[i / 2][i % 2] = _parse_real_expression(value_editor[i]->get_text()); - } - - v = m; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::BASIS: { - Basis m; - for (int i = 0; i < 9; i++) { - m.rows[i / 3][i % 3] = _parse_real_expression(value_editor[i]->get_text()); - } - - v = m; - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::TRANSFORM3D: { - Basis basis; - for (int i = 0; i < 9; i++) { - basis.rows[i / 3][i % 3] = _parse_real_expression(value_editor[(i / 3) * 4 + i % 3]->get_text()); - } - - Vector3 origin; - - origin.x = _parse_real_expression(value_editor[3]->get_text()); - origin.y = _parse_real_expression(value_editor[7]->get_text()); - origin.z = _parse_real_expression(value_editor[11]->get_text()); - - v = Transform3D(basis, origin); - if (v != prev_v) { - _emit_changed_whole_or_field(); - } - - } break; - case Variant::COLOR: { - } break; - - case Variant::NODE_PATH: { - v = NodePath(value_editor[0]->get_text()); - if (v != prev_v) { - emit_signal(SNAME("variant_changed")); - } - } break; - case Variant::DICTIONARY: { - } break; - case Variant::PACKED_BYTE_ARRAY: { - } break; - case Variant::PACKED_INT32_ARRAY: { - } break; - case Variant::PACKED_FLOAT32_ARRAY: { - } break; - case Variant::PACKED_STRING_ARRAY: { - } break; - case Variant::PACKED_VECTOR3_ARRAY: { - } break; - case Variant::PACKED_COLOR_ARRAY: { - } break; - default: { - } - } - - updating = false; -} - -real_t CustomPropertyEditor::_parse_real_expression(String text) { - Ref<Expression> expr; - expr.instantiate(); - Error err = expr->parse(text); - real_t out; - if (err != OK) { - out = value_editor[0]->get_text().to_float(); - } else { - out = expr->execute(Array(), nullptr, false, true); - } - return out; -} - -void CustomPropertyEditor::_emit_changed_whole_or_field() { - if (!Input::get_singleton()->is_key_pressed(Key::SHIFT)) { - emit_signal(SNAME("variant_changed")); - } else { - emit_signal(SNAME("variant_field_changed"), field_names[focused_value_editor]); - } -} - -void CustomPropertyEditor::_range_modified(double p_value) { - v = p_value; - emit_signal(SNAME("variant_changed")); -} - -void CustomPropertyEditor::_focus_enter() { - switch (type) { - case Variant::FLOAT: - case Variant::STRING: - case Variant::VECTOR2: - case Variant::RECT2: - case Variant::VECTOR3: - case Variant::PLANE: - case Variant::QUATERNION: - case Variant::AABB: - case Variant::TRANSFORM2D: - case Variant::BASIS: - case Variant::TRANSFORM3D: { - for (int i = 0; i < MAX_VALUE_EDITORS; ++i) { - if (value_editor[i]->has_focus()) { - focused_value_editor = i; - value_editor[i]->select_all(); - break; - } - } - } break; - default: { - } - } -} - -void CustomPropertyEditor::_focus_exit() { - _modified(String()); -} - -void CustomPropertyEditor::config_action_buttons(const List<String> &p_strings) { - Ref<StyleBox> sb = action_buttons[0]->get_theme_stylebox(SNAME("button")); - int margin_top = sb->get_margin(SIDE_TOP); - int margin_left = sb->get_margin(SIDE_LEFT); - int margin_bottom = sb->get_margin(SIDE_BOTTOM); - int margin_right = sb->get_margin(SIDE_RIGHT); - - int max_width = 0; - int height = 0; - - for (int i = 0; i < MAX_ACTION_BUTTONS; i++) { - if (i < p_strings.size()) { - action_buttons[i]->show(); - action_buttons[i]->set_text(p_strings[i]); - - Size2 btn_m_size = action_buttons[i]->get_minimum_size(); - if (btn_m_size.width > max_width) { - max_width = btn_m_size.width; - } - - } else { - action_buttons[i]->hide(); - } - } - - for (int i = 0; i < p_strings.size(); i++) { - Size2 btn_m_size = action_buttons[i]->get_size(); - action_buttons[i]->set_position(Point2(0, height) + Point2(margin_left, margin_top)); - action_buttons[i]->set_size(Size2(max_width, btn_m_size.height)); - - height += btn_m_size.height; - } - set_size(Size2(max_width, height) + Size2(margin_left + margin_right, margin_top + margin_bottom)); -} - -void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns, int p_label_w, const List<String> &p_strings) { - int cell_width = 95; - int cell_height = 25; - int cell_margin = 5; - int rows = ((p_amount - 1) / p_columns) + 1; - - set_size(Size2(cell_margin + p_label_w + (cell_width + cell_margin + p_label_w) * p_columns, cell_margin + (cell_height + cell_margin) * rows) * EDSCALE); - - for (int i = 0; i < MAX_VALUE_EDITORS; i++) { - value_label[i]->get_parent()->remove_child(value_label[i]); - value_editor[i]->get_parent()->remove_child(value_editor[i]); - - int box_id = i / p_columns; - value_hboxes[box_id]->add_child(value_label[i]); - value_hboxes[box_id]->add_child(value_editor[i]); - - if (i < MAX_VALUE_EDITORS / 4) { - if (i <= p_amount / 4) { - value_hboxes[i]->show(); - } else { - value_hboxes[i]->hide(); - } - } - - if (i < p_amount) { - value_editor[i]->show(); - value_label[i]->show(); - value_label[i]->set_text(i < p_strings.size() ? p_strings[i] : String("")); - value_editor[i]->set_editable(!read_only); - } else { - value_editor[i]->hide(); - value_label[i]->hide(); - } - } -} - -void CustomPropertyEditor::_bind_methods() { - ADD_SIGNAL(MethodInfo("variant_changed")); - ADD_SIGNAL(MethodInfo("variant_field_changed", PropertyInfo(Variant::STRING, "field"))); - ADD_SIGNAL(MethodInfo("resource_edit_request")); -} - -CustomPropertyEditor::CustomPropertyEditor() { - value_vbox = memnew(VBoxContainer); - add_child(value_vbox); - - for (int i = 0; i < MAX_VALUE_EDITORS; i++) { - if (i < MAX_VALUE_EDITORS / 4) { - value_hboxes[i] = memnew(HBoxContainer); - value_vbox->add_child(value_hboxes[i]); - value_hboxes[i]->hide(); - } - int hbox_idx = i / 4; - value_label[i] = memnew(Label); - value_hboxes[hbox_idx]->add_child(value_label[i]); - value_label[i]->hide(); - value_editor[i] = memnew(LineEdit); - value_hboxes[hbox_idx]->add_child(value_editor[i]); - value_editor[i]->set_h_size_flags(Control::SIZE_EXPAND_FILL); - value_editor[i]->hide(); - value_editor[i]->connect("text_submitted", callable_mp(this, &CustomPropertyEditor::_modified)); - value_editor[i]->connect("focus_entered", callable_mp(this, &CustomPropertyEditor::_focus_enter)); - value_editor[i]->connect("focus_exited", callable_mp(this, &CustomPropertyEditor::_focus_exit)); - } - focused_value_editor = -1; - - for (int i = 0; i < 4; i++) { - scroll[i] = memnew(HScrollBar); - scroll[i]->hide(); - scroll[i]->set_min(0); - scroll[i]->set_max(1.0); - scroll[i]->set_step(0.01); - add_child(scroll[i]); - } - - checks20gc = memnew(GridContainer); - add_child(checks20gc); - checks20gc->set_columns(11); - - for (int i = 0; i < 20; i++) { - if (i == 5 || i == 15) { - Control *space = memnew(Control); - space->set_custom_minimum_size(Size2(20, 0) * EDSCALE); - checks20gc->add_child(space); - } - - checks20[i] = memnew(CheckBox); - checks20[i]->set_toggle_mode(true); - checks20[i]->set_focus_mode(Control::FOCUS_NONE); - checks20gc->add_child(checks20[i]); - checks20[i]->hide(); - checks20[i]->connect("pressed", callable_mp(this, &CustomPropertyEditor::_action_pressed), make_binds(i)); - checks20[i]->set_tooltip(vformat(TTR("Bit %d, val %d."), i, 1 << i)); - } - - text_edit = memnew(TextEdit); - value_vbox->add_child(text_edit); - text_edit->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 5); - text_edit->set_v_size_flags(Control::SIZE_EXPAND_FILL); - text_edit->set_offset(SIDE_BOTTOM, -30); - - text_edit->hide(); - text_edit->connect("text_changed", callable_mp(this, &CustomPropertyEditor::_text_edit_changed)); - - color_picker = nullptr; - - file = memnew(EditorFileDialog); - value_vbox->add_child(file); - file->hide(); - - file->connect("file_selected", callable_mp(this, &CustomPropertyEditor::_file_selected)); - file->connect("dir_selected", callable_mp(this, &CustomPropertyEditor::_file_selected)); - - locale = memnew(EditorLocaleDialog); - value_vbox->add_child(locale); - locale->hide(); - - locale->connect("locale_selected", callable_mp(this, &CustomPropertyEditor::_locale_selected)); - - error = memnew(ConfirmationDialog); - error->set_title(TTR("Error!")); - value_vbox->add_child(error); - - scene_tree = memnew(SceneTreeDialog); - value_vbox->add_child(scene_tree); - scene_tree->connect("selected", callable_mp(this, &CustomPropertyEditor::_node_path_selected)); - scene_tree->get_scene_tree()->set_show_enabled_subscene(true); - - texture_preview = memnew(TextureRect); - value_vbox->add_child(texture_preview); - texture_preview->hide(); - - easing_draw = memnew(Control); - value_vbox->add_child(easing_draw); - easing_draw->hide(); - easing_draw->connect("draw", callable_mp(this, &CustomPropertyEditor::_draw_easing)); - easing_draw->connect("gui_input", callable_mp(this, &CustomPropertyEditor::_drag_easing)); - easing_draw->set_default_cursor_shape(Control::CURSOR_MOVE); - - type_button = memnew(MenuButton); - value_vbox->add_child(type_button); - type_button->hide(); - type_button->get_popup()->connect("id_pressed", callable_mp(this, &CustomPropertyEditor::_type_create_selected)); - - menu = memnew(PopupMenu); - // menu->set_pass_on_modal_close_click(false); - value_vbox->add_child(menu); - menu->connect("id_pressed", callable_mp(this, &CustomPropertyEditor::_menu_option)); - - evaluator = nullptr; - - spinbox = memnew(SpinBox); - value_vbox->add_child(spinbox); - spinbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 5); - spinbox->connect("value_changed", callable_mp(this, &CustomPropertyEditor::_range_modified)); - - slider = memnew(HSlider); - value_vbox->add_child(slider); - slider->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 5); - slider->connect("value_changed", callable_mp(this, &CustomPropertyEditor::_range_modified)); - - action_hboxes = memnew(HBoxContainer); - action_hboxes->set_alignment(BoxContainer::ALIGNMENT_CENTER); - value_vbox->add_child(action_hboxes); - for (int i = 0; i < MAX_ACTION_BUTTONS; i++) { - action_buttons[i] = memnew(Button); - action_buttons[i]->hide(); - action_hboxes->add_child(action_buttons[i]); - Vector<Variant> binds; - binds.push_back(i); - action_buttons[i]->connect("pressed", callable_mp(this, &CustomPropertyEditor::_action_pressed), binds); - } - - create_dialog = nullptr; - property_select = nullptr; -} diff --git a/editor/property_editor.h b/editor/property_editor.h deleted file mode 100644 index 27d1cabc3d..0000000000 --- a/editor/property_editor.h +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************/ -/* property_editor.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef PROPERTY_EDITOR_H -#define PROPERTY_EDITOR_H - -#include "editor/editor_locale_dialog.h" -#include "editor/scene_tree_editor.h" -#include "scene/gui/button.h" -#include "scene/gui/check_box.h" -#include "scene/gui/check_button.h" -#include "scene/gui/color_picker.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/grid_container.h" -#include "scene/gui/label.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/split_container.h" -#include "scene/gui/text_edit.h" -#include "scene/gui/texture_rect.h" -#include "scene/gui/tree.h" - -class CreateDialog; -class EditorFileDialog; -class PropertyValueEvaluator; -class PropertySelector; - -class EditorResourceConversionPlugin : public RefCounted { - GDCLASS(EditorResourceConversionPlugin, RefCounted); - -protected: - static void _bind_methods(); - - GDVIRTUAL0RC(String, _converts_to) - GDVIRTUAL1RC(bool, _handles, Ref<Resource>) - GDVIRTUAL1RC(Ref<Resource>, _convert, Ref<Resource>) - -public: - virtual String converts_to() const; - virtual bool handles(const Ref<Resource> &p_resource) const; - virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const; -}; - -class CustomPropertyEditor : public PopupPanel { - GDCLASS(CustomPropertyEditor, PopupPanel); - - enum { - MAX_VALUE_EDITORS = 12, - MAX_ACTION_BUTTONS = 5, - OBJ_MENU_LOAD = 0, - OBJ_MENU_EDIT = 1, - OBJ_MENU_CLEAR = 2, - OBJ_MENU_MAKE_UNIQUE = 3, - OBJ_MENU_COPY = 4, - OBJ_MENU_PASTE = 5, - OBJ_MENU_NEW_SCRIPT = 6, - OBJ_MENU_EXTEND_SCRIPT = 7, - OBJ_MENU_SHOW_IN_FILE_SYSTEM = 8, - TYPE_BASE_ID = 100, - CONVERT_BASE_ID = 1000 - }; - - enum { - EASING_LINEAR, - EASING_EASE_IN, - EASING_EASE_OUT, - EASING_ZERO, - EASING_IN_OUT, - EASING_OUT_IN - }; - - PopupMenu *menu = nullptr; - SceneTreeDialog *scene_tree = nullptr; - EditorFileDialog *file = nullptr; - EditorLocaleDialog *locale = nullptr; - ConfirmationDialog *error = nullptr; - String name; - Variant::Type type; - Variant v; - List<String> field_names; - int hint = 0; - String hint_text; - HBoxContainer *value_hboxes[MAX_VALUE_EDITORS / 4]; - VBoxContainer *value_vbox = nullptr; - LineEdit *value_editor[MAX_VALUE_EDITORS]; - int focused_value_editor; - Label *value_label[MAX_VALUE_EDITORS]; - HScrollBar *scroll[4]; - HBoxContainer *action_hboxes = nullptr; - Button *action_buttons[MAX_ACTION_BUTTONS]; - MenuButton *type_button = nullptr; - Vector<String> inheritors_array; - TextureRect *texture_preview = nullptr; - ColorPicker *color_picker = nullptr; - TextEdit *text_edit = nullptr; - bool read_only = false; - bool picking_viewport = false; - GridContainer *checks20gc = nullptr; - CheckBox *checks20[20]; - SpinBox *spinbox = nullptr; - HSlider *slider = nullptr; - - Control *easing_draw = nullptr; - CreateDialog *create_dialog = nullptr; - PropertySelector *property_select = nullptr; - - Object *owner = nullptr; - - bool updating = false; - - PropertyValueEvaluator *evaluator = nullptr; - - void _text_edit_changed(); - void _file_selected(String p_file); - void _locale_selected(String p_locale); - void _modified(String p_string); - - real_t _parse_real_expression(String text); - - void _range_modified(double p_value); - void _focus_enter(); - void _focus_exit(); - void _action_pressed(int p_which); - void _type_create_selected(int p_idx); - void _create_dialog_callback(); - void _create_selected_property(const String &p_prop); - - void _color_changed(const Color &p_color); - void _draw_easing(); - void _menu_option(int p_which); - - void _drag_easing(const Ref<InputEvent> &p_ev); - - void _node_path_selected(NodePath p_path); - void show_value_editors(int p_amount); - void config_value_editors(int p_amount, int p_columns, int p_label_w, const List<String> &p_strings); - void config_action_buttons(const List<String> &p_strings); - - void _emit_changed_whole_or_field(); - -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - void hide_menu(); - - Variant get_variant() const; - String get_name() const; - - void set_read_only(bool p_read_only) { read_only = p_read_only; } - - bool edit(Object *p_owner, const String &p_name, Variant::Type p_type, const Variant &p_variant, int p_hint, String p_hint_text); - - CustomPropertyEditor(); -}; - -#endif // PROPERTY_EDITOR_H diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index 841c3ff3b1..1b17a740dd 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -32,8 +32,12 @@ #include "core/os/keyboard.h" #include "editor/doc_tools.h" +#include "editor/editor_help.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/rich_text_label.h" +#include "scene/gui/tree.h" void PropertySelector::_text_changed(const String &p_newtext) { _update_search(); diff --git a/editor/property_selector.h b/editor/property_selector.h index e2bf5c02b7..9f1af576dd 100644 --- a/editor/property_selector.h +++ b/editor/property_selector.h @@ -31,9 +31,11 @@ #ifndef PROPERTY_SELECTOR_H #define PROPERTY_SELECTOR_H -#include "editor/editor_help.h" -#include "editor/property_editor.h" -#include "scene/gui/rich_text_label.h" +#include "scene/gui/dialogs.h" + +class EditorHelpBit; +class LineEdit; +class Tree; class PropertySelector : public ConfirmationDialog { GDCLASS(PropertySelector, ConfirmationDialog); diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index 255187e4ed..665aca6a37 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -42,6 +42,7 @@ #include "plugins/script_editor_plugin.h" #include "scene/gui/control.h" #include "scene/gui/label.h" +#include "scene/gui/separator.h" #include "scene/gui/tab_container.h" RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_undo_redo) { @@ -139,7 +140,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und but_insert_name->set_text("NAME"); but_insert_name->set_tooltip(String("${NAME}\n") + TTR("Node name.")); but_insert_name->set_focus_mode(Control::FOCUS_NONE); - but_insert_name->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${NAME}")); + but_insert_name->connect("pressed", callable_mp(this, &RenameDialog::_insert_text).bind("${NAME}")); but_insert_name->set_h_size_flags(Control::SIZE_EXPAND_FILL); grd_substitute->add_child(but_insert_name); @@ -149,7 +150,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und but_insert_parent->set_text("PARENT"); but_insert_parent->set_tooltip(String("${PARENT}\n") + TTR("Node's parent name, if available.")); but_insert_parent->set_focus_mode(Control::FOCUS_NONE); - but_insert_parent->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${PARENT}")); + but_insert_parent->connect("pressed", callable_mp(this, &RenameDialog::_insert_text).bind("${PARENT}")); but_insert_parent->set_h_size_flags(Control::SIZE_EXPAND_FILL); grd_substitute->add_child(but_insert_parent); @@ -159,7 +160,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und but_insert_type->set_text("TYPE"); but_insert_type->set_tooltip(String("${TYPE}\n") + TTR("Node type.")); but_insert_type->set_focus_mode(Control::FOCUS_NONE); - but_insert_type->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${TYPE}")); + but_insert_type->connect("pressed", callable_mp(this, &RenameDialog::_insert_text).bind("${TYPE}")); but_insert_type->set_h_size_flags(Control::SIZE_EXPAND_FILL); grd_substitute->add_child(but_insert_type); @@ -169,7 +170,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und but_insert_scene->set_text("SCENE"); but_insert_scene->set_tooltip(String("${SCENE}\n") + TTR("Current scene name.")); but_insert_scene->set_focus_mode(Control::FOCUS_NONE); - but_insert_scene->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${SCENE}")); + but_insert_scene->connect("pressed", callable_mp(this, &RenameDialog::_insert_text).bind("${SCENE}")); but_insert_scene->set_h_size_flags(Control::SIZE_EXPAND_FILL); grd_substitute->add_child(but_insert_scene); @@ -179,7 +180,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und but_insert_root->set_text("ROOT"); but_insert_root->set_tooltip(String("${ROOT}\n") + TTR("Root node name.")); but_insert_root->set_focus_mode(Control::FOCUS_NONE); - but_insert_root->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${ROOT}")); + but_insert_root->connect("pressed", callable_mp(this, &RenameDialog::_insert_text).bind("${ROOT}")); but_insert_root->set_h_size_flags(Control::SIZE_EXPAND_FILL); grd_substitute->add_child(but_insert_root); @@ -189,7 +190,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und but_insert_count->set_text("COUNTER"); but_insert_count->set_tooltip(String("${COUNTER}\n") + TTR("Sequential integer counter.\nCompare counter options.")); but_insert_count->set_focus_mode(Control::FOCUS_NONE); - but_insert_count->connect("pressed", callable_mp(this, &RenameDialog::_insert_text), make_binds("${COUNTER}")); + but_insert_count->connect("pressed", callable_mp(this, &RenameDialog::_insert_text).bind("${COUNTER}")); but_insert_count->set_h_size_flags(Control::SIZE_EXPAND_FILL); grd_substitute->add_child(but_insert_count); @@ -321,9 +322,9 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und spn_count_padding->connect("value_changed", callable_mp(this, &RenameDialog::_update_preview_int)); opt_style->connect("item_selected", callable_mp(this, &RenameDialog::_update_preview_int)); opt_case->connect("item_selected", callable_mp(this, &RenameDialog::_update_preview_int)); - cbut_substitute->connect("pressed", callable_mp(this, &RenameDialog::_update_preview), varray("")); - cbut_regex->connect("pressed", callable_mp(this, &RenameDialog::_update_preview), varray("")); - cbut_process->connect("pressed", callable_mp(this, &RenameDialog::_update_preview), varray("")); + cbut_substitute->connect("pressed", callable_mp(this, &RenameDialog::_update_preview).bind("")); + cbut_regex->connect("pressed", callable_mp(this, &RenameDialog::_update_preview).bind("")); + cbut_process->connect("pressed", callable_mp(this, &RenameDialog::_update_preview).bind("")); but_reset->connect("pressed", callable_mp(this, &RenameDialog::reset)); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index ca1771bedf..d19a40599f 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -39,6 +39,7 @@ #include "editor/editor_feature_profile.h" #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/multi_node_edit.h" @@ -1257,19 +1258,19 @@ void SceneTreeDock::_notification(int p_what) { beginner_node_shortcuts->add_child(button_2d); button_2d->set_text(TTR("2D Scene")); button_2d->set_icon(get_theme_icon(SNAME("Node2D"), SNAME("EditorIcons"))); - button_2d->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_CREATE_2D_SCENE, false)); + button_2d->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_CREATE_2D_SCENE, false)); button_3d = memnew(Button); beginner_node_shortcuts->add_child(button_3d); button_3d->set_text(TTR("3D Scene")); button_3d->set_icon(get_theme_icon(SNAME("Node3D"), SNAME("EditorIcons"))); - button_3d->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_CREATE_3D_SCENE, false)); + button_3d->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_CREATE_3D_SCENE, false)); button_ui = memnew(Button); beginner_node_shortcuts->add_child(button_ui); button_ui->set_text(TTR("User Interface")); button_ui->set_icon(get_theme_icon(SNAME("Control"), SNAME("EditorIcons"))); - button_ui->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_CREATE_USER_INTERFACE, false)); + button_ui->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_CREATE_USER_INTERFACE, false)); VBoxContainer *favorite_node_shortcuts = memnew(VBoxContainer); favorite_node_shortcuts->set_name("FavoriteNodeShortcuts"); @@ -1279,19 +1280,19 @@ void SceneTreeDock::_notification(int p_what) { node_shortcuts->add_child(button_custom); button_custom->set_text(TTR("Other Node")); button_custom->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); - button_custom->connect("pressed", callable_bind(callable_mp(this, &SceneTreeDock::_tool_selected), TOOL_NEW, false)); + button_custom->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_NEW, false)); button_clipboard = memnew(Button); node_shortcuts->add_child(button_clipboard); button_clipboard->set_text(TTR("Paste From Clipboard")); button_clipboard->set_icon(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons"))); - button_clipboard->connect("pressed", callable_bind(callable_mp(this, &SceneTreeDock::_tool_selected), TOOL_PASTE, false)); + button_clipboard->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_PASTE, false)); _update_create_root_dialog(); } break; case NOTIFICATION_ENTER_TREE: { - clear_inherit_confirm->connect("confirmed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM, false)); + clear_inherit_confirm->connect("confirmed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM, false)); scene_tree->set_auto_expand_selected(EditorSettings::get_singleton()->get("docks/scene_tree/auto_expand_to_selected"), false); } break; @@ -1952,17 +1953,36 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) { return; } - editor_data->get_undo_redo().create_action(TTR("Attach Script")); - for (Node *E : selected) { - Ref<Script> existing = E->get_script(); - editor_data->get_undo_redo().add_do_method(E, "set_script", p_script); - editor_data->get_undo_redo().add_undo_method(E, "set_script", existing); + if (selected.size() == 1) { + Node *node = selected.front()->get(); + Ref<Script> existing = node->get_script(); + + editor_data->get_undo_redo().create_action(TTR("Attach Script")); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "store_script_properties", node); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "store_script_properties", node); + editor_data->get_undo_redo().add_do_method(node, "set_script", p_script); + editor_data->get_undo_redo().add_undo_method(node, "set_script", existing); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "apply_script_properties", node); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", node); editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); + editor_data->get_undo_redo().commit_action(); + } else { + editor_data->get_undo_redo().create_action(TTR("Attach Script")); + for (List<Node *>::Element *E = selected.front(); E; E = E->next()) { + Ref<Script> existing = E->get()->get_script(); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "store_script_properties", E->get()); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "store_script_properties", E->get()); + editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script); + editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "apply_script_properties", E->get()); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", E->get()); + editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); + editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); + } + editor_data->get_undo_redo().commit_action(); } - editor_data->get_undo_redo().commit_action(); - _push_item(p_script.operator->()); _update_script_button(); } @@ -2347,7 +2367,7 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop if (!(c.flags & Object::CONNECT_PERSIST)) { continue; } - newnode->connect(c.signal.get_name(), c.callable, c.binds, Object::CONNECT_PERSIST); + newnode->connect(c.signal.get_name(), c.callable, Object::CONNECT_PERSIST); } } @@ -2437,7 +2457,7 @@ void SceneTreeDock::_new_scene_from(String p_file) { flg |= ResourceSaver::FLAG_COMPRESS; } - err = ResourceSaver::save(p_file, sdata, flg); + err = ResourceSaver::save(sdata, p_file, flg); if (err != OK) { accept->set_text(TTR("Error saving scene.")); accept->popup_centered(); @@ -2586,11 +2606,14 @@ void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) { Ref<Script> scr = ResourceLoader::load(p_file); ERR_FAIL_COND(!scr.is_valid()); - Node *n = get_node(p_to); - if (n) { + if (Node *n = get_node(p_to)) { editor_data->get_undo_redo().create_action(TTR("Attach Script")); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "store_script_properties", n); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "store_script_properties", n); editor_data->get_undo_redo().add_do_method(n, "set_script", scr); editor_data->get_undo_redo().add_undo_method(n, "set_script", n->get_script()); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "apply_script_properties", n); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", n); editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); editor_data->get_undo_redo().commit_action(); @@ -3177,7 +3200,7 @@ void SceneTreeDock::_update_create_root_dialog() { favorite_nodes->get_child(i)->queue_delete(); } - Ref<FileAccess> f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites.Node"), FileAccess::READ); + Ref<FileAccess> f = FileAccess::open(EditorPaths::get_singleton()->get_project_settings_dir().plus_file("favorites.Node"), FileAccess::READ); if (f.is_valid()) { while (!f->eof_reached()) { String l = f->get_line().strip_edges(); @@ -3192,7 +3215,7 @@ void SceneTreeDock::_update_create_root_dialog() { name = ScriptServer::get_global_class_native_base(name); } button->set_icon(EditorNode::get_singleton()->get_class_icon(name)); - button->connect("pressed", callable_mp(this, &SceneTreeDock::_favorite_root_selected), make_binds(l)); + button->connect("pressed", callable_mp(this, &SceneTreeDock::_favorite_root_selected).bind(l)); } } } @@ -3374,14 +3397,14 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec button_add = memnew(Button); button_add->set_flat(true); - button_add->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_NEW, false)); + button_add->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_NEW, false)); button_add->set_tooltip(TTR("Add/Create a New Node.")); button_add->set_shortcut(ED_GET_SHORTCUT("scene_tree/add_child_node")); filter_hbc->add_child(button_add); button_instance = memnew(Button); button_instance->set_flat(true); - button_instance->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_INSTANTIATE, false)); + button_instance->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_INSTANTIATE, false)); button_instance->set_tooltip(TTR("Instantiate a scene file as a Node. Creates an inherited scene if no root node exists.")); button_instance->set_shortcut(ED_GET_SHORTCUT("scene_tree/instance_scene")); filter_hbc->add_child(button_instance); @@ -3396,7 +3419,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec button_create_script = memnew(Button); button_create_script->set_flat(true); - button_create_script->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_ATTACH_SCRIPT, false)); + button_create_script->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_ATTACH_SCRIPT, false)); button_create_script->set_tooltip(TTR("Attach a new or existing script to the selected node.")); button_create_script->set_shortcut(ED_GET_SHORTCUT("scene_tree/attach_script")); filter_hbc->add_child(button_create_script); @@ -3404,7 +3427,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec button_detach_script = memnew(Button); button_detach_script->set_flat(true); - button_detach_script->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_DETACH_SCRIPT, false)); + button_detach_script->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_DETACH_SCRIPT, false)); button_detach_script->set_tooltip(TTR("Detach the script from the selected node.")); button_detach_script->set_shortcut(ED_GET_SHORTCUT("scene_tree/detach_script")); filter_hbc->add_child(button_detach_script); @@ -3417,7 +3440,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec PopupMenu *tree_menu = button_tree_menu->get_popup(); tree_menu->add_check_item(TTR("Auto Expand to Selected"), TOOL_AUTO_EXPAND); - tree_menu->connect("id_pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(false)); + tree_menu->connect("id_pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(false)); button_hb = memnew(HBoxContainer); vbc->add_child(button_hb); @@ -3454,8 +3477,8 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec scene_tree->set_v_size_flags(SIZE_EXPAND | SIZE_FILL); scene_tree->connect("rmb_pressed", callable_mp(this, &SceneTreeDock::_tree_rmb)); - scene_tree->connect("node_selected", callable_mp(this, &SceneTreeDock::_node_selected), varray(), CONNECT_DEFERRED); - scene_tree->connect("node_renamed", callable_mp(this, &SceneTreeDock::_node_renamed), varray(), CONNECT_DEFERRED); + scene_tree->connect("node_selected", callable_mp(this, &SceneTreeDock::_node_selected), CONNECT_DEFERRED); + scene_tree->connect("node_renamed", callable_mp(this, &SceneTreeDock::_node_renamed), CONNECT_DEFERRED); scene_tree->connect("node_prerename", callable_mp(this, &SceneTreeDock::_node_prerenamed)); scene_tree->connect("open", callable_mp(this, &SceneTreeDock::_load_request)); scene_tree->connect("open_script", callable_mp(this, &SceneTreeDock::_script_open_request)); @@ -3505,7 +3528,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec delete_dialog = memnew(ConfirmationDialog); add_child(delete_dialog); - delete_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_delete_confirm), varray(false)); + delete_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_delete_confirm).bind(false)); editable_instance_remove_dialog = memnew(ConfirmationDialog); add_child(editable_instance_remove_dialog); @@ -3522,11 +3545,11 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec menu = memnew(PopupMenu); add_child(menu); - menu->connect("id_pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(false)); + menu->connect("id_pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(false)); menu_subresources = memnew(PopupMenu); menu_subresources->set_name("Sub-Resources"); - menu_subresources->connect("id_pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(false)); + menu_subresources->connect("id_pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(false)); menu->add_child(menu_subresources); menu_properties = memnew(PopupMenu); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 12f037e4da..ad83db9b60 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -268,7 +268,17 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { String warning = p_node->get_configuration_warnings_as_string(); if (!warning.is_empty()) { - item->add_button(0, get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + warning); + const int num_warnings = p_node->get_configuration_warnings().size(); + String warning_icon; + if (num_warnings == 1) { + warning_icon = SNAME("NodeWarning"); + } else if (num_warnings <= 3) { + warning_icon = vformat("NodeWarnings%d", num_warnings); + } else { + warning_icon = SNAME("NodeWarnings4Plus"); + } + + item->add_button(0, get_theme_icon(warning_icon, SNAME("EditorIcons")), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + warning); } if (p_node->is_unique_name_in_owner()) { @@ -358,7 +368,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { if (can_open_instance && undo_redo) { //Show buttons only when necessary(SceneTreeDock) to avoid crashes if (!p_node->is_connected("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed))) { - p_node->connect("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed), varray(p_node)); + p_node->connect("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed).bind(p_node)); } Ref<Script> script = p_node->get_script(); @@ -375,7 +385,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } if (p_node->has_meta("_edit_group_")) { - item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make selectable.")); + item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make them selectable.")); } bool v = p_node->call("is_visible"); @@ -386,7 +396,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) { - p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed), varray(p_node)); + p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed).bind(p_node)); } _update_visibility_color(p_node, item); @@ -399,7 +409,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) { - p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed), varray(p_node)); + p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed).bind(p_node)); } } else if (p_node->is_class("Node3D")) { if (p_node->has_meta("_edit_lock_")) { @@ -407,7 +417,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } if (p_node->has_meta("_edit_group_")) { - item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make selectable.")); + item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make them selectable.")); } bool v = p_node->call("is_visible"); @@ -418,7 +428,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) { - p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed), varray(p_node)); + p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed).bind(p_node)); } _update_visibility_color(p_node, item); @@ -730,7 +740,7 @@ void SceneTreeEditor::_notification(int p_what) { get_tree()->connect("tree_process_mode_changed", callable_mp(this, &SceneTreeEditor::_tree_process_mode_changed)); get_tree()->connect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed)); get_tree()->connect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed)); - get_tree()->connect("node_configuration_warning_changed", callable_mp(this, &SceneTreeEditor::_warning_changed), varray(), CONNECT_DEFERRED); + get_tree()->connect("node_configuration_warning_changed", callable_mp(this, &SceneTreeEditor::_warning_changed), CONNECT_DEFERRED); tree->connect("item_collapsed", callable_mp(this, &SceneTreeEditor::_cell_collapsed)); @@ -1298,7 +1308,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope blocked = 0; update_timer = memnew(Timer); - update_timer->connect("timeout", callable_mp(this, &SceneTreeEditor::_update_tree), varray(false)); + update_timer->connect("timeout", callable_mp(this, &SceneTreeEditor::_update_tree).bind(false)); update_timer->set_one_shot(true); update_timer->set_wait_time(0.5); add_child(update_timer); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index f2eabdd208..77e0321f83 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -38,6 +38,7 @@ #include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" @@ -384,7 +385,7 @@ void ScriptCreateDialog::_create_new() { } else { String lpath = ProjectSettings::get_singleton()->localize_path(file_path->get_text()); scr->set_path(lpath); - Error err = ResourceSaver::save(lpath, scr, ResourceSaver::FLAG_CHANGE_PATH); + Error err = ResourceSaver::save(scr, lpath, ResourceSaver::FLAG_CHANGE_PATH); if (err != OK) { alert->set_text(TTR("Error - Could not create script in filesystem.")); alert->popup_centered(); @@ -620,9 +621,9 @@ void ScriptCreateDialog::_update_template_menu() { } else { String template_directory; if (template_location == ScriptLanguage::TEMPLATE_PROJECT) { - template_directory = EditorSettings::get_singleton()->get_project_script_templates_dir(); + template_directory = EditorPaths::get_singleton()->get_project_script_templates_dir(); } else { - template_directory = EditorSettings::get_singleton()->get_script_templates_dir(); + template_directory = EditorPaths::get_singleton()->get_script_templates_dir(); } templates_found = _get_user_templates(language, current_node, template_directory, template_location); } @@ -1008,7 +1009,7 @@ ScriptCreateDialog::ScriptCreateDialog() { parent_search_button->connect("pressed", callable_mp(this, &ScriptCreateDialog::_browse_class_in_tree)); hb->add_child(parent_search_button); parent_browse_button = memnew(Button); - parent_browse_button->connect("pressed", callable_mp(this, &ScriptCreateDialog::_browse_path), varray(true, false)); + parent_browse_button->connect("pressed", callable_mp(this, &ScriptCreateDialog::_browse_path).bind(true, false)); hb->add_child(parent_browse_button); gc->add_child(memnew(Label(TTR("Inherits:")))); gc->add_child(hb); @@ -1057,7 +1058,7 @@ ScriptCreateDialog::ScriptCreateDialog() { file_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); hb->add_child(file_path); path_button = memnew(Button); - path_button->connect("pressed", callable_mp(this, &ScriptCreateDialog::_browse_path), varray(false, true)); + path_button->connect("pressed", callable_mp(this, &ScriptCreateDialog::_browse_path).bind(false, true)); hb->add_child(path_button); Label *label = memnew(Label(TTR("Path:"))); gc->add_child(label); diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index 7ae03ee96f..bd1f2529ca 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -211,7 +211,7 @@ void ShaderCreateDialog::_create_new() { String lpath = ProjectSettings::get_singleton()->localize_path(file_path->get_text()); shader_inc->set_path(lpath); - Error error = ResourceSaver::save(lpath, shader_inc, ResourceSaver::FLAG_CHANGE_PATH); + Error error = ResourceSaver::save(shader_inc, lpath, ResourceSaver::FLAG_CHANGE_PATH); if (error != OK) { alert->set_text(TTR("Error - Could not create shader include in filesystem.")); alert->popup_centered(); @@ -224,7 +224,7 @@ void ShaderCreateDialog::_create_new() { String lpath = ProjectSettings::get_singleton()->localize_path(file_path->get_text()); shader->set_path(lpath); - Error error = ResourceSaver::save(lpath, shader, ResourceSaver::FLAG_CHANGE_PATH); + Error error = ResourceSaver::save(shader, lpath, ResourceSaver::FLAG_CHANGE_PATH); if (error != OK) { alert->set_text(TTR("Error - Could not create shader in filesystem.")); alert->popup_centered(); diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index 26bd3a5979..1cd1b4ea00 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -79,7 +79,7 @@ protected: } bool _set(const StringName &p_name, const Variant &p_value) { - Variant existing = RS::get_singleton()->global_variable_get(p_name); + Variant existing = RS::get_singleton()->global_shader_uniform_get(p_name); if (existing.get_type() == Variant::NIL) { return false; @@ -88,9 +88,9 @@ protected: UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(TTR("Set Shader Global Variable")); - undo_redo->add_do_method(RS::get_singleton(), "global_variable_set", p_name, p_value); - undo_redo->add_undo_method(RS::get_singleton(), "global_variable_set", p_name, existing); - RS::GlobalVariableType type = RS::get_singleton()->global_variable_get_type(p_name); + undo_redo->add_do_method(RS::get_singleton(), "global_shader_uniform_set", p_name, p_value); + undo_redo->add_undo_method(RS::get_singleton(), "global_shader_uniform_set", p_name, existing); + RS::GlobalShaderUniformType type = RS::get_singleton()->global_shader_uniform_get_type(p_name); Dictionary gv; gv["type"] = global_var_type_names[type]; if (type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { @@ -117,17 +117,17 @@ protected: } bool _get(const StringName &p_name, Variant &r_ret) const { - r_ret = RS::get_singleton()->global_variable_get(p_name); + r_ret = RS::get_singleton()->global_shader_uniform_get(p_name); return r_ret.get_type() != Variant::NIL; } void _get_property_list(List<PropertyInfo> *p_list) const { Vector<StringName> variables; - variables = RS::get_singleton()->global_variable_get_list(); + variables = RS::get_singleton()->global_shader_uniform_get_list(); for (int i = 0; i < variables.size(); i++) { PropertyInfo pinfo; pinfo.name = variables[i]; - switch (RS::get_singleton()->global_variable_get_type(variables[i])) { + switch (RS::get_singleton()->global_shader_uniform_get_type(variables[i])) { case RS::GLOBAL_VAR_TYPE_BOOL: { pinfo.type = Variant::BOOL; } break; @@ -241,7 +241,7 @@ public: } }; -static Variant create_var(RS::GlobalVariableType p_type) { +static Variant create_var(RS::GlobalShaderUniformType p_type) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { return false; @@ -376,12 +376,12 @@ static Variant create_var(RS::GlobalVariableType p_type) { void ShaderGlobalsEditor::_variable_added() { String var = variable_name->get_text().strip_edges(); if (var.is_empty() || !var.is_valid_identifier()) { - EditorNode::get_singleton()->show_warning(TTR("Please specify a valid variable identifier name.")); + EditorNode::get_singleton()->show_warning(TTR("Please specify a valid shader uniform identifier name.")); return; } - if (RenderingServer::get_singleton()->global_variable_get(var).get_type() != Variant::NIL) { - EditorNode::get_singleton()->show_warning(vformat(TTR("Global variable '%s' already exists'"), var)); + if (RenderingServer::get_singleton()->global_shader_uniform_get(var).get_type() != Variant::NIL) { + EditorNode::get_singleton()->show_warning(vformat(TTR("Global shader uniform '%s' already exists'"), var)); return; } @@ -395,11 +395,11 @@ void ShaderGlobalsEditor::_variable_added() { UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); - Variant value = create_var(RS::GlobalVariableType(variable_type->get_selected())); + Variant value = create_var(RS::GlobalShaderUniformType(variable_type->get_selected())); - undo_redo->create_action(TTR("Add Shader Global Variable")); - undo_redo->add_do_method(RS::get_singleton(), "global_variable_add", var, RS::GlobalVariableType(variable_type->get_selected()), value); - undo_redo->add_undo_method(RS::get_singleton(), "global_variable_remove", var); + undo_redo->create_action(TTR("Add Shader Global Uniform")); + undo_redo->add_do_method(RS::get_singleton(), "global_shader_uniform_add", var, RS::GlobalShaderUniformType(variable_type->get_selected()), value); + undo_redo->add_undo_method(RS::get_singleton(), "global_shader_uniform_remove", var); Dictionary gv; gv["type"] = global_var_type_names[variable_type->get_selected()]; gv["value"] = value; @@ -414,9 +414,9 @@ void ShaderGlobalsEditor::_variable_added() { void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) { UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); - undo_redo->create_action(TTR("Add Shader Global Variable")); - undo_redo->add_do_method(RS::get_singleton(), "global_variable_remove", p_variable); - undo_redo->add_undo_method(RS::get_singleton(), "global_variable_add", p_variable, RS::get_singleton()->global_variable_get_type(p_variable), RS::get_singleton()->global_variable_get(p_variable)); + undo_redo->create_action(TTR("Add Shader Global Uniform")); + undo_redo->add_do_method(RS::get_singleton(), "global_shader_uniform_remove", p_variable); + undo_redo->add_undo_method(RS::get_singleton(), "global_shader_uniform_add", p_variable, RS::get_singleton()->global_shader_uniform_get_type(p_variable), RS::get_singleton()->global_shader_uniform_get(p_variable)); undo_redo->add_do_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, Variant()); undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, ProjectSettings::get_singleton()->get("shader_globals/" + p_variable)); @@ -479,7 +479,7 @@ ShaderGlobalsEditor::ShaderGlobalsEditor() { inspector->set_use_wide_editors(true); inspector->set_property_name_style(EditorPropertyNameProcessor::STYLE_RAW); inspector->set_use_deletable_properties(true); - inspector->connect("property_deleted", callable_mp(this, &ShaderGlobalsEditor::_variable_deleted), varray(), CONNECT_DEFERRED); + inspector->connect("property_deleted", callable_mp(this, &ShaderGlobalsEditor::_variable_deleted), CONNECT_DEFERRED); interface = memnew(ShaderGlobalsEditorInterface); interface->connect("var_changed", Callable(this, "_changed")); diff --git a/editor/translations/af.po b/editor/translations/af.po index 78dd7f2140..f2e389b6f5 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -2191,14 +2191,15 @@ msgstr "Gunstelinge:" msgid "Recent:" msgstr "Onlangse:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Soek:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Passendes:" @@ -2260,8 +2261,8 @@ msgstr "Soek Vervanging Hulpbron:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2855,8 +2856,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Verwyder Seleksie" #: editor/editor_export.cpp #, fuzzy @@ -5570,6 +5572,10 @@ msgid "Drag And Drop Selection" msgstr "Alle Seleksie" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11868,6 +11874,11 @@ msgid "New Animation" msgstr "Optimaliseer Animasie" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Eienskappe" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20413,15 +20424,15 @@ msgstr "Kon nie vouer skep nie." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Moet 'n geldige uitbreiding gebruik." #: platform/windows/export/export.cpp #, fuzzy @@ -20445,15 +20456,15 @@ msgstr "Ongeldige naam." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Moet 'n geldige uitbreiding gebruik." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/ar.po b/editor/translations/ar.po index 87266564f8..cda76c44c8 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -66,13 +66,15 @@ # Abderrahim <abdoudido117@gmail.com>, 2022. # Jhon Smith <jhonsmaith3@gmail.com>, 2022. # Oo mohab oO <mohab9225@gmail.com>, 2022. +# عبد الرحمن أبو سعدة ||Abd Alrahman abo saada <abdalrahmanabs2005@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-09 21:11+0000\n" -"Last-Translator: Oo mohab oO <mohab9225@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: عبد الرحمن أبو سعدة ||Abd Alrahman abo saada " +"<abdalrahmanabs2005@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot/ar/>\n" "Language: ar\n" @@ -81,7 +83,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -452,7 +454,7 @@ msgstr "مفتاح Command" #: core/os/input_event.cpp #, fuzzy msgid "Physical" -msgstr " (فيزيائي)" +msgstr "(فيزيائي)" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp @@ -486,7 +488,7 @@ msgstr "الموقع العالمي" #: core/os/input_event.cpp msgid "Factor" -msgstr "المعامل" +msgstr "العامل" #: core/os/input_event.cpp msgid "Button Index" @@ -553,7 +555,7 @@ msgstr "قناة" #: core/os/input_event.cpp main/main.cpp msgid "Message" -msgstr "الرسالة" +msgstr "رسالة" #: core/os/input_event.cpp msgid "Pitch" @@ -585,7 +587,7 @@ msgstr "التطبيق" #: core/project_settings.cpp main/main.cpp msgid "Config" -msgstr "تعديل" +msgstr "إعداد" #: core/project_settings.cpp msgid "Project Settings Override" @@ -602,7 +604,7 @@ msgstr "تجاوز إعدادات المشروع" #: scene/3d/skeleton.cpp scene/main/node.cpp scene/resources/mesh_library.cpp #: scene/resources/skin.cpp msgid "Name" -msgstr "الأسم" +msgstr "الاسم" #: core/project_settings.cpp editor/editor_help.cpp #: modules/visual_script/visual_script_nodes.cpp platform/uwp/export/export.cpp @@ -862,9 +864,8 @@ msgid "Compression" msgstr "ضغط" #: core/project_settings.cpp -#, fuzzy msgid "Formats" -msgstr "البنية (اللاحقة)" +msgstr "التنسيقات" #: core/project_settings.cpp #, fuzzy @@ -944,7 +945,7 @@ msgstr "المسار" #: core/script_language.cpp msgid "Source Code" -msgstr "مصدر الرمز" +msgstr "الكود المصدري || الشفرة المصدرية" #: core/translation.cpp editor/project_settings_editor.cpp msgid "Locale" @@ -956,7 +957,7 @@ msgstr "إختبار" #: core/translation.cpp scene/resources/font.cpp msgid "Fallback" -msgstr "تقهقر" +msgstr "تراجع | انسحاب" #: core/ustring.cpp scene/resources/segment_shape_2d.cpp msgid "B" @@ -1014,7 +1015,7 @@ msgstr "حجم فهرس المخزن المؤقت للوحة المضلعات (K #: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp #: servers/visual_server.cpp msgid "2D" -msgstr "2D" +msgstr "ثنائي الأبعاد" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp @@ -2177,14 +2178,15 @@ msgstr "المفضلة:" msgid "Recent:" msgstr "الحالي:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "بحث:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "يطابق:" @@ -2244,8 +2246,8 @@ msgstr "البحث عن مورد بديل:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2818,7 +2820,7 @@ msgstr "تصدير المشروع لمنصة:" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "نسخ مسار العُقدة" #: editor/editor_export.cpp @@ -4868,7 +4870,7 @@ msgstr "نظام الملفات" #: editor/editor_node.cpp msgid "Expand Bottom Panel" -msgstr "توسيع التبويب السفلي" +msgstr "توسيع القائمة السفلية" #: editor/editor_node.cpp msgid "Don't Save" @@ -5608,6 +5610,10 @@ msgid "Drag And Drop Selection" msgstr "تحديد الملئ خريطة-الشبكة" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "المظهر" @@ -11847,6 +11853,11 @@ msgid "New Animation" msgstr "رسومية متحركة جديدة" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ترشيح الدوال" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "السرعة:" @@ -16283,26 +16294,24 @@ msgid "Set Room Point Position" msgstr "حدد موقع نقطة الإنحناء" #: editor/spatial_editor_gizmos.cpp scene/3d/portal.cpp -#, fuzzy msgid "Portal Margin" -msgstr "تحديد الهامش" +msgstr "هامش البوابة" #: editor/spatial_editor_gizmos.cpp msgid "Portal Edge" -msgstr "" +msgstr "حافة الغرفة" #: editor/spatial_editor_gizmos.cpp msgid "Portal Arrow" -msgstr "" +msgstr "سهم البوابة" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Set Portal Point Position" -msgstr "حدد موقع نقطة الإنحناء" +msgstr "حدد موقع نقطة البوابة" #: editor/spatial_editor_gizmos.cpp msgid "Portal Front" -msgstr "" +msgstr "واجهة البوابة" #: editor/spatial_editor_gizmos.cpp #, fuzzy @@ -16341,18 +16350,16 @@ msgid "Occluder Polygon Front" msgstr "أنشئ شكل مُطبق" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Polygon Back" -msgstr "أنشئ شكل مُطبق" +msgstr "" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Hole" -msgstr "أنشئ شكل مُطبق" +msgstr "" #: main/main.cpp msgid "Godot Physics" -msgstr "" +msgstr "فيزيائيات جودو" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp @@ -16431,9 +16438,8 @@ msgid "Driver" msgstr "" #: main/main.cpp -#, fuzzy msgid "Driver Name" -msgstr "اسم النص البرمجي:" +msgstr "اسم النص البرمجي" #: main/main.cpp msgid "Fallback To GLES2" @@ -16452,22 +16458,20 @@ msgid "Allow hiDPI" msgstr "" #: main/main.cpp -#, fuzzy msgid "V-Sync" -msgstr "مزامنة" +msgstr "مزامنة (مزامنة كرت الشاشة)" #: main/main.cpp -#, fuzzy msgid "Use V-Sync" -msgstr "استخدام المحاذاة" +msgstr "استخدام مزامنة كرت الشاشة" #: main/main.cpp msgid "Per Pixel Transparency" -msgstr "" +msgstr "شفافية بيكسل القلم" #: main/main.cpp msgid "Allowed" -msgstr "" +msgstr "مسموح" #: main/main.cpp msgid "Intended Usage" @@ -16479,18 +16483,16 @@ msgid "Framebuffer Allocation" msgstr "تحديد الإطار" #: main/main.cpp platform/uwp/os_uwp.cpp -#, fuzzy msgid "Energy Saving" -msgstr "خطأ في الحفظ" +msgstr "توفير الطاقة" #: main/main.cpp msgid "Threads" -msgstr "" +msgstr "مسارات" #: main/main.cpp servers/physics_2d/physics_2d_server_wrap_mt.h -#, fuzzy msgid "Thread Model" -msgstr "أظهر المود" +msgstr "نوع المسار" #: main/main.cpp msgid "Thread Safe BVH" @@ -16508,9 +16510,8 @@ msgstr "الوثائق الإلكترونية" #: main/main.cpp scene/gui/scroll_container.cpp scene/gui/text_edit.cpp #: scene/main/scene_tree.cpp scene/register_scene_types.cpp -#, fuzzy msgid "Common" -msgstr "المجتمع" +msgstr "شائع" #: main/main.cpp #, fuzzy @@ -16530,7 +16531,7 @@ msgstr "" #: scene/gui/scroll_container.cpp scene/gui/text_edit.cpp scene/gui/tree.cpp #: scene/main/viewport.cpp scene/register_scene_types.cpp msgid "GUI" -msgstr "" +msgstr "واجهة المستخدم الرسومية" #: main/main.cpp msgid "Drop Mouse On GUI Input Disabled" @@ -16554,9 +16555,8 @@ msgid "Physics Interpolation" msgstr "وضعية الأستيفاء" #: main/main.cpp -#, fuzzy msgid "Enable Warnings" -msgstr "تمكين الترشيح Filtering" +msgstr "تفعيل التحذيرات" #: main/main.cpp #, fuzzy @@ -16573,25 +16573,23 @@ msgstr "" #: main/main.cpp msgid "iOS" -msgstr "" +msgstr "IOS" #: main/main.cpp msgid "Hide Home Indicator" msgstr "" #: main/main.cpp -#, fuzzy msgid "Input Devices" -msgstr "جميع الأجهزة" +msgstr "أجهزة الإدخال" #: main/main.cpp -#, fuzzy msgid "Pointing" -msgstr "نقطة" +msgstr "يشير" #: main/main.cpp msgid "Touch Delay" -msgstr "" +msgstr "تأخير اللمس" #: main/main.cpp servers/visual_server.cpp msgid "GLES3" @@ -16633,7 +16631,7 @@ msgstr "" #: main/main.cpp msgid "Fullsize" -msgstr "" +msgstr "الحجم الكامل" #: main/main.cpp scene/resources/dynamic_font.cpp #, fuzzy @@ -16706,21 +16704,20 @@ msgstr "انتهت المهلة." #: main/main.cpp msgid "Runtime" -msgstr "" +msgstr "اثناء التشغيل" #: main/main.cpp msgid "Unhandled Exception Policy" msgstr "" #: main/main.cpp -#, fuzzy msgid "Main Loop Type" -msgstr "إيجاد نوع العُقدة" +msgstr "نوع الحلقة الرئيسية" #: main/main.cpp scene/gui/texture_progress.cpp #: scene/gui/viewport_container.cpp msgid "Stretch" -msgstr "" +msgstr "تمدد" #: main/main.cpp #, fuzzy @@ -16775,38 +16772,33 @@ msgstr "تغيير نصف قطر الدائرة الداخلي" #: modules/csg/csg_gizmos.cpp msgid "Change Torus Outer Radius" -msgstr "تعديل نصف القطر الخارجي للطارة Torus Outer Radius" +msgstr "تعديل نصف القطر الخارجي للمسنن" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Operation" -msgstr "الإعدادات" +msgstr "عملية" #: modules/csg/csg_shape.cpp msgid "Calculate Tangents" -msgstr "" +msgstr "احسب الظلال" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Use Collision" -msgstr "التصادم" +msgstr "استخدم التصادم" #: modules/csg/csg_shape.cpp servers/physics_2d_server.cpp -#, fuzzy msgid "Collision Layer" -msgstr "وضع التصادم" +msgstr "" #: modules/csg/csg_shape.cpp scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp #: scene/3d/ray_cast.cpp scene/3d/spring_arm.cpp #: scene/resources/navigation_mesh.cpp servers/physics_server.cpp -#, fuzzy msgid "Collision Mask" -msgstr "وضع التصادم" +msgstr "" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Invert Faces" -msgstr "حالة التحويل" +msgstr "اقلب الوجوه" #: modules/csg/csg_shape.cpp scene/2d/navigation_agent_2d.cpp #: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_agent.cpp @@ -16826,37 +16818,32 @@ msgid "Radial Segments" msgstr "معاملات المشهد الرئيس:" #: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Rings" -msgstr "تحذيرات" +msgstr "خواتم" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Smooth Faces" -msgstr "خطوة ناعمة" +msgstr "وجوه ناعمة" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Sides" -msgstr "أظهر الموجهات" +msgstr "جهات" #: modules/csg/csg_shape.cpp msgid "Cone" msgstr "" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Inner Radius" -msgstr "تغيير نصف قطر الدائرة الداخلي" +msgstr "القطر الداخلي" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Outer Radius" -msgstr "تعديل نصف القطر الخارجي للطارة Torus Outer Radius" +msgstr "القطر الخارجي" #: modules/csg/csg_shape.cpp msgid "Ring Sides" -msgstr "" +msgstr "جهات الخاتم" #: modules/csg/csg_shape.cpp scene/2d/collision_polygon_2d.cpp #: scene/2d/light_occluder_2d.cpp scene/2d/polygon_2d.cpp @@ -16867,16 +16854,15 @@ msgstr "المُضلعات" #: modules/csg/csg_shape.cpp msgid "Spin Degrees" -msgstr "" +msgstr "درجة الدوران" #: modules/csg/csg_shape.cpp msgid "Spin Sides" -msgstr "" +msgstr "جهة الدوران" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Node" -msgstr "لصق العُقد" +msgstr "مسار العقدة" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16907,9 +16893,8 @@ msgid "Path Continuous U" msgstr "متواصل" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path U Distance" -msgstr "اختر المسافة:" +msgstr "المسار المحلي" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16917,28 +16902,26 @@ msgid "Path Joined" msgstr "دوران عشوائي:" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Compression Mode" -msgstr "وضع التصادم" +msgstr "وضع الضغط" #: modules/enet/networked_multiplayer_enet.cpp #, fuzzy msgid "Transfer Channel" -msgstr "تعديل التحولات" +msgstr "نقل القنوات" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Channel Count" -msgstr "كائن" +msgstr "عدد القنوات" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Always Ordered" -msgstr "إظهار الشبكة دوماً" +msgstr "مطلوب دائمًا" #: modules/enet/networked_multiplayer_enet.cpp +#, fuzzy msgid "Server Relay" -msgstr "" +msgstr "تناوب الخادم" #: modules/enet/networked_multiplayer_enet.cpp msgid "DTLS Verify" @@ -16962,30 +16945,25 @@ msgid "Use FBX" msgstr "" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Config File" -msgstr "تخزين الملف:" +msgstr "ملف التهيئة" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Load Once" -msgstr "تحميل المورد" +msgstr "حمل مرة واحدة" #: modules/gdnative/gdnative.cpp #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Singleton" -msgstr "الهيكل" +msgstr "" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Symbol Prefix" -msgstr "بادئة:" +msgstr "رمز البادئة" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Reloadable" -msgstr "إعادة تحميل" +msgstr "قابل لإعادة التحميل" #: modules/gdnative/gdnative.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp @@ -17003,7 +16981,7 @@ msgstr "اختر تبعيات المكتبة لأجل هذا الإدخال" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Remove current entry" -msgstr "مسح المدخلة الحالية" +msgstr "مسح المدخلات الحالية" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Double click to create a new entry" @@ -17052,9 +17030,8 @@ msgid "Script Class" msgstr "اسم النص البرمجي:" #: modules/gdnative/nativescript/nativescript.cpp -#, fuzzy msgid "Icon Path" -msgstr "مسار التركيز" +msgstr "مسار الأيقونة" #: modules/gdnative/register_types.cpp msgid "GDNative" @@ -17062,18 +17039,16 @@ msgstr "لغة البرمجة GDNative" #: modules/gdscript/editor/gdscript_highlighter.cpp #: modules/gdscript/gdscript.cpp -#, fuzzy msgid "GDScript" -msgstr "النص البرمجي" +msgstr "لغة جي دي" #: modules/gdscript/editor/gdscript_highlighter.cpp msgid "Function Definition Color" -msgstr "" +msgstr "لون تعريف الدالة" #: modules/gdscript/editor/gdscript_highlighter.cpp -#, fuzzy msgid "Node Path Color" -msgstr "نسخ مسار العُقدة" +msgstr "لون مسار العقدة" #: modules/gdscript/gdscript.cpp modules/visual_script/visual_script.cpp msgid "Max Call Stack" @@ -17101,11 +17076,11 @@ msgstr "ليس نص برمجي مع نموذج" #: modules/gdscript/gdscript_functions.cpp msgid "Not based on a script" -msgstr "لا تستند الى نص برمجي" +msgstr "غير مبني على نص برمجي" #: modules/gdscript/gdscript_functions.cpp msgid "Not based on a resource file" -msgstr "لا يعتمد على ملف موارد" +msgstr "غير مبني على ملف موارد" #: modules/gdscript/gdscript_functions.cpp msgid "Invalid instance dictionary format (missing @path)" @@ -17128,14 +17103,12 @@ msgid "Object can't provide a length." msgstr "لا يمكن للكائن أن يمنح طولاً." #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Language Server" -msgstr "اللغة:" +msgstr "لغة الخادك" #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Enable Smart Resolve" -msgstr "لا يمكن الحل" +msgstr "تفعيل الحل الذكي" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Show Native Symbols In Editor" @@ -17143,7 +17116,7 @@ msgstr "" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Use Thread" -msgstr "" +msgstr "استخدم المسار" #: modules/gltf/editor_scene_exporter_gltf_plugin.cpp #, fuzzy @@ -17166,14 +17139,12 @@ msgid "Byte Offset" msgstr "مقدار إزاحة الشبكة:" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Component Type" -msgstr "مكونات" +msgstr "نوع المكون" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Normalized" -msgstr "البنية (اللاحقة)" +msgstr "" #: modules/gltf/gltf_accessor.cpp #, fuzzy @@ -17181,14 +17152,12 @@ msgid "Count" msgstr "الكمية:" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Min" -msgstr "ميبي بايت (MiB)" +msgstr "أقل" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Max" -msgstr "خلط" +msgstr "أعلى" #: modules/gltf/gltf_accessor.cpp #, fuzzy @@ -17238,7 +17207,7 @@ msgstr "جميع الأجهزة" #: modules/gltf/gltf_camera.cpp #, fuzzy msgid "FOV Size" -msgstr "الحجم:" +msgstr "حجم مساحةالرؤية" #: modules/gltf/gltf_camera.cpp msgid "Zfar" @@ -17257,27 +17226,25 @@ msgstr "خطي" #: scene/resources/environment.cpp scene/resources/material.cpp #: scene/resources/particles_material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp -#, fuzzy msgid "Color" msgstr "الألوان" #: modules/gltf/gltf_light.cpp scene/3d/reflection_probe.cpp #: scene/resources/environment.cpp msgid "Intensity" -msgstr "" +msgstr "الكثافة | الشدة" #: modules/gltf/gltf_light.cpp scene/2d/light_2d.cpp scene/3d/light.cpp -#, fuzzy msgid "Range" -msgstr "تغير" +msgstr "نطاق" #: modules/gltf/gltf_light.cpp msgid "Inner Cone Angle" -msgstr "" +msgstr "زاوية المخروط الداخلية" #: modules/gltf/gltf_light.cpp msgid "Outer Cone Angle" -msgstr "" +msgstr "زاوية المخروط الخارجية" #: modules/gltf/gltf_mesh.cpp #, fuzzy @@ -17290,9 +17257,8 @@ msgid "Instance Materials" msgstr "تغيرات المادة:" #: modules/gltf/gltf_node.cpp scene/3d/skeleton.cpp -#, fuzzy msgid "Parent" -msgstr "إعادة اختيار الأبوة" +msgstr "أب" #: modules/gltf/gltf_node.cpp #, fuzzy @@ -17316,20 +17282,20 @@ msgstr "أبناء قابلين للتعديل" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp #, fuzzy msgid "Joints" -msgstr "نقطة" +msgstr "المفاصل" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp msgid "Roots" -msgstr "" +msgstr "الجذور" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_state.cpp msgid "Unique Names" -msgstr "" +msgstr "أسماء مميزة" #: modules/gltf/gltf_skeleton.cpp #, fuzzy msgid "Godot Bone Node" -msgstr "عقدة التنقل الزمني" +msgstr "عقدة جودو العظمية" #: modules/gltf/gltf_skin.cpp #, fuzzy @@ -17346,9 +17312,8 @@ msgid "Inverse Binds" msgstr "" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Non Joints" -msgstr "تحريك النُقطة" +msgstr "بلا مفاصل" #: modules/gltf/gltf_skin.cpp msgid "Joint I To Bone I" @@ -17372,12 +17337,11 @@ msgstr "" #: modules/gltf/gltf_spec_gloss.cpp msgid "Gloss Factor" -msgstr "" +msgstr "عامل اللمعان" #: modules/gltf/gltf_spec_gloss.cpp -#, fuzzy msgid "Specular Factor" -msgstr "مُشغل الكمية القياسية Scalar." +msgstr "عامل ال" #: modules/gltf/gltf_spec_gloss.cpp msgid "Spec Gloss Img" @@ -17385,17 +17349,15 @@ msgstr "" #: modules/gltf/gltf_state.cpp msgid "Json" -msgstr "" +msgstr "جيسون" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Major Version" -msgstr "الإصدار" +msgstr "إصدار رئيسي" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Minor Version" -msgstr "الإصدار" +msgstr "إصدار فرعي" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17416,9 +17378,8 @@ msgid "Accessors" msgstr "" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Scene Name" -msgstr "المسار للمشهد:" +msgstr "اسم المشهد" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17433,21 +17394,19 @@ msgstr "المزايا" #: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp msgid "Images" -msgstr "" +msgstr "الصور" #: modules/gltf/gltf_state.cpp msgid "Cameras" -msgstr "" +msgstr "الكاميرات" #: modules/gltf/gltf_state.cpp servers/visual_server.cpp -#, fuzzy msgid "Lights" -msgstr "ضوء" +msgstr "الأضواء" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Unique Animation Names" -msgstr "إسم رسم المتحرك جديد:" +msgstr "أسماء حركات مميزة" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17455,37 +17414,32 @@ msgid "Skeletons" msgstr "الهيكل" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeleton To Node" -msgstr "اختر عُقدة" +msgstr "هيكل إلى عقدة" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Animations" -msgstr "الرسومات المتحركة:" +msgstr "الحركات" #: modules/gltf/gltf_texture.cpp -#, fuzzy msgid "Src Image" -msgstr "إظهار العظام" +msgstr "مصدر الصورة" #: modules/gridmap/grid_map.cpp msgid "Mesh Library" msgstr "مكتبة المجسم" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Physics Material" -msgstr "نسبة الإطار الفيزيائي %" +msgstr "مادة" #: modules/gridmap/grid_map.cpp scene/3d/visual_instance.cpp -#, fuzzy msgid "Use In Baked Light" -msgstr "طبخ (إعداد) خرائط الضوء" +msgstr "استخدام في الإضاءة المطبوخة" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp msgid "Cell" -msgstr "" +msgstr "خلية" #: modules/gridmap/grid_map.cpp #, fuzzy @@ -17493,19 +17447,16 @@ msgid "Octant Size" msgstr "الواجهة View الأمامية" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center X" -msgstr "المنتصف" +msgstr "منتصف س" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Y" -msgstr "المنتصف" +msgstr "منتصف ص" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Z" -msgstr "المنتصف" +msgstr "منتصف" #: modules/gridmap/grid_map.cpp scene/2d/collision_object_2d.cpp #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp @@ -17671,14 +17622,12 @@ msgid "Generate buffers" msgstr "ولد AABB" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Direct lighting" -msgstr "الاتجاهات" +msgstr "إضاءة مباشرة" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Indirect lighting" -msgstr "المسافة البادئة يميناً" +msgstr "إضاءة غير مباشرة" #: modules/lightmapper_cpu/lightmapper_cpu.cpp #, fuzzy @@ -17714,27 +17663,24 @@ msgstr "" #: modules/minimp3/resource_importer_mp3.cpp #: modules/stb_vorbis/audio_stream_ogg_vorbis.cpp #: modules/stb_vorbis/resource_importer_ogg_vorbis.cpp -#, fuzzy msgid "Loop Offset" -msgstr "المُعادل:" +msgstr "إزاحة الحلقة" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Eye Height" -msgstr "" +msgstr "ارتفاع الغين" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "IOD" msgstr "" #: modules/mobile_vr/mobile_vr_interface.cpp -#, fuzzy msgid "Display Width" -msgstr "عرض المُخطط Wireframe" +msgstr "عرض الشاشة" #: modules/mobile_vr/mobile_vr_interface.cpp -#, fuzzy msgid "Display To Lens" -msgstr "عرض من غير ظلال" +msgstr "شاشة إلى عدسة" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Oversample" @@ -17753,14 +17699,12 @@ msgid "Class name can't be a reserved keyword" msgstr "لا يمكن أن يكون اسم الصف كلمة محجوزة" #: modules/mono/csharp_script.cpp -#, fuzzy msgid "Build Solution" -msgstr "تعبئة المُحدد" +msgstr "" #: modules/mono/editor/csharp_project.cpp -#, fuzzy msgid "Auto Update Project" -msgstr "مشروع غير مسمى" +msgstr "تحديث المشروع تلقائيًا" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -17837,9 +17781,8 @@ msgid "Seamless" msgstr "" #: modules/opensimplex/noise_texture.cpp -#, fuzzy msgid "As Normal Map" -msgstr "حجم عشوائي:" +msgstr "كخريطة عادية" #: modules/opensimplex/noise_texture.cpp msgid "Bump Strength" @@ -17847,7 +17790,7 @@ msgstr "" #: modules/opensimplex/noise_texture.cpp msgid "Noise" -msgstr "" +msgstr "ضوضاء" #: modules/opensimplex/noise_texture.cpp #, fuzzy @@ -17860,7 +17803,7 @@ msgstr "" #: modules/opensimplex/open_simplex_noise.cpp msgid "Period" -msgstr "" +msgstr "فترة" #: modules/opensimplex/open_simplex_noise.cpp #, fuzzy @@ -17876,14 +17819,12 @@ msgid "Subject" msgstr "" #: modules/regex/regex.cpp -#, fuzzy msgid "Names" -msgstr "الأسم" +msgstr "الأسماء" #: modules/regex/regex.cpp -#, fuzzy msgid "Strings" -msgstr "الإعدادات:" +msgstr "النصوص" #: modules/upnp/upnp.cpp msgid "Discover Multicast If" @@ -17898,14 +17839,12 @@ msgid "Discover IPv6" msgstr "" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "Description URL" -msgstr "الوصف" +msgstr "وصف الرابط" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "Service Type" -msgstr "تحيد نوع المتغير" +msgstr "نوع الخدمة" #: modules/upnp/upnp_device.cpp msgid "IGD Control URL" @@ -17959,9 +17898,8 @@ msgid "Stack overflow with stack depth:" msgstr "حدوث تجاوز للتكدس ( Stack overflow) مع عمق التكدس:" #: modules/visual_script/visual_script.cpp -#, fuzzy msgid "Visual Script" -msgstr "بحث VisualScript" +msgstr "البرمجة المرئية" #: modules/visual_script/visual_script_editor.cpp msgid "Change Signal Arguments" @@ -17992,14 +17930,12 @@ msgid "Add Output Port" msgstr "أضف منفذ إخراج" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Port Type" -msgstr "تغيير النوع" +msgstr "تغيير نوع المنفذ" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Port Name" -msgstr "غيّر اسم منفذ المُدخلات" +msgstr "تغيير اسم المنفذ" #: modules/visual_script/visual_script_editor.cpp msgid "Override an existing built-in function." @@ -18185,7 +18121,7 @@ msgstr "تعديل قيمة الإدخال" #: modules/visual_script/visual_script_editor.cpp msgid "Resize Comment" -msgstr "تغيير حجم التعليق" +msgstr "تغيير حجم الملاحظة" #: modules/visual_script/visual_script_editor.cpp msgid "Can't create function with a function node." @@ -20634,15 +20570,15 @@ msgstr "لا يمكن العثور على مفتاح المتجر، لا يمك #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "صيغة غير صالحة." #: platform/windows/export/export.cpp #, fuzzy @@ -20666,15 +20602,15 @@ msgstr "اسم غير صالح." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "صيغة غير صالحة." #: platform/windows/export/export.cpp #, fuzzy @@ -22836,9 +22772,8 @@ msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Pixel Size" -msgstr "محاذاة البكسل" +msgstr "حجم البكسل" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Billboard" @@ -23377,9 +23312,8 @@ msgid "Solver" msgstr "" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Exclude Nodes" -msgstr "حذف العُقد" +msgstr "استثناء العُقد" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23445,14 +23379,12 @@ msgid "Linear Ortho" msgstr "نظر من الخلف (متعامد/ليس له بعد ثالث)" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper Angle" -msgstr "الأحرف الكبيرة (Uppercase)" +msgstr "الزاوية العلوية" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower Angle" -msgstr "الأحرف الصغيرة (Lowercase)" +msgstr "الزاوية السفلية" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23608,9 +23540,8 @@ msgid "Thickness" msgstr "" #: scene/3d/reflection_probe.cpp scene/main/viewport.cpp -#, fuzzy msgid "Update Mode" -msgstr "وضع التدوير" +msgstr "وضع التحديث" #: scene/3d/reflection_probe.cpp #, fuzzy @@ -23709,7 +23640,7 @@ msgstr "يجب توافر مدير-غرف (RoomManager) واحد فقط في ش #: scene/3d/room_manager.cpp msgid "Main" -msgstr "" +msgstr "رئيسي | الرئيسي" #: scene/3d/room_manager.cpp scene/animation/animation_blend_tree.cpp #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp @@ -23972,13 +23903,12 @@ msgid "Per-Wheel Motion" msgstr "زر العجلة للأسفل" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Engine Force" -msgstr "مستندات الإنترنت" +msgstr "قوة المحرك" #: scene/3d/vehicle_body.cpp msgid "Brake" -msgstr "" +msgstr "فرامل | مكابح" #: scene/3d/vehicle_body.cpp msgid "Steering" @@ -23998,9 +23928,8 @@ msgid "Use As Steering" msgstr "" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Wheel" -msgstr "العجلة نحو الأقصى." +msgstr "عجلة" #: scene/3d/vehicle_body.cpp msgid "Roll Influence" @@ -24130,14 +24059,12 @@ msgid "Fadeout Time" msgstr "وقت التلاشي X (ثواني):" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Auto Restart" -msgstr "إعادة تشغيل تلقائية:" +msgstr "إعادة تشغيل تلقائية" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Autorestart" -msgstr "إعادة تشغيل تلقائية:" +msgstr "إعادة تشغيل تلقائية" #: scene/animation/animation_blend_tree.cpp msgid "Delay" diff --git a/editor/translations/az.po b/editor/translations/az.po index cd3e8def9b..af28a85240 100644 --- a/editor/translations/az.po +++ b/editor/translations/az.po @@ -5,49 +5,49 @@ # # Jafar Tarverdiyev <cefertarverdiyevv@gmail.com>, 2021. # Lucifer25x <umudyt2006@gmail.com>, 2021. +# Ümid Quliyev <lucifer25x@protonmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2021-09-16 14:36+0000\n" -"Last-Translator: Lucifer25x <umudyt2006@gmail.com>\n" +"PO-Revision-Date: 2022-08-05 01:04+0000\n" +"Last-Translator: Ümid Quliyev <lucifer25x@protonmail.com>\n" "Language-Team: Azerbaijani <https://hosted.weblate.org/projects/godot-engine/" "godot/az/>\n" "Language: az\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.9-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp +#, fuzzy msgid "Tablet Driver" -msgstr "" +msgstr "Planşet sürücü" #: core/bind/core_bind.cpp -#, fuzzy msgid "Clipboard" -msgstr "Pano boşdur!" +msgstr "Pano" #: core/bind/core_bind.cpp -#, fuzzy msgid "Current Screen" -msgstr "Animasiya xüsusiyyətləri." +msgstr "Aktiv Ekran" #: core/bind/core_bind.cpp msgid "Exit Code" -msgstr "" +msgstr "Çıxış Kodu" #: core/bind/core_bind.cpp msgid "V-Sync Enabled" -msgstr "" +msgstr "V-Sync Aktivdir" #: core/bind/core_bind.cpp main/main.cpp msgid "V-Sync Via Compositor" -msgstr "" +msgstr "V-Sync Kompozitor Vasitəsilə" #: core/bind/core_bind.cpp main/main.cpp msgid "Delta Smoothing" -msgstr "" +msgstr "Delta hamarlanması" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode" @@ -59,28 +59,28 @@ msgstr "" #: core/bind/core_bind.cpp main/main.cpp platform/uwp/os_uwp.cpp msgid "Keep Screen On" -msgstr "" +msgstr "Ekranı Açıq Tut" #: core/bind/core_bind.cpp msgid "Min Window Size" -msgstr "" +msgstr "Minimum Pəncərə Ölçüsü" #: core/bind/core_bind.cpp msgid "Max Window Size" -msgstr "" +msgstr "Maksimum Pəncərə Ölçüsü" #: core/bind/core_bind.cpp msgid "Screen Orientation" -msgstr "" +msgstr "Pəncərə Nisbəti" #: core/bind/core_bind.cpp core/project_settings.cpp main/main.cpp #: platform/uwp/os_uwp.cpp msgid "Window" -msgstr "" +msgstr "Pəncərə" #: core/bind/core_bind.cpp core/project_settings.cpp msgid "Borderless" -msgstr "" +msgstr "Kənarsız" #: core/bind/core_bind.cpp msgid "Per Pixel Transparency Enabled" @@ -88,29 +88,28 @@ msgstr "" #: core/bind/core_bind.cpp core/project_settings.cpp msgid "Fullscreen" -msgstr "" +msgstr "Bütün Ekran" #: core/bind/core_bind.cpp msgid "Maximized" -msgstr "" +msgstr "Böyüdülmüş" #: core/bind/core_bind.cpp msgid "Minimized" -msgstr "" +msgstr "Kiçildilmiş" #: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp #: scene/gui/graph_node.cpp msgid "Resizable" -msgstr "" +msgstr "Ölçüsü Dəyişdirilə Bilər" #: core/bind/core_bind.cpp core/os/input_event.cpp scene/2d/node_2d.cpp #: scene/2d/physics_body_2d.cpp scene/2d/remote_transform_2d.cpp #: scene/3d/physics_body.cpp scene/3d/remote_transform.cpp #: scene/gui/control.cpp scene/gui/line_edit.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Position" -msgstr "Animasiyanı Təmizləmə" +msgstr "Pozisiya" #: core/bind/core_bind.cpp core/project_settings.cpp editor/editor_settings.cpp #: main/main.cpp modules/gridmap/grid_map.cpp @@ -122,7 +121,7 @@ msgstr "Animasiyanı Təmizləmə" #: scene/resources/style_box.cpp scene/resources/texture.cpp #: scene/resources/visual_shader.cpp servers/visual_server.cpp msgid "Size" -msgstr "" +msgstr "Ölçü" #: core/bind/core_bind.cpp msgid "Endian Swap" @@ -131,25 +130,23 @@ msgstr "" #: core/bind/core_bind.cpp #, fuzzy msgid "Editor Hint" -msgstr "Redaktə et" +msgstr "Editor İpucu" #: core/bind/core_bind.cpp msgid "Print Error Messages" -msgstr "" +msgstr "Xəta Mesajlarını Yazdır" #: core/bind/core_bind.cpp -#, fuzzy msgid "Iterations Per Second" -msgstr "İnterpolasiya rejimi" +msgstr "Hər Saniyədə İterasiya Sayı" #: core/bind/core_bind.cpp msgid "Target FPS" -msgstr "" +msgstr "Hədəf FPS" #: core/bind/core_bind.cpp -#, fuzzy msgid "Time Scale" -msgstr "Animasya Açarlarını Ölçülə" +msgstr "Zaman Ölçəyi" #: core/bind/core_bind.cpp main/main.cpp msgid "Physics Jitter Fix" @@ -157,25 +154,23 @@ msgstr "" #: core/bind/core_bind.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Error" -msgstr "" +msgstr "Xəta" #: core/bind/core_bind.cpp -#, fuzzy msgid "Error String" -msgstr "Yükləmə xətası:" +msgstr "Xəta Yazısı" #: core/bind/core_bind.cpp -#, fuzzy msgid "Error Line" -msgstr "Yükləmə xətası:" +msgstr "Xəta Sətiri" #: core/bind/core_bind.cpp msgid "Result" -msgstr "" +msgstr "Nəticə" #: core/command_queue_mt.cpp core/message_queue.cpp main/main.cpp msgid "Memory" -msgstr "" +msgstr "Yaddaş" #: core/command_queue_mt.cpp core/message_queue.cpp #: core/register_core_types.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp @@ -186,11 +181,11 @@ msgstr "" #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: servers/visual_server.cpp msgid "Limits" -msgstr "" +msgstr "Limitlər" #: core/command_queue_mt.cpp msgid "Command Queue" -msgstr "" +msgstr "Əmr Növbəsi" #: core/command_queue_mt.cpp msgid "Multithreading Queue Size (KB)" @@ -200,14 +195,13 @@ msgstr "" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp #: scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Function" -msgstr "Funksiyalar:" +msgstr "Funksiya" #: core/image.cpp core/packed_data_container.cpp scene/2d/polygon_2d.cpp #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Data" -msgstr "" +msgstr "Məlumat" #: core/io/file_access_network.cpp core/register_core_types.cpp #: editor/editor_file_dialog.cpp editor/editor_settings.cpp main/main.cpp @@ -215,16 +209,15 @@ msgstr "" #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: scene/gui/file_dialog.cpp msgid "Network" -msgstr "" +msgstr "Şəbəkə" #: core/io/file_access_network.cpp -#, fuzzy msgid "Remote FS" -msgstr "Sil" +msgstr "Uzaqdan FS" #: core/io/file_access_network.cpp msgid "Page Size" -msgstr "" +msgstr "Səhifə Ölçüsü" #: core/io/file_access_network.cpp msgid "Page Read Ahead" @@ -232,12 +225,11 @@ msgstr "" #: core/io/http_client.cpp msgid "Blocking Mode Enabled" -msgstr "" +msgstr "Bloklama Modu Aktivdir" #: core/io/http_client.cpp -#, fuzzy msgid "Connection" -msgstr "Qoş" +msgstr "Əlaqə" #: core/io/http_client.cpp msgid "Read Chunk Size" @@ -245,15 +237,15 @@ msgstr "" #: core/io/marshalls.cpp msgid "Object ID" -msgstr "" +msgstr "Obyekt ID" #: core/io/multiplayer_api.cpp core/io/packet_peer.cpp msgid "Allow Object Decoding" -msgstr "" +msgstr "Obyekt Deşifrəsinə İzn Verin" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp msgid "Refuse New Network Connections" -msgstr "" +msgstr "Yeni Şəbəkə Əlaqələrindən İmtina Et" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp msgid "Network Peer" @@ -261,16 +253,15 @@ msgstr "" #: core/io/multiplayer_api.cpp scene/animation/animation_player.cpp msgid "Root Node" -msgstr "" +msgstr "Kök Düyün" #: core/io/networked_multiplayer_peer.cpp -#, fuzzy msgid "Refuse New Connections" -msgstr "Qoş" +msgstr "Yeni Əlaqələrdən İmtina Et" #: core/io/networked_multiplayer_peer.cpp msgid "Transfer Mode" -msgstr "" +msgstr "Transfer Modu" #: core/io/packet_peer.cpp msgid "Encode Buffer Max Size" @@ -294,16 +285,15 @@ msgstr "" #: core/io/stream_peer.cpp msgid "Data Array" -msgstr "" +msgstr "Məlumat Siyahısı" #: core/io/stream_peer_ssl.cpp msgid "Blocking Handshake" -msgstr "" +msgstr "Əl Sıxmağın Qarşısının Alınması" #: core/io/udp_server.cpp -#, fuzzy msgid "Max Pending Connections" -msgstr "Əlaqəni redaktə edin:" +msgstr "Gözlənilən Maksimum Əlaqələr" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -325,7 +315,6 @@ msgstr "" "format." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %d (not passed) in expression" msgstr "İfadədə uyğunsuz giriş %d (ötürülmədi)" @@ -2163,14 +2152,15 @@ msgstr "Favoritlər:" msgid "Recent:" msgstr "Son:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Axtar:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Uyğunlaşmalar:" @@ -2230,8 +2220,8 @@ msgstr "Əvəzetmə mənbəyini axtarın:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2809,8 +2799,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Animasiyanı Təmizləmə" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5410,6 +5401,10 @@ msgid "Drag And Drop Selection" msgstr "Ölçmə seçimi" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11445,6 +11440,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Animasiyanı Təmizləmə" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19631,14 +19631,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19660,14 +19659,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/bg.po b/editor/translations/bg.po index 06d16ebe96..d2d7a56dc3 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -2177,14 +2177,15 @@ msgstr "Любими:" msgid "Recent:" msgstr "Последни:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Търсене:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Съвпадения:" @@ -2244,8 +2245,8 @@ msgstr "Търсене на заместващ ресурс:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2813,8 +2814,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Копиране на избраното" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5494,6 +5496,10 @@ msgid "Drag And Drop Selection" msgstr "Настройки" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11659,6 +11665,11 @@ msgid "New Animation" msgstr "Нова анимация" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Филтриране на методите" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Скорост:" @@ -20100,15 +20111,15 @@ msgstr "Не е намерено хранилище за ключове. Изн #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Неправилно разширение." #: platform/windows/export/export.cpp #, fuzzy @@ -20132,15 +20143,15 @@ msgstr "Неправилно име." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Неправилно разширение." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/bn.po b/editor/translations/bn.po index c2ed1a7596..6f1e8f945d 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -2233,14 +2233,15 @@ msgstr "ফেবরিট/প্রিয়-সমূহ:" msgid "Recent:" msgstr "সাম্প্রতিক:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "অনুসন্ধান করুন:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "মিলসমূহ:" @@ -2302,8 +2303,8 @@ msgstr "প্রতিস্থাপক রিসোর্স-এর অনু #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2903,7 +2904,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "পথ প্রতিলিপি/কপি করুন" #: editor/editor_export.cpp @@ -5821,6 +5822,10 @@ msgid "Drag And Drop Selection" msgstr "নির্বাচিত সমূহ অপসারণ করুন" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12482,6 +12487,11 @@ msgstr "অ্যানিমেশন" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy +msgid "Filter animations" +msgstr "ফিল্টারসমূহ" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Speed:" msgstr "গতি (FPS):" @@ -21529,15 +21539,15 @@ msgstr "ফোল্ডার তৈরী করা সম্ভব হয়ন #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "অগ্রহণযোগ্য এক্সটেনশন" #: platform/windows/export/export.cpp #, fuzzy @@ -21561,15 +21571,15 @@ msgstr "অগ্রহনযোগ্য নাম।" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "অগ্রহণযোগ্য এক্সটেনশন" #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/br.po b/editor/translations/br.po index 2d7b6fe900..823490a280 100644 --- a/editor/translations/br.po +++ b/editor/translations/br.po @@ -2108,14 +2108,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2171,8 +2172,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2731,8 +2732,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Tro Fiñvskeudenn" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5318,6 +5320,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11309,6 +11315,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Tro Fiñvskeudenn" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19423,14 +19434,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19452,14 +19462,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 67f0296b05..04c9b7761c 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -2143,14 +2143,15 @@ msgstr "Favorits:" msgid "Recent:" msgstr "Recents:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cerca:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Coincidències:" @@ -2210,8 +2211,8 @@ msgstr "Cerca Recurs Reemplaçant:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2789,7 +2790,8 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." +#, fuzzy +msgid "Completed with warnings." msgstr "Completat amb errors." #: editor/editor_export.cpp @@ -5607,6 +5609,10 @@ msgid "Drag And Drop Selection" msgstr "Elimina la Selecció del GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11962,6 +11968,11 @@ msgstr "Nova Animació" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy +msgid "Filter animations" +msgstr "Filtrar mètodes" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Speed:" msgstr "Velocitat (FPS):" @@ -20963,15 +20974,15 @@ msgstr "No es pot obrir la plantilla per exportar." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "L'extensió no és vàlida." #: platform/windows/export/export.cpp #, fuzzy @@ -20995,15 +21006,15 @@ msgstr "Nom no vàlid." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "L'extensió no és vàlida." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/cs.po b/editor/translations/cs.po index a166951396..1e92a92ae7 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -2238,14 +2238,15 @@ msgstr "Oblíbené:" msgid "Recent:" msgstr "Nedávné:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Hledat:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Shody:" @@ -2305,8 +2306,8 @@ msgstr "Hledat náhradní zdroj:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2881,7 +2882,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Kopírovat cestu k uzlu" #: editor/editor_export.cpp @@ -5681,6 +5682,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap Vyplnit výběr" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11953,6 +11958,11 @@ msgid "New Animation" msgstr "Nová animace" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrovat metody" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Rychlost:" @@ -20724,15 +20734,15 @@ msgstr "Nepodařilo se najít úložiště klíčů, nelze exportovat." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Neplatná přípona." #: platform/windows/export/export.cpp #, fuzzy @@ -20756,15 +20766,15 @@ msgstr "Neplatný název." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Neplatná přípona." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/da.po b/editor/translations/da.po index b4f7334278..1bb05be6f9 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -2227,14 +2227,15 @@ msgstr "Favoritter:" msgid "Recent:" msgstr "Seneste:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Søgning:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Matches:" @@ -2296,8 +2297,8 @@ msgstr "Søg Erstatnings Ressource:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2894,8 +2895,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Fjern Markering" #: editor/editor_export.cpp #, fuzzy @@ -5734,6 +5736,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap Slet Markerede" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12145,6 +12151,11 @@ msgid "New Animation" msgstr "Ny Animation Navn:" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filter mode:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20901,15 +20912,15 @@ msgstr "Kan ikke åbne skabelon til eksport:\n" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Du skal bruge en gyldig udvidelse." #: platform/windows/export/export.cpp #, fuzzy @@ -20933,15 +20944,15 @@ msgstr "Ugyldigt navn." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Du skal bruge en gyldig udvidelse." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/de.po b/editor/translations/de.po index 64b8268adb..aa92914ada 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -82,13 +82,14 @@ # Christian Packenius <christian@packenius.com>, 2022. # Sajeg <jfx@posteo.de>, 2022. # Tobias Jacobs <tobi@jacobs.rocks>, 2022. +# JeremyStarTM <jeremystartm@tuta.io>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-09 21:11+0000\n" -"Last-Translator: So Wieso <sowieso@dukun.de>\n" +"PO-Revision-Date: 2022-07-31 18:34+0000\n" +"Last-Translator: JeremyStarTM <jeremystartm@tuta.io>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" "Language: de\n" @@ -96,7 +97,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -520,9 +521,8 @@ msgid "Pressure" msgstr "Druck" #: core/os/input_event.cpp -#, fuzzy msgid "Pen Inverted" -msgstr "Umkehren" +msgstr "Stift invertiert" #: core/os/input_event.cpp msgid "Relative" @@ -1633,7 +1633,7 @@ msgstr "Methodenaufrufsspurschlüssel hinzufügen" #: editor/animation_track_editor.cpp msgid "Method not found in object:" -msgstr "Methode nicht in Objekt gefunden:" +msgstr "Methode im Objekt nicht gefunden:" #: editor/animation_track_editor.cpp msgid "Anim Move Keys" @@ -2169,14 +2169,15 @@ msgstr "Favoriten:" msgid "Recent:" msgstr "Kürzlich:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Suche:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Treffer:" @@ -2236,8 +2237,8 @@ msgstr "Ersatzressource suchen:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2814,7 +2815,8 @@ msgid "Project export for platform:" msgstr "Projektexport für Plattform:" #: editor/editor_export.cpp -msgid "Completed with errors." +#, fuzzy +msgid "Completed with warnings." msgstr "Fertiggestellt mit Fehlern." #: editor/editor_export.cpp @@ -5568,6 +5570,10 @@ msgid "Drag And Drop Selection" msgstr "Auswahl ziehen und fallen lassen" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "Im Skript Editor bei ausgewähltem Node bleiben" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Aussehen" @@ -11693,6 +11699,10 @@ msgid "New Animation" msgstr "Neue Animation" #: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Filter animations" +msgstr "Animationen filtern" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Geschwindigkeit:" @@ -18142,7 +18152,7 @@ msgstr "Ungültiges Argument vom Typ:" #: modules/visual_script/visual_script_nodes.cpp msgid "Invalid arguments:" -msgstr "Ungültige Argumente:" +msgstr "Ungültige Parameter:" #: modules/visual_script/visual_script_nodes.cpp msgid "a if cond, else b" @@ -19643,8 +19653,8 @@ msgid "" "Could not start codesign executable, make sure Xcode command line tools are " "installed." msgstr "" -"Codesign-Anwendung konnte nicht gestartet werden. Wurden die Xcode-" -"Kommandozeilen-Hilfsprogramme installiert?" +"Codesign-Anwendung konnte nicht gestartet werden, stelle sicher dass die " +"Xcode-Kommandozeilen-Tools installiert sind." #: platform/osx/export/export.cpp platform/windows/export/export.cpp msgid "No identity found." @@ -20136,17 +20146,18 @@ msgid "Could not find wine executable at \"%s\"." msgstr "Anwendung wine konnte nicht gefunden werden in „%s“." #: platform/windows/export/export.cpp +#, fuzzy msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" "Anwendung rcedit konnte nicht gestartet werden. Bitte rcedit-Pfad in " "Editoreinstellungen festlegen (Export > Windows > Rcedit)." #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +#, fuzzy +msgid "rcedit failed to modify executable: %s." msgstr "" "Modifikation der Anwendung durch rcedit fehlgeschlagen:\n" "%s" @@ -20168,17 +20179,18 @@ msgid "Invalid timestamp server." msgstr "Ungültiger Zeitstempelserver." #: platform/windows/export/export.cpp +#, fuzzy msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" "Anwendung signtool konnte nicht gestartet werden. Bitte signtool-Pfad in " "Editoreinstellungen festlegen (Export > Windows > Signtool)." #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +#, fuzzy +msgid "Signtool failed to sign executable: %s." msgstr "" "Signieren der Anwendung durch Signtool ist fehlgeschlagen:\n" "%s" @@ -23109,9 +23121,8 @@ msgstr "" "geändert werden." #: scene/3d/spatial.cpp -#, fuzzy msgid "Global Translation" -msgstr "Globales Transform" +msgstr "Globale Verschiebung" #: scene/3d/spatial.cpp msgid "Matrix" diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index 231863615b..23c58c5ffb 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -2060,14 +2060,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2123,8 +2124,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2683,7 +2684,7 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "" #: editor/editor_export.cpp @@ -5256,6 +5257,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11206,6 +11211,10 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Filter animations" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19249,14 +19258,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19277,14 +19285,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/el.po b/editor/translations/el.po index 8511b4fdd2..4b71ed8528 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -2184,14 +2184,15 @@ msgstr "Αγαπημένα:" msgid "Recent:" msgstr "Πρόσφατα:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Αναζήτηση:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Αντιστοιχίες:" @@ -2251,8 +2252,8 @@ msgstr "Αναζήτηση αντικαταστάτη πόρου:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2840,7 +2841,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Αντιγραφή διαδρομής κόμβου" #: editor/editor_export.cpp @@ -5663,6 +5664,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap Γέμισμα Επιλογής" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12044,6 +12049,11 @@ msgid "New Animation" msgstr "Νέα Κίνηση" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Φιλτράρισμα μεθόδων" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Ταχύτητα:" @@ -20897,15 +20907,15 @@ msgstr "Σφάλμα κατά το άνοιγμα προτύπου για εξα #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Άκυρη επέκταση." #: platform/windows/export/export.cpp #, fuzzy @@ -20929,15 +20939,15 @@ msgstr "Μη έγκυρο όνομα." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Άκυρη επέκταση." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/en_Shaw.po b/editor/translations/en_Shaw.po index d69ca8d97f..361c10ce1a 100644 --- a/editor/translations/en_Shaw.po +++ b/editor/translations/en_Shaw.po @@ -2083,14 +2083,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2146,8 +2147,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2706,8 +2707,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "𐑓𐑳𐑙𐑒𐑖𐑩𐑯𐑟:" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5284,6 +5286,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11257,6 +11263,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "𐑦𐑯𐑑𐑻𐑐𐑩𐑤𐑱𐑖𐑩𐑯 𐑥𐑴𐑛" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19343,14 +19354,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19372,14 +19382,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/eo.po b/editor/translations/eo.po index 3b651b3e97..0139382972 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -2206,14 +2206,15 @@ msgstr "Favoritaj:" msgid "Recent:" msgstr "Lastatempe:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Serĉo:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Matĉoj:" @@ -2273,8 +2274,8 @@ msgstr "Serĉi anstataŭiga risurco:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2851,8 +2852,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Kopii elektaron" #: editor/editor_export.cpp #, fuzzy @@ -5656,6 +5658,10 @@ msgid "Drag And Drop Selection" msgstr "Enkadrigi elekton" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11939,6 +11945,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Forigi animacion?" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20545,15 +20556,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Nevalida kromprogramo." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20575,15 +20586,15 @@ msgstr "Malvalida nomo." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Nevalida kromprogramo." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/es.po b/editor/translations/es.po index 3c21955a46..173b195cc4 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -81,13 +81,17 @@ # David Martínez <goddrinksjava@gmail.com>, 2022. # Nagamine-j <jimmy.kochi@unmsm.edu.pe>, 2022. # Esdras Caleb Oliveira Silva <acheicaleb@gmail.com>, 2022. +# Luis Ortiz <luisortiz66@hotmail.com>, 2022. +# Angel Andrade <aandradeb99@gmail.com>, 2022. +# Juan Felipe Gómez López <juanfgomez0912@gmail.com>, 2022. +# Pineappletooth <yochank003@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-06-29 10:04+0000\n" -"Last-Translator: Esdras Caleb Oliveira Silva <acheicaleb@gmail.com>\n" +"PO-Revision-Date: 2022-08-05 01:04+0000\n" +"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" "Language: es\n" @@ -95,7 +99,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -225,7 +229,7 @@ msgstr "Escala de Tiempo" #: core/bind/core_bind.cpp main/main.cpp msgid "Physics Jitter Fix" -msgstr "Arreglo de las Fluctuaciones Físicas" +msgstr "Corrección de Fluctuaciones de Física" #: core/bind/core_bind.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Error" @@ -467,9 +471,8 @@ msgid "Command" msgstr "Command" #: core/os/input_event.cpp -#, fuzzy msgid "Physical" -msgstr " (Física)" +msgstr "Física" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp @@ -523,7 +526,7 @@ msgstr "Presionado" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Pluma Invertida" #: core/os/input_event.cpp msgid "Relative" @@ -725,14 +728,12 @@ msgid "Script Templates Search Path" msgstr "Ruta de Búsqueda de Plantillas de Scripts" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Autoload On Startup" -msgstr "Cargar automáticamente al inicio" +msgstr "Carga Automática de Control de Versiones al Inicio" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Plugin Name" -msgstr "Control de Versiones" +msgstr "Nombre del Plugin de Control de Versiones" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp @@ -1222,21 +1223,19 @@ msgid "Type" msgstr "Tipo" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "Establecer Manipulador" +msgstr "En el Manipulador" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out Handle" -msgstr "Establecer Manipulador" +msgstr "Fuera del Manipulador" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp msgid "Stream" -msgstr "" +msgstr "Stream" #: editor/animation_track_editor.cpp msgid "Start Offset" @@ -1257,9 +1256,8 @@ msgid "Animation" msgstr "Animación" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Easing" -msgstr "Entrada-Salida Suave" +msgstr "Suavizar" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -1414,19 +1412,16 @@ msgid "Stream:" msgstr "Stream:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Start (s):" -msgstr "Reiniciar (s):" +msgstr "Inicio (s):" #: editor/animation_track_editor.cpp -#, fuzzy msgid "End (s):" -msgstr "Fundido de entrada (s):" +msgstr "Fin (s):" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation Clip:" -msgstr "Animaciones:" +msgstr "Clip de Animación:" #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" @@ -2180,14 +2175,15 @@ msgstr "Favoritos:" msgid "Recent:" msgstr "Recientes:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Buscar:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Coincidencias:" @@ -2247,8 +2243,8 @@ msgstr "Buscar Recurso de Reemplazo:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2257,7 +2253,7 @@ msgstr "Abrir" #: editor/dependency_editor.cpp msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "Propietarios de: %s (Total: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2821,7 +2817,8 @@ msgid "Project export for platform:" msgstr "Exportar proyecto para la plataforma:" #: editor/editor_export.cpp -msgid "Completed with errors." +#, fuzzy +msgid "Completed with warnings." msgstr "Completado con errores." #: editor/editor_export.cpp @@ -2984,9 +2981,8 @@ msgid "Custom release template not found." msgstr "Plantilla release personalizada no encontrada." #: editor/editor_export.cpp -#, fuzzy msgid "Prepare Template" -msgstr "Administrar Plantillas" +msgstr "Preparar Plantilla" #: editor/editor_export.cpp platform/osx/export/export.cpp msgid "The given export path doesn't exist." @@ -3002,9 +2998,8 @@ msgstr "Fallo al copiar la plantilla de exportación." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp -#, fuzzy msgid "PCK Embedding" -msgstr "Relleno" +msgstr "Integrar PCK" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." @@ -3403,7 +3398,7 @@ msgstr "Mostrar/Ocultar archivos ocultos." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." -msgstr "Ver elementos como una cuadrícula de miniaturas." +msgstr "Sesgo del nivel de división de la cuadrícula." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a list." @@ -4583,7 +4578,7 @@ msgstr "Exportar…" #: editor/editor_node.cpp msgid "Install Android Build Template..." -msgstr "Instalar plantilla de compilación de Android..." +msgstr "Instalar Plantilla de Compilación de Android..." #: editor/editor_node.cpp msgid "Open User Data Folder" @@ -4902,8 +4897,8 @@ msgstr "" "personalizado al exportarlo (agregando módulos, cambiando el AndroidManifest." "xml, etc.).\n" "Ten en cuenta que para realizar compilaciones personalizadas en lugar de " -"usar APKs predefinidos, la opción \"Use Custom Build\" debería estar " -"habilitada en la configuración de exportación de Android." +"usar APKs predefinidos, la opción \"Usar Compilación Personalizada\" debería " +"estar habilitada en la configuración de exportación de Android." #: editor/editor_node.cpp msgid "" @@ -5285,9 +5280,8 @@ msgstr "" "preset existente como ejecutable." #: editor/editor_run_native.cpp -#, fuzzy msgid "Project Run" -msgstr "Proyecto" +msgstr "Ejecutar Proyecto" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." @@ -5359,11 +5353,11 @@ msgstr "Atenuar Editor en Diálogo de Popup" #: editor/editor_settings.cpp main/main.cpp msgid "Low Processor Mode Sleep (µsec)" -msgstr "" +msgstr "Modo de Reposo en Consumo Bajo del Procesador (µsec)" #: editor/editor_settings.cpp msgid "Unfocused Low Processor Mode Sleep (µsec)" -msgstr "" +msgstr "Modo de Bajo Uso del Procesador Desconectado (µseg)" #: editor/editor_settings.cpp msgid "Separate Distraction Mode" @@ -5375,7 +5369,7 @@ msgstr "Abrir Capturas De Pantalla Automáticamente" #: editor/editor_settings.cpp msgid "Max Array Dictionary Items Per Page" -msgstr "" +msgstr "Cantidad Máxima de Elementos del Diccionario por Página" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp scene/gui/control.cpp @@ -5453,7 +5447,7 @@ msgstr "Comprimir Recursos Binarios" #: editor/editor_settings.cpp msgid "Safe Save On Backup Then Rename" -msgstr "" +msgstr "Guardar de Forma Segura en el Backup y luego Renombrar" #: editor/editor_settings.cpp msgid "File Dialog" @@ -5465,7 +5459,7 @@ msgstr "Tamaño de las Miniaturas" #: editor/editor_settings.cpp msgid "Docks" -msgstr "" +msgstr "Paneles" #: editor/editor_settings.cpp msgid "Scene Tree" @@ -5488,9 +5482,8 @@ msgid "Auto Refresh Interval" msgstr "Intervalo de Auto Refrescar" #: editor/editor_settings.cpp -#, fuzzy msgid "Subresource Hue Tint" -msgstr "Sub-Recursos" +msgstr "Subrecurso Tinte del Tono" #: editor/editor_settings.cpp msgid "Color Theme" @@ -5570,9 +5563,12 @@ msgid "Mouse Extra Buttons Navigate History" msgstr "Botones Extra del Ratón Navegar por el Historial" #: editor/editor_settings.cpp -#, fuzzy msgid "Drag And Drop Selection" -msgstr "Seleccionar GridMap" +msgstr "Arrastrar y Soltar la Selección" + +#: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "Permanecer En Editor de Scripts En Nodo Seleccionado" #: editor/editor_settings.cpp msgid "Appearance" @@ -5616,7 +5612,7 @@ msgstr "Directriz de longitud de Línea de Columna Flexible" #: editor/editor_settings.cpp msgid "Line Length Guideline Hard Column" -msgstr "" +msgstr "Longitud de Línea de la Guía de la Columna Rígida" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp msgid "Script List" @@ -5702,11 +5698,11 @@ msgstr "Espera de Completado de Código" #: editor/editor_settings.cpp msgid "Put Callhint Tooltip Below Current Line" -msgstr "Colocar la Información Sobre la Llamada Debajo de la Línea Actual" +msgstr "Colocar Tooltip de Llamada Debajo de la Línea Actual" #: editor/editor_settings.cpp msgid "Callhint Tooltip Offset" -msgstr "Desplazamiento de la Información Sobre la Llamada" +msgstr "Desplazamiento del Tooltip de Llamada" #: editor/editor_settings.cpp msgid "Complete File Paths" @@ -5806,7 +5802,7 @@ msgstr "Nivel Mínimo de División de Cuadrícula" #: editor/editor_settings.cpp msgid "Grid Division Level Bias" -msgstr "" +msgstr "Sesgo del Nivel de División de la Cuadrícula" #: editor/editor_settings.cpp msgid "Grid XZ Plane" @@ -5865,23 +5861,20 @@ msgid "Orbit Modifier" msgstr "Modificador de Órbita" #: editor/editor_settings.cpp -#, fuzzy msgid "Pan Modifier" -msgstr "Modo desplazamiento lateral" +msgstr "Modificador Panorámico" #: editor/editor_settings.cpp -#, fuzzy msgid "Zoom Modifier" -msgstr "Modificado/s" +msgstr "Modificador de Zoom" #: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp msgid "Warped Mouse Panning" -msgstr "" +msgstr "Paneo del Mouse Deformado" #: editor/editor_settings.cpp -#, fuzzy msgid "Navigation Feel" -msgstr "Modo de Navegación" +msgstr "Sensación de Navegación" #: editor/editor_settings.cpp msgid "Orbit Sensitivity" @@ -5924,9 +5917,8 @@ msgid "Freelook Activation Modifier" msgstr "Modificador de Activación de Vista Libre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Speed Zoom Link" -msgstr "Modificador de Velocidad de Vista Libre" +msgstr "Velocidad de Zoom de Vista Libre" #: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp msgid "Grid Color" @@ -5974,7 +5966,7 @@ msgstr "Color del Borde del Viewport" #: editor/editor_settings.cpp msgid "Constrain Editor View" -msgstr "" +msgstr "Vista del Editor de Restricciones" #: editor/editor_settings.cpp msgid "Simple Panning" @@ -6035,14 +6027,12 @@ msgstr "Ubicación de la Ventana" #: editor/editor_settings.cpp scene/2d/back_buffer_copy.cpp scene/2d/sprite.cpp #: scene/2d/visibility_notifier_2d.cpp scene/3d/sprite_3d.cpp #: scene/gui/control.cpp -#, fuzzy msgid "Rect" -msgstr "Completo" +msgstr "Rect" #: editor/editor_settings.cpp -#, fuzzy msgid "Rect Custom Position" -msgstr "Establecer Posición de Salida de Curva" +msgstr "Posición Personalizada de Rect" #: editor/editor_settings.cpp platform/android/export/export_plugin.cpp msgid "Screen" @@ -6108,24 +6098,23 @@ msgstr "Color de Palabra Clave" #: editor/editor_settings.cpp msgid "Control Flow Keyword Color" -msgstr "" +msgstr "Control de Flujo Color de Palabra Clave" #: editor/editor_settings.cpp -#, fuzzy msgid "Base Type Color" -msgstr "Tipo Base" +msgstr "Tipo de Color Base" #: editor/editor_settings.cpp msgid "Engine Type Color" -msgstr "" +msgstr "Tipo de Color del Engine" #: editor/editor_settings.cpp msgid "User Type Color" -msgstr "" +msgstr "Tipo de Color del Usuario" #: editor/editor_settings.cpp msgid "Comment Color" -msgstr "" +msgstr "Color de los Comentarios" #: editor/editor_settings.cpp msgid "String Color" @@ -6142,25 +6131,24 @@ msgid "Completion Background Color" msgstr "Completar Color de Fondo" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Completion Selected Color" -msgstr "Importar Seleccionado" +msgstr "Completar Color Seleccionado" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Existing Color" -msgstr "" +msgstr "Completar Color Existente" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Scroll Color" -msgstr "" +msgstr "Completar Color de Scroll" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Font Color" -msgstr "" +msgstr "Completar Color de la Fuente" #: editor/editor_settings.cpp msgid "Text Color" -msgstr "Color de Texto" +msgstr "Color del Texto" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Line Number Color" @@ -6172,7 +6160,7 @@ msgstr "Color de Número de Línea Seguro" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Caret Color" -msgstr "" +msgstr "Color del Caret" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Caret Background Color" @@ -6199,33 +6187,28 @@ msgid "Line Length Guideline Color" msgstr "" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Word Highlighted Color" -msgstr "Resaltador de Sintaxis" +msgstr "Color de la Palabra Resaltada" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Number Color" -msgstr "" +msgstr "Número del Color" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Function Color" -msgstr "Función" +msgstr "Función Color" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Member Variable Color" -msgstr "Cambiar nombre de variable" +msgstr "Color de la Variable Miembro" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Mark Color" -msgstr "Seleccionar Color" +msgstr "Marcar Color" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Bookmark Color" -msgstr "Marcadores" +msgstr "Color del Marcador" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Breakpoint Color" @@ -6233,21 +6216,19 @@ msgstr "Puntos de Interrupción" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Executing Line Color" -msgstr "" +msgstr "Color de la línea de ejecución" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Code Folding Color" msgstr "" #: editor/editor_settings.cpp -#, fuzzy msgid "Search Result Color" -msgstr "Resultados de la Búsqueda" +msgstr "Color del Resultado de Búsqueda" #: editor/editor_settings.cpp -#, fuzzy msgid "Search Result Border Color" -msgstr "Resultados de la Búsqueda" +msgstr "Color de los Bordes del Resultado de Búsqueda" #: editor/editor_spin_slider.cpp msgid "Hold %s to round to integers. Hold Shift for more precise changes." @@ -6256,14 +6237,12 @@ msgstr "" "la tecla Mayús para cambios más precisos." #: editor/editor_spin_slider.cpp scene/gui/button.cpp -#, fuzzy msgid "Flat" -msgstr "Plano 0" +msgstr "Plano" #: editor/editor_spin_slider.cpp -#, fuzzy msgid "Hide Slider" -msgstr "Modo de Colisión" +msgstr "Ocultar Deslizador" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" @@ -6941,9 +6920,8 @@ msgid "Use Ambient" msgstr "" #: editor/import/resource_importer_bitmask.cpp -#, fuzzy msgid "Create From" -msgstr "Crear Carpeta" +msgstr "Crear Desde" #: editor/import/resource_importer_bitmask.cpp #: servers/audio/effects/audio_effect_compressor.cpp @@ -6963,9 +6941,8 @@ msgid "Delimiter" msgstr "Delimitador" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "ColorCorrect" -msgstr "Corrección del Color" +msgstr "Corrección de Color" #: editor/import/resource_importer_layered_texture.cpp msgid "No BPTC If RGB" @@ -6993,9 +6970,8 @@ msgstr "Filtro" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Mipmaps" -msgstr "Señales" +msgstr "Mipmaps" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp @@ -7026,14 +7002,12 @@ msgid "Vertical" msgstr "Vertical" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Generate Tangents" -msgstr "Generar puntos" +msgstr "Generar Tangentes" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Scale Mesh" -msgstr "Modo de Escalado" +msgstr "Escalar Mesh" #: editor/import/resource_importer_obj.cpp msgid "Offset Mesh" @@ -7041,14 +7015,12 @@ msgstr "Offset de Malla" #: editor/import/resource_importer_obj.cpp #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Octahedral Compression" -msgstr "Compresión" +msgstr "Compresión Octaédrica" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Optimize Mesh Flags" -msgstr "Tamaño de los Indicadores" +msgstr "Optimizar Marcadores de Malla" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" @@ -7092,29 +7064,24 @@ msgstr "Importar como Escenas y Materiales Múltiples" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Nodes" msgstr "Nodos" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Type" -msgstr "Regresar" +msgstr "Tipo de Raíz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Name" -msgstr "Nombre Remoto" +msgstr "Nombre de Raíz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Scale" -msgstr "Escala" +msgstr "Escala de Raíz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Custom Script" -msgstr "CustomNode" +msgstr "Script Personalizado" #: editor/import/resource_importer_scene.cpp scene/resources/texture.cpp msgid "Storage" @@ -7129,62 +7096,52 @@ msgid "Materials" msgstr "Materiales" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Keep On Reimport" -msgstr "Reimportar" +msgstr "Seguir Reimportando" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp -#, fuzzy msgid "Meshes" -msgstr "Malla" +msgstr "Meshes" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Ensure Tangents" -msgstr "Modificar Tangente de Curva" +msgstr "Asegurar Tangentes" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Light Baking" -msgstr "Lightmapping" +msgstr "Bake de Luces" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Lightmap Texel Size" -msgstr "Calcular Lightmaps" +msgstr "Tamaño Lightmap Texel" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp msgid "Skins" msgstr "" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Use Named Skins" -msgstr "Usar Ajuste de Escalado" +msgstr "Usar Skins con Nombre" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "External Files" -msgstr "Abrir un Archivo" +msgstr "Archivos Externos" #: editor/import/resource_importer_scene.cpp msgid "Store In Subdir" msgstr "" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Filter Script" -msgstr "Filtrar scripts" +msgstr "Filtrar Script" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Keep Custom Tracks" -msgstr "Transformar" +msgstr "Mantener Pistas Personalizadas" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Optimizer" -msgstr "Optimizar" +msgstr "Optimizador" #: editor/import/resource_importer_scene.cpp #: editor/plugins/item_list_editor_plugin.cpp main/main.cpp @@ -7198,9 +7155,8 @@ msgstr "Optimizar" #: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp #: scene/gui/rich_text_label.cpp scene/resources/curve.cpp #: scene/resources/environment.cpp scene/resources/material.cpp -#, fuzzy msgid "Enabled" -msgstr "Activar" +msgstr "Activado" #: editor/import/resource_importer_scene.cpp msgid "Max Linear Error" @@ -7211,19 +7167,16 @@ msgid "Max Angular Error" msgstr "Error Angular Máximo" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Max Angle" -msgstr "Valor" +msgstr "Ángulo Máximo" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Remove Unused Tracks" -msgstr "Eliminar Pista de Animación" +msgstr "Eliminar Pistas Sin Usar" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Clips" -msgstr "Clips de Animación" +msgstr "Clips" #: editor/import/resource_importer_scene.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/particles_2d.cpp scene/3d/area.cpp scene/3d/cpu_particles.cpp @@ -7290,18 +7243,16 @@ msgid "2D, Detect 3D" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "2D Pixel" -msgstr "Pixeles Sólidos" +msgstr "Pixel 2D" #: editor/import/resource_importer_texture.cpp scene/resources/texture.cpp msgid "Lossy Quality" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "HDR Mode" -msgstr "Modo de Selección" +msgstr "Modo HDR" #: editor/import/resource_importer_texture.cpp msgid "BPTC LDR" @@ -7315,45 +7266,40 @@ msgid "Normal Map" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Process" -msgstr "Post procesado" +msgstr "Proceso" #: editor/import/resource_importer_texture.cpp msgid "Fix Alpha Border" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Premult Alpha" -msgstr "Editar Polígono" +msgstr "Premult Alpha" #: editor/import/resource_importer_texture.cpp msgid "Hdr As Srgb" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Invert Color" -msgstr "Vértice" +msgstr "Invertir Color" #: editor/import/resource_importer_texture.cpp msgid "Normal Map Invert Y" msgstr "Invertir Y en Mapa Normal" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Size Limit" -msgstr "Límites" +msgstr "Tamaño Límite" #: editor/import/resource_importer_texture.cpp msgid "Detect 3D" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "SVG" -msgstr "HSV" +msgstr "SVG" #: editor/import/resource_importer_texture.cpp msgid "" @@ -7370,18 +7316,16 @@ msgid "Import Mode" msgstr "Modo de Importación" #: editor/import/resource_importer_texture_atlas.cpp -#, fuzzy msgid "Crop To Region" -msgstr "Establecer Región de Tile" +msgstr "Recortar la Región" #: editor/import/resource_importer_texture_atlas.cpp msgid "Trim Alpha Border From Region" msgstr "" #: editor/import/resource_importer_wav.cpp scene/2d/physics_body_2d.cpp -#, fuzzy msgid "Force" -msgstr "Forzar Push" +msgstr "Fuerza" #: editor/import/resource_importer_wav.cpp msgid "8 Bit" @@ -7393,41 +7337,35 @@ msgid "Mono" msgstr "" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Max Rate" -msgstr "Nodo Mix" +msgstr "Tasa Máxima" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Max Rate Hz" -msgstr "Nodo Mix" +msgstr "Tasa Máxima Hz" #: editor/import/resource_importer_wav.cpp msgid "Trim" msgstr "" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Normalize" -msgstr "Formato" +msgstr "Normalizar" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop Mode" -msgstr "Modo de Movimiento" +msgstr "Modo Bucle" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop Begin" -msgstr "Modo de Movimiento" +msgstr "Inicio del Bucle" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop End" -msgstr "Modo de Movimiento" +msgstr "Fin del Bucle" #: editor/import_defaults_editor.cpp msgid "Select Importer" @@ -7514,14 +7452,12 @@ msgid "Raw" msgstr "Raw" #: editor/inspector_dock.cpp -#, fuzzy msgid "Capitalized" -msgstr "Capitalizar" +msgstr "Capitalización" #: editor/inspector_dock.cpp -#, fuzzy msgid "Localized" -msgstr "Idioma" +msgstr "Localizado" #: editor/inspector_dock.cpp msgid "Localization not available for current language." @@ -8075,9 +8011,8 @@ msgid "New" msgstr "Nuevo" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Paste As Reference" -msgstr "%s Referencia de Clase" +msgstr "Pegar Como Referencia" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Transitions..." @@ -8569,25 +8504,21 @@ msgid "Loading..." msgstr "Cargar..." #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "First" msgstr "Primero" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Previous" msgstr "Anterior" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Next" msgstr "Siguiente" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Last" msgstr "Último" @@ -9206,9 +9137,8 @@ msgid "View" msgstr "Ver" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Show" -msgstr "Ver Cuadrícula" +msgstr "Mostrar" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show When Snapping" @@ -9216,12 +9146,11 @@ msgstr "Mostrar Al Ajustar" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Hide" -msgstr "" +msgstr "Ocultar" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Toggle Grid" -msgstr "Cambiar Modo" +msgstr "Cambiar Cuadrícula" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -9843,7 +9772,6 @@ msgstr "" "%s" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "MeshLibrary" msgstr "Librería de Mallas" @@ -9868,14 +9796,12 @@ msgid "Update from Scene" msgstr "Actualizar desde escena" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Apply without Transforms" -msgstr "Aplicar Transformaciones al MeshInstance" +msgstr "Aplicar sin Transformaciones" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Apply with Transforms" -msgstr "Aplicar Transformaciones al MeshInstance" +msgstr "Aplicar con Transformaciones" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." @@ -10223,7 +10149,7 @@ msgid "" "viewport." msgstr "" "El polígono 2D tiene vértices internos, por lo que ya no se puede editar en " -"la ventanilla." +"el viewport." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create Polygon & UV" @@ -10744,19 +10670,16 @@ msgid "External" msgstr "" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Use External Editor" -msgstr "Depurar con Editor Externo" +msgstr "Usar un Editor Externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Exec Path" -msgstr "Ruta de Exportación" +msgstr "Ruta de Ejecución" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Script Temperature Enabled" -msgstr "Seleccionar el archivo de la plantilla" +msgstr "Temperatura del Script Activada" #: editor/plugins/script_editor_plugin.cpp msgid "Highlight Current Script" @@ -10771,14 +10694,12 @@ msgid "Current Script Background Color" msgstr "Color de Fondo del Script Actual" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Group Help Pages" -msgstr "Agrupar Seleccionados" +msgstr "Páginas de Ayuda para Grupos" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Sort Scripts By" -msgstr "Crear Script" +msgstr "Ordenar Scripts por" #: editor/plugins/script_editor_plugin.cpp msgid "List Script Names As" @@ -10995,8 +10916,8 @@ msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"Este shader ha sido modificado en disco.\n" -"¿Qué acciones deben tomarse?" +"Este shader ha sido modificado en el disco.\n" +"¿Qué acción debe tomarse?" #: editor/plugins/shader_editor_plugin.cpp scene/resources/material.cpp msgid "Shader" @@ -11494,27 +11415,27 @@ msgstr "Dialogo de Transformación..." #: editor/plugins/spatial_editor_plugin.cpp msgid "1 Viewport" -msgstr "1 Ventana" +msgstr "1 Viewport" #: editor/plugins/spatial_editor_plugin.cpp msgid "2 Viewports" -msgstr "2 Ventanas" +msgstr "2 Viewports" #: editor/plugins/spatial_editor_plugin.cpp msgid "2 Viewports (Alt)" -msgstr "2 Ventanas (Alt)" +msgstr "2 Viewports (Alt)" #: editor/plugins/spatial_editor_plugin.cpp msgid "3 Viewports" -msgstr "3 Ventanas" +msgstr "3 Viewports" #: editor/plugins/spatial_editor_plugin.cpp msgid "3 Viewports (Alt)" -msgstr "3 Ventanas (Alt)" +msgstr "3 Viewports (Alt)" #: editor/plugins/spatial_editor_plugin.cpp msgid "4 Viewports" -msgstr "4 Ventanas" +msgstr "4 Viewports" #: editor/plugins/spatial_editor_plugin.cpp msgid "Gizmos" @@ -11559,7 +11480,7 @@ msgstr "Ajuste de Escala (%):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Viewport Settings" -msgstr "Configuración de ventanilla" +msgstr "Configuración del Viewport" #: editor/plugins/spatial_editor_plugin.cpp msgid "Perspective FOV (deg.):" @@ -11610,9 +11531,8 @@ msgid "Manipulator Gizmo Opacity" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Show Viewport Rotation Gizmo" -msgstr "Bloquear Rotación de Vista" +msgstr "Mostrar Gizmo de Rotación del Viewport" #: editor/plugins/spatial_editor_plugin.cpp msgid "Unnamed Gizmo" @@ -11664,9 +11584,8 @@ msgid "Invalid geometry, can't replace by mesh." msgstr "Geometría inválida, no puede ser reemplazada por una malla." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to MeshInstance2D" -msgstr "Convertir a Mesh2D" +msgstr "Convertir a MeshInstance2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." @@ -11769,6 +11688,10 @@ msgid "New Animation" msgstr "Nueva Animación" #: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Filter animations" +msgstr "Filtrar animaciones" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocidad:" @@ -12066,9 +11989,8 @@ msgstr "" "¿Cerrar de todos modos?" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove Type" -msgstr "Eliminar Tile" +msgstr "Eliminar Tipo" #: editor/plugins/theme_editor_plugin.cpp msgid "" @@ -12112,14 +12034,12 @@ msgstr "" "Añade más propiedades manualmente o impórtalas desde otro Theme." #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Add Theme Type" -msgstr "Añadir Tipo de Elemento" +msgstr "Añadir Tipo de Theme" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove Theme Type" -msgstr "Eliminar Remoto" +msgstr "Eliminar Tipo de Theme" #: editor/plugins/theme_editor_plugin.cpp msgid "Add Color Item" @@ -12566,55 +12486,46 @@ msgid "Clear Transform" msgstr "Reestablecer Transformación" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Tile Map" -msgstr "Dibujar TileMap" +msgstr "Mapa de Tiles" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Palette Min Width" -msgstr "" +msgstr "Ancho Mínimo de la Paleta" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Palette Item H Separation" -msgstr "Separador con nombre" +msgstr "Separación del Elemento H de la Paleta" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Show Tile Names" -msgstr "Mostrar Todos los Idiomas" +msgstr "Mostrar Nombres de Tiles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Show Tile Ids" -msgstr "Mostrar Reglas" +msgstr "Mostrar ID de los Tiles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Sort Tiles By Name" -msgstr "Ordenar archivos" +msgstr "Ordenar Tiles por Nombre" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Bucket Fill Preview" -msgstr "Bote de Relleno" +msgstr "Vista previa del Bote de Relleno" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Editor Side" -msgstr "Editor" +msgstr "Lado del Editor" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Display Grid" -msgstr "Mostrar Overdraw" +msgstr "Mostrar Cuadrícula" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Axis Color" -msgstr "Seleccionar Color" +msgstr "Color de los Ejes" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Add Texture(s) to TileSet." @@ -12953,7 +12864,6 @@ msgid "This property can't be changed." msgstr "Esta propiedad no se puede cambiar." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Snap Options" msgstr "Opciones de Ajuste" @@ -12982,9 +12892,8 @@ msgid "Separation" msgstr "Separación" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Tile" -msgstr "Seleccionar" +msgstr "Tiles Seleccionados" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/light_2d.cpp scene/2d/line_2d.cpp scene/2d/mesh_instance_2d.cpp @@ -12993,14 +12902,12 @@ msgstr "Seleccionar" #: scene/gui/nine_patch_rect.cpp scene/gui/texture_rect.cpp #: scene/resources/material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Texture" -msgstr "Texto" +msgstr "Textura" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tex Offset" -msgstr "Desplazamiento de Byte" +msgstr "Desplazamiento de Textura" #: editor/plugins/tile_set_editor_plugin.cpp modules/csg/csg_shape.cpp #: scene/2d/canvas_item.cpp scene/2d/particles_2d.cpp @@ -13010,79 +12917,64 @@ msgstr "Material" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/canvas_item.cpp #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Modulate" -msgstr "Rellenar" +msgstr "Modular" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tile Mode" -msgstr "Cambiar Modo" +msgstr "Modo Tile" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Autotile Bitmask Mode" -msgstr "Modo de Bitmask" +msgstr "Modo Bitmask Automático" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Size" -msgstr "Tamaño del Contorno" +msgstr "Tamaño de Subtile" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Spacing" -msgstr "Espaciado de Línea" +msgstr "Espaciado de Subtile" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occluder Offset" -msgstr "Crear Polígono Oclusor" +msgstr "Desplazamiento del Oclusor" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Offset" -msgstr "Modo de Navegación" +msgstr "Desplazamiento de Navegación" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Shape Offset" -msgstr "Desplazamiento Base" +msgstr "Desplazamiento del Shape" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Shape Transform" -msgstr "Transformar" +msgstr "Transformar Shape" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision" -msgstr "Colisión" +msgstr "Colisión Seleccionada" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision One Way" -msgstr "Sólo selección" +msgstr "Colisión Seleccionada en Una Dirección" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision One Way Margin" -msgstr "Modo de Colisión" +msgstr "Margen Seleccionado de Colisión en Una Dirección" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Navigation" -msgstr "Navegación Visible" +msgstr "Navegación Seleccionada" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Occlusion" -msgstr "Seleccionar" +msgstr "Oclusión Seleccionada" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tileset Script" -msgstr "Filtrar scripts" +msgstr "Script de Tileset" #: editor/plugins/tile_set_editor_plugin.cpp msgid "TileSet" @@ -14293,9 +14185,8 @@ msgid "" msgstr "" #: editor/project_export.cpp -#, fuzzy msgid "More Info..." -msgstr "Mover a..." +msgstr "Más información..." #: editor/project_export.cpp msgid "Export PCK/Zip..." @@ -14322,18 +14213,16 @@ msgid "ZIP File" msgstr "Archivo ZIP" #: editor/project_export.cpp -#, fuzzy msgid "Godot Project Pack" -msgstr "Godot Game Pack" +msgstr "Paquete de Proyectos de Godot" #: editor/project_export.cpp msgid "Export templates for this platform are missing:" msgstr "Faltan plantillas de exportación para esta plataforma:" #: editor/project_export.cpp -#, fuzzy msgid "Project Export" -msgstr "Fundadores del Proyecto" +msgstr "Exportación del Proyecto" #: editor/project_export.cpp msgid "Manage Export Templates" @@ -14648,7 +14537,6 @@ msgstr "" #. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp -#, fuzzy msgctxt "Application" msgid "Project Manager" msgstr "Administrador de Proyectos" @@ -15456,14 +15344,12 @@ msgid "Another node already uses this unique name in the scene." msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Enable Scene Unique Name" -msgstr "Nombre Único" +msgstr "Activar Nombre Único de Escena" #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -#, fuzzy msgid "Disable Scene Unique Name" -msgstr "Nombre Único" +msgstr "Desactivar Nombre Único de Escena" #: editor/scene_tree_dock.cpp msgid "New Scene Root" @@ -15638,18 +15524,16 @@ msgid "Clear Inheritance? (No Undo!)" msgstr "¿Quieres limpiar la herencia? (No se puede deshacer)" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Show Scene Tree Root Selection" -msgstr "Centrar Selección" +msgstr "Mostrar Selección de la Raíz del Árbol de Escenas" #: editor/scene_tree_dock.cpp msgid "Derive Script Globals By Name" msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Use Favorites Root Selection" -msgstr "Seleccionar Fotogramas" +msgstr "Usar Selección de Raíces Favoritas" #: editor/scene_tree_editor.cpp msgid "Toggle Visible" @@ -16108,23 +15992,20 @@ msgid "Change Particles AABB" msgstr "Cambiar partículas AABB" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Reflection Probe" -msgstr "Seleccionar Propiedad" +msgstr "Sonda de Reflexión" #: editor/spatial_editor_gizmos.cpp msgid "Change Probe Extents" msgstr "Cambiar Alcance de la Sonda" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "GI Probe" -msgstr "Calcular GI Probe" +msgstr "Sonda GI" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Baked Indirect Light" -msgstr "Iluminación indirecta" +msgstr "Iluminación Indirecta Bakeada" #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp msgid "Change Sphere Shape Radius" @@ -16155,24 +16036,20 @@ msgid "Change Ray Shape Length" msgstr "Cambiar Longitud de la Forma del Rayo" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Edge" -msgstr "Modo de Navegación" +msgstr "Borde de Navegación" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Edge Disabled" -msgstr "Modo de Navegación" +msgstr "Borde de Navegación Desactivado" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Solid" -msgstr "Modo de Navegación" +msgstr "Navegación Sólida" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Solid Disabled" -msgstr "Modo de Navegación" +msgstr "Navegación Sólida Desactivada" #: editor/spatial_editor_gizmos.cpp msgid "Joint Body A" @@ -16195,9 +16072,8 @@ msgid "Set Room Point Position" msgstr "Establecer Posición del Room Point" #: editor/spatial_editor_gizmos.cpp scene/3d/portal.cpp -#, fuzzy msgid "Portal Margin" -msgstr "Asignar Margen" +msgstr "Margen del Portal" #: editor/spatial_editor_gizmos.cpp msgid "Portal Edge" @@ -16216,15 +16092,13 @@ msgid "Portal Front" msgstr "" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Portal Back" -msgstr "Retroceder" +msgstr "Portal de Regreso" #: editor/spatial_editor_gizmos.cpp scene/2d/light_occluder_2d.cpp #: scene/2d/tile_map.cpp -#, fuzzy msgid "Occluder" -msgstr "Modo de Oclusión" +msgstr "Oclusor" #: editor/spatial_editor_gizmos.cpp msgid "Set Occluder Sphere Radius" @@ -16243,19 +16117,16 @@ msgid "Set Occluder Hole Point Position" msgstr "Establecer posición del orificio del oclusor" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Polygon Front" -msgstr "Crear Polígono Oclusor" +msgstr "Frente del Polígono Oclusor" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Polygon Back" -msgstr "Crear Polígono Oclusor" +msgstr "Posterior del Polígono Oclusor" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Hole" -msgstr "Crear Polígono Oclusor" +msgstr "Orificio Oclusor" #: main/main.cpp msgid "Godot Physics" @@ -16264,32 +16135,28 @@ msgstr "" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp msgid "Use BVH" -msgstr "" +msgstr "Usar BVH" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp -#, fuzzy msgid "BVH Collision Margin" -msgstr "Modo de Colisión" +msgstr "Margen de Colisión BVH" #: main/main.cpp -#, fuzzy msgid "Crash Handler" -msgstr "Establecer Manipulador" +msgstr "Manipulador de Colisiones" #: main/main.cpp -#, fuzzy msgid "Multithreaded Server" -msgstr "Establecer multinodo" +msgstr "Servidor Multihilo" #: main/main.cpp msgid "RID Pool Prealloc" msgstr "" #: main/main.cpp -#, fuzzy msgid "Debugger stdout" -msgstr "Depurador" +msgstr "Depurador stdout" #: main/main.cpp msgid "Max Chars Per Second" @@ -16320,14 +16187,12 @@ msgid "File Logging" msgstr "" #: main/main.cpp -#, fuzzy msgid "Enable File Logging" -msgstr "Habilitar Filtrado" +msgstr "Activar Registro de Archivos" #: main/main.cpp -#, fuzzy msgid "Log Path" -msgstr "Copiar Ruta" +msgstr "Ruta del Registro" #: main/main.cpp msgid "Max Log Files" @@ -16358,14 +16223,12 @@ msgid "Allow hiDPI" msgstr "" #: main/main.cpp -#, fuzzy msgid "V-Sync" -msgstr "Sincronizar" +msgstr "Sincronización Vertical" #: main/main.cpp -#, fuzzy msgid "Use V-Sync" -msgstr "Usar Snap" +msgstr "Usar Sincronización Vertical" #: main/main.cpp msgid "Per Pixel Transparency" @@ -16380,23 +16243,20 @@ msgid "Intended Usage" msgstr "" #: main/main.cpp -#, fuzzy msgid "Framebuffer Allocation" -msgstr "Seleccionar Fotogramas" +msgstr "Asignación del Buffer de Imágenes" #: main/main.cpp platform/uwp/os_uwp.cpp -#, fuzzy msgid "Energy Saving" -msgstr "Error al Guardar" +msgstr "Ahorro de Energía" #: main/main.cpp msgid "Threads" msgstr "" #: main/main.cpp servers/physics_2d/physics_2d_server_wrap_mt.h -#, fuzzy msgid "Thread Model" -msgstr "Cambiar Modo" +msgstr "Modelo de Hilo" #: main/main.cpp msgid "Thread Safe BVH" @@ -16408,25 +16268,21 @@ msgstr "" #: main/main.cpp platform/javascript/export/export.cpp #: platform/uwp/export/export.cpp -#, fuzzy msgid "Orientation" -msgstr "Documentación en línea" +msgstr "Orientación" #: main/main.cpp scene/gui/scroll_container.cpp scene/gui/text_edit.cpp #: scene/main/scene_tree.cpp scene/register_scene_types.cpp -#, fuzzy msgid "Common" -msgstr "Comunidad" +msgstr "Común" #: main/main.cpp -#, fuzzy msgid "Physics FPS" -msgstr "Fotogramas de Física %" +msgstr "Física FPS" #: main/main.cpp -#, fuzzy msgid "Force FPS" -msgstr "Forzar Push" +msgstr "Forzar FPS" #: main/main.cpp msgid "Enable Pause Aware Picking" @@ -16455,19 +16311,16 @@ msgid "Verbose stdout" msgstr "" #: main/main.cpp scene/main/scene_tree.cpp scene/resources/multimesh.cpp -#, fuzzy msgid "Physics Interpolation" -msgstr "Modo de Interpolación" +msgstr "Interpolación de Física" #: main/main.cpp -#, fuzzy msgid "Enable Warnings" -msgstr "Habilitar Filtrado" +msgstr "Activar Advertencias" #: main/main.cpp -#, fuzzy msgid "Frame Delay Msec" -msgstr "Seleccionar Fotogramas" +msgstr "Retraso de los Fotogramas Msec" #: main/main.cpp msgid "Low Processor Mode" @@ -16486,14 +16339,12 @@ msgid "Hide Home Indicator" msgstr "" #: main/main.cpp -#, fuzzy msgid "Input Devices" -msgstr "Todos los Dispositivos" +msgstr "Dispositivos de Entrada" #: main/main.cpp -#, fuzzy msgid "Pointing" -msgstr "Punto" +msgstr "Apuntador" #: main/main.cpp msgid "Touch Delay" @@ -16504,21 +16355,18 @@ msgid "GLES3" msgstr "" #: main/main.cpp servers/visual_server.cpp -#, fuzzy msgid "Shaders" -msgstr "Shader" +msgstr "Shaders" #: main/main.cpp -#, fuzzy msgid "Debug Shader Fallbacks" -msgstr "Forzar Shader Fallbacks" +msgstr "Depurar Fallbacks de Shader" #: main/main.cpp scene/3d/baked_lightmap.cpp scene/3d/camera.cpp #: scene/3d/world_environment.cpp scene/main/scene_tree.cpp #: scene/resources/world.cpp -#, fuzzy msgid "Environment" -msgstr "Ver Entorno" +msgstr "Entorno" #: main/main.cpp msgid "Default Clear Color" @@ -16529,9 +16377,8 @@ msgid "Boot Splash" msgstr "" #: main/main.cpp -#, fuzzy msgid "Show Image" -msgstr "Mostrar Huesos" +msgstr "Mostrar Imagen" #: main/main.cpp msgid "Image" @@ -16546,14 +16393,12 @@ msgid "Use Filter" msgstr "Usar Filtro" #: main/main.cpp scene/resources/style_box.cpp -#, fuzzy msgid "BG Color" -msgstr "Colores" +msgstr "Color de Fondo" #: main/main.cpp -#, fuzzy msgid "macOS Native Icon" -msgstr "Establecer Icono de Tile" +msgstr "Icono Nativo de macOS" #: main/main.cpp msgid "Windows Native Icon" @@ -16576,14 +16421,12 @@ msgid "Emulate Mouse From Touch" msgstr "" #: main/main.cpp -#, fuzzy msgid "Mouse Cursor" -msgstr "Botón del Mouse" +msgstr "Cursor del Mouse" #: main/main.cpp -#, fuzzy msgid "Custom Image" -msgstr "CustomNode" +msgstr "Imagen Personalizada" #: main/main.cpp msgid "Custom Image Hotspot" @@ -16591,17 +16434,15 @@ msgstr "" #: main/main.cpp msgid "Tooltip Position Offset" -msgstr "Offset de la Posición del Tooltip" +msgstr "Desplazamiento de Posición del Tooltip" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp -#, fuzzy msgid "Debugger Agent" -msgstr "Depurador" +msgstr "Agente de Depuración" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp -#, fuzzy msgid "Wait For Debugger" -msgstr "Depurador" +msgstr "Esperar al Depurador" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp msgid "Wait Timeout" @@ -16616,20 +16457,17 @@ msgid "Unhandled Exception Policy" msgstr "" #: main/main.cpp -#, fuzzy msgid "Main Loop Type" -msgstr "Buscar Tipo de Nodo" +msgstr "Tipo de Bucle Principal" #: main/main.cpp scene/gui/texture_progress.cpp #: scene/gui/viewport_container.cpp -#, fuzzy msgid "Stretch" -msgstr "Buscar" +msgstr "Estirar" #: main/main.cpp -#, fuzzy msgid "Aspect" -msgstr "Inspector" +msgstr "Aspecto" #: main/main.cpp msgid "Shrink" @@ -16640,14 +16478,12 @@ msgid "Auto Accept Quit" msgstr "" #: main/main.cpp scene/main/scene_tree.cpp -#, fuzzy msgid "Quit On Go Back" -msgstr "Retroceder" +msgstr "Salir y Regresar" #: main/main.cpp scene/main/viewport.cpp -#, fuzzy msgid "Snap Controls To Pixels" -msgstr "Ajustar a los Lados del Nodo" +msgstr "Ajustar Controles a Píxeles" #: main/main.cpp msgid "Dynamic Fonts" @@ -16682,35 +16518,30 @@ msgid "Change Torus Outer Radius" msgstr "Cambiar Radio Externo de Torus" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Operation" -msgstr "Opciones" +msgstr "Operación" #: modules/csg/csg_shape.cpp msgid "Calculate Tangents" msgstr "" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Use Collision" -msgstr "Colisión" +msgstr "Usar Colisión" #: modules/csg/csg_shape.cpp servers/physics_2d_server.cpp -#, fuzzy msgid "Collision Layer" -msgstr "Modo de Colisión" +msgstr "Capa de Colisión" #: modules/csg/csg_shape.cpp scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp #: scene/3d/ray_cast.cpp scene/3d/spring_arm.cpp #: scene/resources/navigation_mesh.cpp servers/physics_server.cpp -#, fuzzy msgid "Collision Mask" -msgstr "Modo de Colisión" +msgstr "Máscara de Colisión" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Invert Faces" -msgstr "Convertir Mayúsculas/Minúsculas" +msgstr "Invertir Caras" #: modules/csg/csg_shape.cpp scene/2d/navigation_agent_2d.cpp #: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_agent.cpp @@ -16728,33 +16559,28 @@ msgid "Radial Segments" msgstr "Segmentos Radiales" #: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Rings" -msgstr "Advertencias" +msgstr "Anillos" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Smooth Faces" -msgstr "Suavizado" +msgstr "Caras Suaves" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Sides" -msgstr "Mostrar Guías" +msgstr "Lados" #: modules/csg/csg_shape.cpp msgid "Cone" msgstr "" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Inner Radius" -msgstr "Cambiar Radio Interno de Torus" +msgstr "Radio Interior" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Outer Radius" -msgstr "Cambiar Radio Externo de Torus" +msgstr "Radio Exterior" #: modules/csg/csg_shape.cpp msgid "Ring Sides" @@ -16763,9 +16589,8 @@ msgstr "" #: modules/csg/csg_shape.cpp scene/2d/collision_polygon_2d.cpp #: scene/2d/light_occluder_2d.cpp scene/2d/polygon_2d.cpp #: scene/3d/collision_polygon.cpp -#, fuzzy msgid "Polygon" -msgstr "Polígonos" +msgstr "Polígono" #: modules/csg/csg_shape.cpp msgid "Spin Degrees" @@ -16776,14 +16601,12 @@ msgid "Spin Sides" msgstr "" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Node" -msgstr "Pegar Nodos" +msgstr "Ruta del Nodo" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Interval Type" -msgstr "Crear Vértice Interno" +msgstr "Tipo de Intervalo de Ruta" #: modules/csg/csg_shape.cpp msgid "Path Interval" @@ -16798,14 +16621,12 @@ msgid "Path Rotation" msgstr "Rotación de Trayectoria" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Local" -msgstr "Crear Local" +msgstr "Ruta Local" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Continuous U" -msgstr "Continuo" +msgstr "Ruta Continua U" #: modules/csg/csg_shape.cpp msgid "Path U Distance" @@ -16816,24 +16637,20 @@ msgid "Path Joined" msgstr "Ruta Unida" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Compression Mode" -msgstr "Modo de Colisión" +msgstr "Modo de Compresión" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Transfer Channel" -msgstr "Cambio de Transformación" +msgstr "Canal de Transferencia" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Channel Count" -msgstr "Instanciar" +msgstr "Conteo de Canales" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Always Ordered" -msgstr "Mostrar Siempre la Cuadrícula" +msgstr "Siempre Ordenado" #: modules/enet/networked_multiplayer_enet.cpp msgid "Server Relay" @@ -16848,9 +16665,8 @@ msgid "DTLS Hostname" msgstr "" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Use DTLS" -msgstr "Usar Snap" +msgstr "Usar DTLS" #: modules/fbx/editor_scene_importer_fbx.cpp msgid "FBX" @@ -16865,24 +16681,21 @@ msgid "Config File" msgstr "Archivo de Configuración" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Load Once" -msgstr "Cargar Recurso" +msgstr "Cargar Una Vez" #: modules/gdnative/gdnative.cpp #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Singleton" -msgstr "Esqueleto" +msgstr "Singleton" #: modules/gdnative/gdnative.cpp msgid "Symbol Prefix" msgstr "Prefijo de Símbolo" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Reloadable" -msgstr "Recargar" +msgstr "Recargable" #: modules/gdnative/gdnative.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp @@ -16947,9 +16760,8 @@ msgid "Script Class" msgstr "Clase del Script" #: modules/gdnative/nativescript/nativescript.cpp -#, fuzzy msgid "Icon Path" -msgstr "Foco en Ruta" +msgstr "Ruta del Icono" #: modules/gdnative/register_types.cpp msgid "GDNative" @@ -16957,18 +16769,16 @@ msgstr "GDNative" #: modules/gdscript/editor/gdscript_highlighter.cpp #: modules/gdscript/gdscript.cpp -#, fuzzy msgid "GDScript" -msgstr "Script" +msgstr "GDScript" #: modules/gdscript/editor/gdscript_highlighter.cpp msgid "Function Definition Color" msgstr "" #: modules/gdscript/editor/gdscript_highlighter.cpp -#, fuzzy msgid "Node Path Color" -msgstr "Copiar Ruta del Nodo" +msgstr "Color de la Ruta del Nodo" #: modules/gdscript/gdscript.cpp modules/visual_script/visual_script.cpp msgid "Max Call Stack" @@ -17031,9 +16841,8 @@ msgid "Language Server" msgstr "Servidor de Lenguaje" #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Enable Smart Resolve" -msgstr "No se puede resolver" +msgstr "Activar Smart Resolve" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Show Native Symbols In Editor" @@ -17052,42 +16861,36 @@ msgid "Export GLTF..." msgstr "Exportar GLTF..." #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Buffer View" -msgstr "Vista Trasera" +msgstr "Vista del Buffer" #: modules/gltf/gltf_accessor.cpp modules/gltf/gltf_buffer_view.cpp msgid "Byte Offset" msgstr "Desplazamiento de Byte" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Component Type" -msgstr "Componentes" +msgstr "Tipo de Componente" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Normalized" -msgstr "Formato" +msgstr "Normalizado" #: modules/gltf/gltf_accessor.cpp msgid "Count" msgstr "Cuenta" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Min" -msgstr "MiB" +msgstr "Min" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Max" -msgstr "Mix" +msgstr "Max" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Sparse Count" -msgstr "Instanciar" +msgstr "Recuento Parcial" #: modules/gltf/gltf_accessor.cpp msgid "Sparse Indices Buffer View" @@ -17110,23 +16913,20 @@ msgid "Sparse Values Byte Offset" msgstr "" #: modules/gltf/gltf_buffer_view.cpp -#, fuzzy msgid "Buffer" -msgstr "Vista Trasera" +msgstr "Buffer" #: modules/gltf/gltf_buffer_view.cpp -#, fuzzy msgid "Byte Length" -msgstr "Theme Predeterminado" +msgstr "Longitud de Bytes" #: modules/gltf/gltf_buffer_view.cpp msgid "Byte Stride" msgstr "" #: modules/gltf/gltf_buffer_view.cpp -#, fuzzy msgid "Indices" -msgstr "Todos los Dispositivos" +msgstr "Índices" #: modules/gltf/gltf_camera.cpp msgid "FOV Size" @@ -17137,9 +16937,8 @@ msgid "Zfar" msgstr "" #: modules/gltf/gltf_camera.cpp -#, fuzzy msgid "Znear" -msgstr "Lineal" +msgstr "Znear" #: modules/gltf/gltf_light.cpp scene/2d/canvas_modulate.cpp #: scene/2d/cpu_particles_2d.cpp scene/2d/light_2d.cpp scene/2d/polygon_2d.cpp @@ -17149,9 +16948,8 @@ msgstr "Lineal" #: scene/resources/environment.cpp scene/resources/material.cpp #: scene/resources/particles_material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp -#, fuzzy msgid "Color" -msgstr "Colores" +msgstr "Color" #: modules/gltf/gltf_light.cpp scene/3d/reflection_probe.cpp #: scene/resources/environment.cpp @@ -17159,9 +16957,8 @@ msgid "Intensity" msgstr "" #: modules/gltf/gltf_light.cpp scene/2d/light_2d.cpp scene/3d/light.cpp -#, fuzzy msgid "Range" -msgstr "Cambiar" +msgstr "Rango" #: modules/gltf/gltf_light.cpp msgid "Inner Cone Angle" @@ -17172,42 +16969,36 @@ msgid "Outer Cone Angle" msgstr "" #: modules/gltf/gltf_mesh.cpp -#, fuzzy msgid "Blend Weights" -msgstr "Calcular Lightmaps" +msgstr "Mezcla de Pesos" #: modules/gltf/gltf_mesh.cpp msgid "Instance Materials" msgstr "Materiales de Instancia" #: modules/gltf/gltf_node.cpp scene/3d/skeleton.cpp -#, fuzzy msgid "Parent" -msgstr "Reemparentar" +msgstr "Padre" #: modules/gltf/gltf_node.cpp -#, fuzzy msgid "Xform" -msgstr "Plataforma" +msgstr "Xform" #: modules/gltf/gltf_node.cpp scene/3d/mesh_instance.cpp msgid "Skin" msgstr "" #: modules/gltf/gltf_node.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Translation" -msgstr "Traducciones" +msgstr "Traducción" #: modules/gltf/gltf_node.cpp -#, fuzzy msgid "Children" -msgstr "Hijos Editables" +msgstr "Hijos" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints" -msgstr "Punto" +msgstr "Articulaciones" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp msgid "Roots" @@ -17218,28 +17009,24 @@ msgid "Unique Names" msgstr "" #: modules/gltf/gltf_skeleton.cpp -#, fuzzy msgid "Godot Bone Node" -msgstr "Obtener Nodo de Escena" +msgstr "Nodo de Huesos de Godot" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Skin Root" -msgstr "Nueva Raíz de Escena" +msgstr "Raíz de la Skin" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints Original" -msgstr "Foco en Origen" +msgstr "Articulaciones Originales" #: modules/gltf/gltf_skin.cpp msgid "Inverse Binds" msgstr "" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Non Joints" -msgstr "Mover Unión" +msgstr "Sin Articulaciones" #: modules/gltf/gltf_skin.cpp msgid "Joint I To Bone I" @@ -17278,28 +17065,24 @@ msgid "Json" msgstr "" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Major Version" -msgstr "Versión" +msgstr "Versión Mayor" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Minor Version" -msgstr "Versión" +msgstr "Versión Menor" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "GLB Data" -msgstr "Con Datos" +msgstr "Datos GLB" #: modules/gltf/gltf_state.cpp msgid "Use Named Skin Binds" msgstr "" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Buffer Views" -msgstr "Vista Trasera" +msgstr "Vistas del Buffer" #: modules/gltf/gltf_state.cpp msgid "Accessors" @@ -17310,15 +17093,13 @@ msgid "Scene Name" msgstr "Nombre de la Escena" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Root Nodes" -msgstr "Nombre del nodo raíz" +msgstr "Nodos Raíz" #: modules/gltf/gltf_state.cpp scene/2d/particles_2d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_progress.cpp -#, fuzzy msgid "Textures" -msgstr "Características" +msgstr "Texturas" #: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp msgid "Images" @@ -17329,70 +17110,60 @@ msgid "Cameras" msgstr "" #: modules/gltf/gltf_state.cpp servers/visual_server.cpp -#, fuzzy msgid "Lights" -msgstr "Luz" +msgstr "Luces" #: modules/gltf/gltf_state.cpp msgid "Unique Animation Names" msgstr "Nombres Únicos de Animación" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeletons" -msgstr "Esqueleto" +msgstr "Esqueletos" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeleton To Node" -msgstr "Selecciona un Nodo" +msgstr "Esqueleto a Nodo" #: modules/gltf/gltf_state.cpp msgid "Animations" msgstr "Animaciones" #: modules/gltf/gltf_texture.cpp -#, fuzzy msgid "Src Image" -msgstr "Mostrar Huesos" +msgstr "Imagen de Origen" #: modules/gridmap/grid_map.cpp msgid "Mesh Library" msgstr "Librería de Mallas" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Physics Material" -msgstr "Fotogramas de Física %" +msgstr "Material de Física" #: modules/gridmap/grid_map.cpp scene/3d/visual_instance.cpp -#, fuzzy msgid "Use In Baked Light" -msgstr "Calcular Lightmaps" +msgstr "Uso en Luz Bakeada" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp msgid "Cell" msgstr "" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Octant Size" -msgstr "Vista Frontal" +msgstr "Tamaño del Octante" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center X" -msgstr "Centro" +msgstr "Centro X" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Y" -msgstr "Centro" +msgstr "Centro Y" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Z" -msgstr "Centro" +msgstr "Centro Z" #: modules/gridmap/grid_map.cpp scene/2d/collision_object_2d.cpp #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp @@ -17401,17 +17172,15 @@ msgid "Mask" msgstr "" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp -#, fuzzy msgid "Bake Navigation" -msgstr "Navegación" +msgstr "Bakear Navegación" #: modules/gridmap/grid_map.cpp scene/2d/navigation_2d.cpp #: scene/2d/navigation_agent_2d.cpp scene/2d/navigation_polygon.cpp #: scene/2d/tile_map.cpp scene/3d/navigation.cpp scene/3d/navigation_agent.cpp #: scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Navigation Layers" -msgstr "Modo de Navegación" +msgstr "Capas de Navegación" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Plane" @@ -17571,9 +17340,8 @@ msgid "Plotting lightmaps" msgstr "Trazar lightmaps" #: modules/lightmapper_cpu/register_types.cpp -#, fuzzy msgid "CPU Lightmapper" -msgstr "Calcular Lightmaps" +msgstr "CPU Lightmapper" #: modules/lightmapper_cpu/register_types.cpp msgid "Low Quality Ray Count" @@ -17607,14 +17375,12 @@ msgid "IOD" msgstr "" #: modules/mobile_vr/mobile_vr_interface.cpp -#, fuzzy msgid "Display Width" -msgstr "Mostrar Wireframe" +msgstr "Ancho de Pantalla" #: modules/mobile_vr/mobile_vr_interface.cpp -#, fuzzy msgid "Display To Lens" -msgstr "Mostrar Sin Sombreado" +msgstr "Pantalla a Lente" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Oversample" @@ -17637,9 +17403,8 @@ msgid "Build Solution" msgstr "Crear Solución" #: modules/mono/editor/csharp_project.cpp -#, fuzzy msgid "Auto Update Project" -msgstr "Proyecto Sin Nombre" +msgstr "Actualización Automática del Proyecto" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -17741,9 +17506,8 @@ msgid "Period" msgstr "" #: modules/opensimplex/open_simplex_noise.cpp -#, fuzzy msgid "Persistence" -msgstr "Perspectiva" +msgstr "Persistencia" #: modules/opensimplex/open_simplex_noise.cpp msgid "Lacunarity" @@ -17754,9 +17518,8 @@ msgid "Subject" msgstr "" #: modules/regex/regex.cpp -#, fuzzy msgid "Names" -msgstr "Nombre" +msgstr "Nombres" #: modules/regex/regex.cpp msgid "Strings" @@ -17775,32 +17538,28 @@ msgid "Discover IPv6" msgstr "" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "Description URL" -msgstr "Descripción" +msgstr "Descripción URL" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "Service Type" -msgstr "Establecer Tipo de la Variable" +msgstr "Tipo de Servicio" #: modules/upnp/upnp_device.cpp msgid "IGD Control URL" msgstr "" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "IGD Service Type" -msgstr "Establecer Tipo de la Variable" +msgstr "Tipo de Servicio IGD" #: modules/upnp/upnp_device.cpp msgid "IGD Our Addr" msgstr "" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "IGD Status" -msgstr "Estado" +msgstr "Estado del IGD" #: modules/visual_script/visual_script.cpp msgid "" @@ -17841,9 +17600,8 @@ msgid "Stack overflow with stack depth:" msgstr "Desbordamiento de pila con profundidad de pila:" #: modules/visual_script/visual_script.cpp -#, fuzzy msgid "Visual Script" -msgstr "Buscar en VisualScript" +msgstr "Visual Script" #: modules/visual_script/visual_script_editor.cpp msgid "Change Signal Arguments" @@ -18173,14 +17931,12 @@ msgid "Return" msgstr "Regresar" #: modules/visual_script/visual_script_flow_control.cpp -#, fuzzy msgid "Return Enabled" -msgstr "Ejecutable" +msgstr "Retorno Activado" #: modules/visual_script/visual_script_flow_control.cpp -#, fuzzy msgid "Return Type" -msgstr "Regresar" +msgstr "Tipo de Retorno" #: modules/visual_script/visual_script_flow_control.cpp #: scene/resources/visual_shader_nodes.cpp @@ -18228,9 +17984,8 @@ msgid "in order:" msgstr "en orden:" #: modules/visual_script/visual_script_flow_control.cpp -#, fuzzy msgid "Steps" -msgstr "Paso" +msgstr "Pasos" #: modules/visual_script/visual_script_flow_control.cpp msgid "Switch" @@ -18250,9 +18005,8 @@ msgstr "¿Es %s?" #: modules/visual_script/visual_script_flow_control.cpp #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Base Script" -msgstr "Nuevo Script" +msgstr "Script Base" #: modules/visual_script/visual_script_func_nodes.cpp msgid "On %s" @@ -18264,36 +18018,31 @@ msgstr "Sobre Sí Mismo" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_yield_nodes.cpp -#, fuzzy msgid "Call Mode" -msgstr "Modo de Escalado" +msgstr "Modo de Llamada" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Basic Type" -msgstr "Tipo Base" +msgstr "Tipo Básico" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_yield_nodes.cpp -#, fuzzy msgid "Node Path" -msgstr "Copiar Ruta del Nodo" +msgstr "Ruta del Nodo" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Use Default Args" -msgstr "Restablecer Valores por Defecto" +msgstr "Usar Argumentos por Defecto" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Validate" msgstr "Validar" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "RPC Call Mode" -msgstr "Modo de Escalado" +msgstr "Modo de Llamada RPC" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Subtract %s" @@ -18332,14 +18081,12 @@ msgid "BitXor %s" msgstr "BitXor %s" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Set Mode" -msgstr "Modo de Selección" +msgstr "Modo de Ajuste" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Assign Op" -msgstr "Asignar" +msgstr "Asignar Op" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp @@ -18356,9 +18103,8 @@ msgid "Base object is not a Node!" msgstr "¡El objeto base no es un nodo!" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Path does not lead to Node!" -msgstr "¡La ruta no apunta a un Nodo!" +msgstr "¡La ruta no lleva al nodo!" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name '%s' in node %s." @@ -18374,9 +18120,8 @@ msgstr "Ordenar Array" #: modules/visual_script/visual_script_nodes.cpp scene/resources/material.cpp #: scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Operator" -msgstr "Iterador" +msgstr "Operador" #: modules/visual_script/visual_script_nodes.cpp msgid "Invalid argument of type:" @@ -18391,9 +18136,8 @@ msgid "a if cond, else b" msgstr "a si cond, sino b" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Var Name" -msgstr "Nombre" +msgstr "Nombre de la Variable" #: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script:" @@ -18518,9 +18262,8 @@ msgid "%s sec(s)" msgstr "%s seg(s)" #: modules/visual_script/visual_script_yield_nodes.cpp scene/main/timer.cpp -#, fuzzy msgid "Wait Time" -msgstr "Dibujar Tile" +msgstr "Tiempo de Espera" #: modules/visual_script/visual_script_yield_nodes.cpp msgid "WaitSignal" @@ -18535,18 +18278,16 @@ msgid "WaitInstanceSignal" msgstr "WaitInstanceSignal" #: modules/webrtc/webrtc_data_channel.cpp -#, fuzzy msgid "Write Mode" -msgstr "Modo de Prioridad" +msgstr "Modo de Escritura" #: modules/webrtc/webrtc_data_channel.h msgid "WebRTC" msgstr "" #: modules/webrtc/webrtc_data_channel.h -#, fuzzy msgid "Max Channel In Buffer (KB)" -msgstr "Tamaño del buffer del índice del polígono del lienzo (KB)" +msgstr "Buffer de Canal Máximo (KB)" #: modules/websocket/websocket_client.cpp msgid "Verify SSL" @@ -18557,59 +18298,52 @@ msgid "Trusted SSL Certificate" msgstr "" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Client" -msgstr "Red de Pares" +msgstr "Cliente WebSocket" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max In Buffer (KB)" -msgstr "Tamaño Máximo (KB)" +msgstr "Buffer de Entrada Máximo (KB)" #: modules/websocket/websocket_macros.h msgid "Max In Packets" msgstr "" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max Out Buffer (KB)" -msgstr "Tamaño Máximo (KB)" +msgstr "Buffer de Salida Máximo (KB)" #: modules/websocket/websocket_macros.h msgid "Max Out Packets" msgstr "" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Server" -msgstr "Red de Pares" +msgstr "Servidor WebSocket" #: modules/websocket/websocket_server.cpp msgid "Bind IP" msgstr "" #: modules/websocket/websocket_server.cpp -#, fuzzy msgid "Private Key" -msgstr "Ruta de la Clave Privada SSH" +msgstr "Clave Privada" #: modules/websocket/websocket_server.cpp platform/javascript/export/export.cpp msgid "SSL Certificate" msgstr "" #: modules/websocket/websocket_server.cpp -#, fuzzy msgid "CA Chain" -msgstr "Reestrablecer cadena IK" +msgstr "Cadena CA" #: modules/websocket/websocket_server.cpp msgid "Handshake Timeout" msgstr "Tiempo de Espera del Handshake" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Session Mode" -msgstr "Modo de Región" +msgstr "Modo de Sesión" #: modules/webxr/webxr_interface.cpp msgid "Required Features" @@ -18628,28 +18362,24 @@ msgid "Reference Space Type" msgstr "" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Visibility State" -msgstr "Cambiar Visibilidad" +msgstr "Estado de Visibilidad" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Bounds Geometry" -msgstr "Reintentar" +msgstr "Límites Geométricos" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "XR Standard Mapping" -msgstr "Ajuste Inteligente" +msgstr "Mapeo Estándar XR" #: platform/android/export/export.cpp msgid "Android SDK Path" msgstr "" #: platform/android/export/export.cpp -#, fuzzy msgid "Debug Keystore" -msgstr "Depurador" +msgstr "Debug Keystore" #: platform/android/export/export.cpp msgid "Debug Keystore User" @@ -18711,84 +18441,72 @@ msgid "The package must have at least one '.' separator." msgstr "El paquete debe tener al menos un '.' como separador." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Custom Build" -msgstr "CustomNode" +msgstr "Build Personalizada" #: platform/android/export/export_plugin.cpp msgid "Use Custom Build" -msgstr "" +msgstr "Usar Compilación Personalizada" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Export Format" -msgstr "Ruta de Exportación" +msgstr "Formato de Exportación" #: platform/android/export/export_plugin.cpp msgid "Min SDK" msgstr "SDK Mínimo" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Target SDK" -msgstr "Objetivo de FPS" +msgstr "SDK de Destino" #: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp -#, fuzzy msgid "Architectures" -msgstr "Añadir una entrada de arquitectura" +msgstr "Arquitecturas" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Keystore" -msgstr "Depurador" +msgstr "Keystore" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Debug User" -msgstr "Depurador" +msgstr "Usuario de Depuración" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Debug Password" -msgstr "Contraseña" +msgstr "Contraseña de Depuración" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Release User" -msgstr "Release" +msgstr "Usuario de Release" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Release Password" -msgstr "Contraseña" +msgstr "Contraseña de Release" #: platform/android/export/export_plugin.cpp msgid "One Click Deploy" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Clear Previous Install" -msgstr "Inspeccionar Instancia Anterior" +msgstr "Limpiar Instalación Previa" #: platform/android/export/export_plugin.cpp msgid "Code" msgstr "" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Package" -msgstr "Empaquetando" +msgstr "Paquete" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp msgid "Unique Name" msgstr "Nombre Único" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Signed" -msgstr "Señal" +msgstr "Firmado" #: platform/android/export/export_plugin.cpp msgid "Classify As Game" @@ -18799,33 +18517,28 @@ msgid "Retain Data On Uninstall" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Exclude From Recents" -msgstr "Eliminar Nodos" +msgstr "Excluir de los Recientes" #: platform/android/export/export_plugin.cpp msgid "Graphics" msgstr "Gráficos" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "OpenGL Debug" -msgstr "Abrir" +msgstr "Depuración de OpenGL" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "XR Features" -msgstr "Características" +msgstr "Características del XR" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "XR Mode" -msgstr "Modo desplazamiento lateral" +msgstr "Modo XR" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Hand Tracking" -msgstr "Empaquetando" +msgstr "Seguimiento de Manos" #: platform/android/export/export_plugin.cpp msgid "Hand Tracking Frequency" @@ -18836,71 +18549,60 @@ msgid "Passthrough" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Immersive Mode" -msgstr "Modo de Prioridad" +msgstr "Modo Inmersivo" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Small" -msgstr "Soporte" +msgstr "Soporte Pequeño" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Normal" -msgstr "Soporte" +msgstr "Soporte Normal" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Large" -msgstr "Soporte" +msgstr "Soporte Grande" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Xlarge" -msgstr "Soporte" +msgstr "Soporte Xlarge" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "User Data Backup" -msgstr "Interfaz de usuario" +msgstr "Backup de Datos del Usuario" #: platform/android/export/export_plugin.cpp msgid "Allow" msgstr "" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Command Line" -msgstr "Command" +msgstr "Línea de Comandos" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp msgid "Extra Args" msgstr "Argumentos extras" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "APK Expansion" -msgstr "Expresión" +msgstr "Expansión del APK" #: platform/android/export/export_plugin.cpp msgid "Salt" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Public Key" -msgstr "Ruta de la clave pública SSH" +msgstr "Clave Pública" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Permissions" -msgstr "Máscara de Emisión" +msgstr "Permisos" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Custom Permissions" -msgstr "Reproducir Escena Personalizada" +msgstr "Permisos Personalizados" #: platform/android/export/export_plugin.cpp msgid "Select device from the list" @@ -19029,34 +18731,33 @@ msgstr "" #: platform/android/export/export_plugin.cpp msgid "\"Use Custom Build\" must be enabled to use the plugins." -msgstr "\"Use Custom Build\" debe estar activado para usar los plugins." +msgstr "" +"\"Usar Compilación Personalizada\" debe estar activado para usar los plugins." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" " "or \"OpenXR\"." msgstr "" -"\"Hand Tracking\" solo es válido cuando \"Xr Mode\" es \"Oculus Mobile " -"VrApi\" u \"OpenXR\"." +"\"Seguimiento de Manos\" solo es válido cuando el \"Modo XR\" es \"Oculus " +"Mobile VrApi\" u \"OpenXR\"." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"." -msgstr "\"Passthrough\" solo es válido cuando \"Xr Mode\" es \"OpenXR\"." +msgstr "\"Passthrough\" solo es válido cuando el \"Modo XR\" es \"OpenXR\"." #: platform/android/export/export_plugin.cpp msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled." msgstr "" -"\"Export AAB\" sólo es válido cuando \"Use Custom Build\" está activado." +"\"Exportar AAB\" solo es válido cuando \"Usar Compilación Personalizada\" " +"está activado." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled." msgstr "" -"Cambiar el \"Min Sdk\" solo es válido cuando \"Use Custom Build\" está " -"activado." +"\"Min SDK\" solo puede sobrescribirse cuando está activada la opción \"Usar " +"Compilación Personalizada\"." #: platform/android/export/export_plugin.cpp msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid." @@ -19069,36 +18770,36 @@ msgid "" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled." msgstr "" -"Cambiar el \"Target Sdk\" solo es válido cuando \"Use Custom Build\" está " -"activado." +"\"SDK de Destino\" solo se puede sobrescribir cuando \"Usar Compilación " +"Personalizada\" está activado." #: platform/android/export/export_plugin.cpp msgid "" "\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid." msgstr "" +"\"SDK de Destino\" debería ser un entero válido, pero obtuvo \"%s\" inválido." #: platform/android/export/export_plugin.cpp msgid "" "\"Target SDK\" %d is higher than the default version %d. This may work, but " "wasn't tested and may be unstable." msgstr "" +"\"SDK de Destino\" %d es superior a la versión por defecto %d. Podría " +"funcionar, pero no se ha probado y puede ser inestable." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version." msgstr "" -"La versión de \"Target Sdk\" debe ser mayor o igual que la versión de \"Min " -"Sdk\"." +"La versión \"SDK de Destino\" debe ser mayor o igual a la versión \"Min " +"SDK\"." #: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Code Signing" -msgstr "Firma de código DMG" +msgstr "Firma del Código" #: platform/android/export/export_plugin.cpp msgid "" @@ -19328,9 +19029,8 @@ msgid "Code Sign Identity Debug" msgstr "" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Method Debug" -msgstr "Exportar Con Depuración" +msgstr "Exportar Método de Depuración" #: platform/iphone/export/export.cpp msgid "Provisioning Profile UUID Release" @@ -19357,39 +19057,33 @@ msgid "Identifier" msgstr "Identificador" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Signature" -msgstr "Señal" +msgstr "Firma" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Short Version" -msgstr "Versión" +msgstr "Versión Corta" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Copyright" -msgstr "Superior Derecha" +msgstr "Copyright" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Capabilities" -msgstr "Capitalizar Propiedades" +msgstr "Capacidades" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Access Wi-Fi" -msgstr "Acceso" +msgstr "Acceso Wi-Fi" #: platform/iphone/export/export.cpp msgid "Push Notifications" msgstr "Notificaciones Push" #: platform/iphone/export/export.cpp -#, fuzzy msgid "User Data" -msgstr "Interfaz de usuario" +msgstr "Datos de Usuario" #: platform/iphone/export/export.cpp msgid "Accessible From Files App" @@ -19400,24 +19094,20 @@ msgid "Accessible From iTunes Sharing" msgstr "" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Privacy" -msgstr "Ruta de la Clave Privada SSH" +msgstr "Privacidad" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Camera Usage Description" -msgstr "Descripción" +msgstr "Descripción del Uso de la Cámara" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Microphone Usage Description" -msgstr "Descripciones de Propiedades" +msgstr "Descripción del Uso del Micrófono" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Photolibrary Usage Description" -msgstr "Descripciones de Propiedades" +msgstr "Descripción del Uso de la Fotolibrería" #: platform/iphone/export/export.cpp msgid "iPhone 120 X 120" @@ -19460,40 +19150,33 @@ msgid "Use Launch Screen Storyboard" msgstr "" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Image Scale Mode" -msgstr "Modo de Escalado" +msgstr "Modo de Escalado de Imagen" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom Image @2x" -msgstr "CustomNode" +msgstr "Imagen Personalizada @2x" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom Image @3x" -msgstr "CustomNode" +msgstr "Imagen Personalizada @3x" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Use Custom BG Color" -msgstr "CustomNode" +msgstr "Usar Color de Fondo Personalizado" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom BG Color" -msgstr "CustomNode" +msgstr "Color de Fondo Personalizado" #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp -#, fuzzy msgid "Prepare Templates" -msgstr "Administrar Plantillas" +msgstr "Preparar Plantillas" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Export template not found." -msgstr "Plantilla release personalizada no encontrada." +msgstr "No se ha encontrado la plantilla de exportación." #: platform/iphone/export/export.cpp msgid "App Store Team ID not specified - cannot configure the project." @@ -19529,9 +19212,8 @@ msgid "Could not write file: \"%s\"." msgstr "No se pudo escribir el archivo: \"%s\"." #: platform/javascript/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Icon Creation" -msgstr "Asignar Margen" +msgstr "Creación de Iconos" #: platform/javascript/export/export.cpp msgid "Could not read file: \"%s\"." @@ -19546,14 +19228,12 @@ msgid "Variant" msgstr "Variante" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Export Type" -msgstr "Exportar" +msgstr "Tipo de Exportación" #: platform/javascript/export/export.cpp -#, fuzzy msgid "VRAM Texture Compression" -msgstr "Expresión" +msgstr "Compresión de Texturas en la VRAM" #: platform/javascript/export/export.cpp msgid "For Desktop" @@ -19568,14 +19248,12 @@ msgid "HTML" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Export Icon" -msgstr "Expandir Todo" +msgstr "Icono de Exportación" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Custom HTML Shell" -msgstr "CustomNode" +msgstr "HTML Shell Personalizado" #: platform/javascript/export/export.cpp msgid "Head Include" @@ -19590,9 +19268,8 @@ msgid "Focus Canvas On Start" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Experimental Virtual Keyboard" -msgstr "Filtrar señales" +msgstr "Teclado Virtual Experimental" #: platform/javascript/export/export.cpp msgid "Progressive Web App" @@ -19639,9 +19316,8 @@ msgid "HTTP Port" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Use SSL" -msgstr "Usar Snap" +msgstr "Usar SSL" #: platform/javascript/export/export.cpp msgid "SSL Key" @@ -19728,33 +19404,28 @@ msgid "High Res" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Location Usage Description" -msgstr "Descripción" +msgstr "Ubicación de la Descripción de Uso" #: platform/osx/export/export.cpp msgid "Address Book Usage Description" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Calendar Usage Description" -msgstr "Descripción" +msgstr "Descripción del Uso del Calendario" #: platform/osx/export/export.cpp -#, fuzzy msgid "Photos Library Usage Description" -msgstr "Descripciones de Propiedades" +msgstr "Descripción de Uso de la Librería de Fotos" #: platform/osx/export/export.cpp -#, fuzzy msgid "Desktop Folder Usage Description" -msgstr "Descripciones de Métodos" +msgstr "Descripción de Uso de la Carpeta de Escritorio" #: platform/osx/export/export.cpp -#, fuzzy msgid "Documents Folder Usage Description" -msgstr "Descripciones de Métodos" +msgstr "Descripción de Uso de la Carpeta de Documentos" #: platform/osx/export/export.cpp msgid "Downloads Folder Usage Description" @@ -19769,39 +19440,33 @@ msgid "Removable Volumes Usage Description" msgstr "" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Codesign" -msgstr "Firma de código DMG" +msgstr "Codesign" #: platform/osx/export/export.cpp platform/uwp/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Identity" -msgstr "Indentar a la Izquierda" +msgstr "Identidad" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Timestamp" -msgstr "Tiempo" +msgstr "Marca de Tiempo" #: platform/osx/export/export.cpp msgid "Hardened Runtime" -msgstr "" +msgstr "Hardened Runtime" #: platform/osx/export/export.cpp -#, fuzzy msgid "Replace Existing Signature" -msgstr "Reemplazar en Archivos" +msgstr "Reemplazar Firma Existente" #: platform/osx/export/export.cpp -#, fuzzy msgid "Entitlements" -msgstr "Gizmos" +msgstr "Derechos" #: platform/osx/export/export.cpp -#, fuzzy msgid "Custom File" -msgstr "CustomNode" +msgstr "Archivo Personalizado" #: platform/osx/export/export.cpp msgid "Allow JIT Code Execution" @@ -19816,14 +19481,12 @@ msgid "Allow Dyld Environment Variables" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Disable Library Validation" -msgstr "Botón Desactivado" +msgstr "Desactivar Validación de Bibliotecas" #: platform/osx/export/export.cpp -#, fuzzy msgid "Audio Input" -msgstr "Añadir Entrada" +msgstr "Entrada de Audio" #: platform/osx/export/export.cpp msgid "Address Book" @@ -19834,81 +19497,68 @@ msgid "Calendars" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Photos Library" -msgstr "Exportar Librería" +msgstr "Librería de Fotos" #: platform/osx/export/export.cpp -#, fuzzy msgid "Apple Events" -msgstr "Añadir Evento" +msgstr "Eventos de Apple" #: platform/osx/export/export.cpp -#, fuzzy msgid "Debugging" -msgstr "Depurar" +msgstr "Depuración" #: platform/osx/export/export.cpp msgid "App Sandbox" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Network Server" -msgstr "Red de Pares" +msgstr "Servidor de Red" #: platform/osx/export/export.cpp -#, fuzzy msgid "Network Client" -msgstr "Red de Pares" +msgstr "Cliente de Red" #: platform/osx/export/export.cpp -#, fuzzy msgid "Device USB" -msgstr "Dispositivo" +msgstr "Dispositivo USB" #: platform/osx/export/export.cpp msgid "Device Bluetooth" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Downloads" -msgstr "Descargar" +msgstr "Descargas de Archivos" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Pictures" -msgstr "Características" +msgstr "Archivos de Imágenes" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Music" -msgstr "Archivo" +msgstr "Archivos de Música" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Movies" -msgstr "Filtrar tiles" +msgstr "Archivos de Vídeo" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Custom Options" -msgstr "Opciones de Bus" +msgstr "Opciones Personalizadas" #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization" -msgstr "Traducciones" +msgstr "Notarización" #: platform/osx/export/export.cpp msgid "Apple ID Name" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Apple ID Password" -msgstr "Contraseña" +msgstr "Contraseña del ID de Apple" #: platform/osx/export/export.cpp msgid "Apple Team ID" @@ -19931,13 +19581,12 @@ msgid "Notarization request UUID: \"%s\"" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "" "The notarization process generally takes less than an hour. When the process " "is completed, you'll receive an email." msgstr "" -"Nota: El proceso de notarización generalmente toma menos de una hora. Cuando " -"se complete el proceso, recibirá un correo electrónico." +"El proceso de notarización suele durar menos de una hora. Cuando el proceso " +"haya finalizado, recibirás un correo electrónico." #: platform/osx/export/export.cpp msgid "" @@ -19956,17 +19605,15 @@ msgstr "" "notarial a la aplicación exportada (opcional):" #: platform/osx/export/export.cpp -#, fuzzy msgid "Timestamping is not compatible with ad-hoc signature, and was disabled!" msgstr "" -"El sellado de tiempo no es compatible con la firma ad-hoc, y se desactivará!" +"¡La marca de tiempo no es compatible con la firma ad-hoc, y fue desactivada!" #: platform/osx/export/export.cpp -#, fuzzy msgid "" "Hardened Runtime is not compatible with ad-hoc signature, and was disabled!" msgstr "" -"Hardened Runtime no es compatible con la firma ad-hoc, y se desactivará!" +"¡Hardened Runtime no es compatible con la firma ad-hoc, y fue desactivado!" #: platform/osx/export/export.cpp msgid "Built-in CodeSign failed with error \"%s\"." @@ -19991,16 +19638,14 @@ msgid "Cannot sign file %s." msgstr "No se puede firmar el archivo %s." #: platform/osx/export/export.cpp -#, fuzzy msgid "Relative symlinks are not supported, exported \"%s\" might be broken!" msgstr "" -"Los enlaces simbólicos relativos no son compatibles con este sistema " -"operativo, ¡el proyecto exportado podría estar dañado!" +"Los enlaces simbólicos relativos no son compatibles, ¡los \"%s\" exportados " +"podrían estar rotos!" #: platform/osx/export/export.cpp -#, fuzzy msgid "DMG Creation" -msgstr "Direcciones" +msgstr "Creación de DMG" #: platform/osx/export/export.cpp msgid "Could not start hdiutil executable." @@ -20036,13 +19681,12 @@ msgstr "" "operativo, ¡el proyecto exportado podría estar dañado!" #: platform/osx/export/export.cpp -#, fuzzy msgid "" "Requested template binary \"%s\" not found. It might be missing from your " "template archive." msgstr "" -"Plantilla binaria solicitada '%s' no encontrada. Es posible que falte en el " -"archivo de plantillas." +"No se ha encontrado la plantilla binaria \"%s\" solicitada. Es posible que " +"no se encuentre en el archivo de plantillas." #: platform/osx/export/export.cpp msgid "Making PKG" @@ -20085,9 +19729,8 @@ msgid "Sending archive for notarization" msgstr "Enviando archivo para notarización" #: platform/osx/export/export.cpp -#, fuzzy msgid "ZIP Creation" -msgstr "Proyecto" +msgstr "Creación de ZIP" #: platform/osx/export/export.cpp msgid "Could not open file to read from path \"%s\"." @@ -20126,9 +19769,7 @@ msgstr "Notarización: Se requiere la firma del código para la notarización." #: platform/osx/export/export.cpp msgid "Notarization: Hardened runtime is required for notarization." -msgstr "" -"Notarización: se requiere tiempo de ejecución endurecido para la " -"certificación notarial." +msgstr "Notarización: Se requiere Hardened runtime para la notarización." #: platform/osx/export/export.cpp msgid "Notarization: Timestamp runtime is required for notarization." @@ -20165,7 +19806,7 @@ msgid "" "Hardened Runtime is not compatible with ad-hoc signature, and will be " "disabled!" msgstr "" -"Hardened Runtime no es compatible con la firma ad-hoc, y se desactivará!" +"¡Hardened Runtime no es compatible con la firma ad-hoc, y se desactivará!" #: platform/osx/export/export.cpp msgid "" @@ -20237,14 +19878,12 @@ msgid "Force Builtin Codesign" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Architecture" -msgstr "Añadir una entrada de arquitectura" +msgstr "Arquitectura" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Display Name" -msgstr "Escala de Visualización" +msgstr "Nombre a Mostrar" #: platform/uwp/export/export.cpp msgid "Short Name" @@ -20263,24 +19902,20 @@ msgid "Product GUID" msgstr "GUID del producto" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Publisher GUID" -msgstr "Limpiar Guías" +msgstr "GUID del Editor" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Signing" -msgstr "Señal" +msgstr "Firmando" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Certificate" -msgstr "Certificados" +msgstr "Certificado" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Algorithm" -msgstr "Depurador" +msgstr "Algoritmo" #: platform/uwp/export/export.cpp msgid "Major" @@ -20291,23 +19926,20 @@ msgid "Minor" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Build" -msgstr "Modo de Regla" +msgstr "Compilación" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Revision" -msgstr "Expresión" +msgstr "Revisión" #: platform/uwp/export/export.cpp msgid "Landscape" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Portrait" -msgstr "Voltear Portales" +msgstr "Retrato" #: platform/uwp/export/export.cpp msgid "Landscape Flipped" @@ -20318,9 +19950,8 @@ msgid "Portrait Flipped" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Store Logo" -msgstr "Modo de Escalado" +msgstr "Logo de Tienda" #: platform/uwp/export/export.cpp msgid "Square 44 X 44 Logo" @@ -20347,9 +19978,8 @@ msgid "Splash Screen" msgstr "Pantalla de Bienvenida" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Tiles" -msgstr "Archivo" +msgstr "Tiles" #: platform/uwp/export/export.cpp msgid "Show Name On Square 150 X 150" @@ -20433,18 +20063,16 @@ msgid "UWP" msgstr "" #: platform/uwp/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Signtool" -msgstr "Señal" +msgstr "Signtool" #: platform/uwp/export/export.cpp msgid "Debug Certificate" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Debug Algorithm" -msgstr "Depurador" +msgstr "Algoritmo de Depuración" #: platform/windows/export/export.cpp msgid "Failed to rename temporary file \"%s\"." @@ -20459,19 +20087,16 @@ msgid "Timestamp Server URL" msgstr "" #: platform/windows/export/export.cpp -#, fuzzy msgid "Digest Algorithm" -msgstr "Depurador" +msgstr "Algoritmo de Compilación" #: platform/windows/export/export.cpp -#, fuzzy msgid "Modify Resources" -msgstr "Copiar Recurso" +msgstr "Modificar Recursos" #: platform/windows/export/export.cpp -#, fuzzy msgid "File Version" -msgstr "Versión" +msgstr "Versión del Archivo" #: platform/windows/export/export.cpp msgid "Product Version" @@ -20486,79 +20111,70 @@ msgid "Product Name" msgstr "Nombre del Producto" #: platform/windows/export/export.cpp -#, fuzzy msgid "File Description" -msgstr "Descripción" +msgstr "Descripción del Archivo" #: platform/windows/export/export.cpp msgid "Trademarks" msgstr "" #: platform/windows/export/export.cpp -#, fuzzy msgid "Resources Modification" -msgstr "Notificaciones Push" +msgstr "Modificación de los Recursos" #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find rcedit executable at \"%s\"." -msgstr "No se pudo encontrar la keystore, no se puedo exportar." +msgstr "No se pudo encontrar el ejecutable rcedit en \"%s\"." #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find wine executable at \"%s\"." -msgstr "No se pudo encontrar la keystore, no se puedo exportar." +msgstr "No se pudo encontrar el ejecutable de wine en \"%s\"." #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" -"La herramienta rcedit debe configurarse en la configuración del editor " -"(Exportar > Windows > Rcedit) para cambiar los datos de información del " -"ícono o la aplicación." +"No se ha podido iniciar el ejecutable rcedit, configura la ruta de rcedit en " +"la configuración del editor (Exportar > Windows > Rcedit)." #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Fallo al abrir el archivo ejecutable \"%s\"." #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find signtool executable at \"%s\"." -msgstr "No se pudo encontrar la keystore, no se puedo exportar." +msgstr "No se pudo encontrar el ejecutable de signtool en \"%s\"." #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find osslsigncode executable at \"%s\"." -msgstr "No se pudo encontrar la keystore, no se puedo exportar." +msgstr "No se pudo encontrar el ejecutable osslsigncode en \"%s\"." #: platform/windows/export/export.cpp msgid "Invalid identity type." msgstr "Tipo de identificador inválido." #: platform/windows/export/export.cpp -#, fuzzy msgid "Invalid timestamp server." -msgstr "Nombre inválido." +msgstr "Servidor de marcas de tiempo inválido." #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" -"La herramienta rcedit debe configurarse en la configuración del editor " -"(Exportar > Windows > Rcedit) para cambiar los datos de información del " -"ícono o la aplicación." +"No se ha podido iniciar el ejecutable de signtool, configura la ruta de " +"signtool en la configuración del editor (Exportar > Windows > Signtool)." #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Fallo al abrir el archivo ejecutable \"%s\"." #: platform/windows/export/export.cpp msgid "Failed to remove temporary file \"%s\"." @@ -20590,9 +20206,8 @@ msgid "Windows executables cannot be >= 4 GiB." msgstr "" #: platform/windows/export/export.cpp platform/x11/export/export.cpp -#, fuzzy msgid "Failed to open executable file \"%s\"." -msgstr "Archivo ejecutable no válido." +msgstr "Fallo al abrir el archivo ejecutable \"%s\"." #: platform/windows/export/export.cpp platform/x11/export/export.cpp msgid "Executable file header corrupted." @@ -20603,9 +20218,8 @@ msgid "Executable \"pck\" section not found." msgstr "" #: platform/windows/export/export.cpp -#, fuzzy msgid "Windows" -msgstr "Nueva Ventana" +msgstr "Windows" #: platform/windows/export/export.cpp msgid "Rcedit" @@ -20625,9 +20239,8 @@ msgstr "" #: scene/2d/animated_sprite.cpp scene/3d/sprite_3d.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Frames" -msgstr "Fotograma %" +msgstr "Fotogramas" #: scene/2d/animated_sprite.cpp msgid "" @@ -20639,21 +20252,18 @@ msgstr "" #: scene/2d/animated_sprite.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/particles_2d.cpp scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Speed Scale" -msgstr "Escala" +msgstr "Escala de Velocidad" #: scene/2d/animated_sprite.cpp scene/2d/audio_stream_player_2d.cpp #: scene/3d/audio_stream_player_3d.cpp scene/3d/sprite_3d.cpp #: scene/audio/audio_stream_player.cpp -#, fuzzy msgid "Playing" msgstr "Reproducir" #: scene/2d/animated_sprite.cpp scene/2d/sprite.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Centered" -msgstr "Centro" +msgstr "Centrado" #: scene/2d/animated_sprite.cpp scene/2d/sprite.cpp scene/3d/sprite_3d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_rect.cpp @@ -20666,39 +20276,32 @@ msgid "Flip V" msgstr "" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Monitoring" -msgstr "Monitor" +msgstr "Monitorización" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Monitorable" -msgstr "Monitor" +msgstr "Monitorizable" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Physics Overrides" -msgstr "Anulaciones" +msgstr "Anulaciones de Físicas" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Space Override" -msgstr "Anulaciones" +msgstr "Anulación de Espacio" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Point" -msgstr "Generar puntos" +msgstr "Punto de Gravedad" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Distance Scale" -msgstr "WaitInstanceSignal" +msgstr "Escala de Distancia de la Gravedad" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Vec" -msgstr "Vista Previa Por Defecto" +msgstr "Velocidad de la Gravedad" #: scene/2d/area_2d.cpp scene/2d/cpu_particles_2d.cpp scene/3d/area.cpp #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp @@ -20706,42 +20309,36 @@ msgid "Gravity" msgstr "" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Linear Damp" -msgstr "Lineal" +msgstr "Amortiguación Lineal" #: scene/2d/area_2d.cpp scene/3d/area.cpp msgid "Angular Damp" msgstr "" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Audio Bus" -msgstr "Añadir Bus de Audio" +msgstr "Bus de Audio" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Override" -msgstr "Anulaciones" +msgstr "Anular" #: scene/2d/audio_stream_player_2d.cpp scene/audio/audio_stream_player.cpp #: scene/gui/video_player.cpp servers/audio/effects/audio_effect_amplify.cpp -#, fuzzy msgid "Volume dB" -msgstr "Volumen" +msgstr "Volumen dB" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp #: servers/audio/effects/audio_effect_pitch_shift.cpp -#, fuzzy msgid "Pitch Scale" -msgstr "Escala" +msgstr "Escala de Tono" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp -#, fuzzy msgid "Autoplay" -msgstr "Act./Desact. Reproducción Automática" +msgstr "Reproducción Automática" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp @@ -20756,29 +20353,25 @@ msgid "Max Distance" msgstr "Distancia Maxima" #: scene/2d/audio_stream_player_2d.cpp scene/3d/light.cpp -#, fuzzy msgid "Attenuation" -msgstr "Animación" +msgstr "Atenuación" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp -#, fuzzy msgid "Bus" -msgstr "Añadir Bus" +msgstr "Bus" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp msgid "Area Mask" msgstr "" #: scene/2d/back_buffer_copy.cpp -#, fuzzy msgid "Copy Mode" -msgstr "Copiar Nodos" +msgstr "Modo de Copia" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Anchor Mode" -msgstr "Modo de Icono" +msgstr "Modo de Anclaje" #: scene/2d/camera_2d.cpp msgid "Rotating" @@ -20790,83 +20383,70 @@ msgid "Current" msgstr "Actual" #: scene/2d/camera_2d.cpp scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom" -msgstr "Acercar Zoom" +msgstr "Zoom" #: scene/2d/camera_2d.cpp scene/main/canvas_layer.cpp -#, fuzzy msgid "Custom Viewport" -msgstr "1 Viewport" +msgstr "Viewport Personalizado" #: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp #: scene/animation/animation_tree_player.cpp scene/main/timer.cpp -#, fuzzy msgid "Process Mode" -msgstr "Modo de Movimiento" +msgstr "Modo de Proceso" #: scene/2d/camera_2d.cpp msgid "Limit" -msgstr "" +msgstr "Limite" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp -#, fuzzy msgid "Left" -msgstr "UI Izquierda" +msgstr "Izquierda" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp -#, fuzzy msgid "Right" -msgstr "Luz" +msgstr "Derecha" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/dynamic_font.cpp scene/resources/style_box.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Bottom" -msgstr "Inferior Izquierda" +msgstr "Inferior" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Smoothed" msgstr "Suavizado" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Draw Margin" -msgstr "Asignar Margen" +msgstr "Margen de Arrastre" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Drag Margin H Enabled" -msgstr "Asignar Margen" +msgstr "Margen de Arrastre H Activado" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Drag Margin V Enabled" -msgstr "Asignar Margen" +msgstr "Margen de Arrastre V Activado" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Smoothing" -msgstr "Suavizado" +msgstr "Suavizar" #: scene/2d/camera_2d.cpp msgid "H" msgstr "" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "V" -msgstr "UV" +msgstr "V" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Drag Margin" -msgstr "Asignar Margen" +msgstr "Margen de Arrastre" #: scene/2d/camera_2d.cpp msgid "Draw Screen" @@ -20877,25 +20457,21 @@ msgid "Draw Limits" msgstr "Límites de Dibujo" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Draw Drag Margin" -msgstr "Asignar Margen" +msgstr "Margen de Arrastre del Trazado" #: scene/2d/canvas_item.cpp scene/resources/environment.cpp #: scene/resources/material.cpp -#, fuzzy msgid "Blend Mode" -msgstr "Nodo Blend2" +msgstr "Modo de Fusión" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Light Mode" -msgstr "Ancho Derecha" +msgstr "Modo de Iluminación" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Particles Animation" -msgstr "Partículas" +msgstr "Animación de Partículas" #: scene/2d/canvas_item.cpp msgid "Particles Anim H Frames" @@ -20906,40 +20482,34 @@ msgid "Particles Anim V Frames" msgstr "" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Particles Anim Loop" -msgstr "Partículas" +msgstr "Bucle de Animación de Partículas" #: scene/2d/canvas_item.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Visibility" -msgstr "Cambiar Visibilidad" +msgstr "Visibilidad" #: scene/2d/canvas_item.cpp scene/3d/spatial.cpp scene/gui/progress_bar.cpp #: scene/gui/rich_text_effect.cpp scene/main/canvas_layer.cpp -#, fuzzy msgid "Visible" -msgstr "Cambiar Visibilidad" +msgstr "Visible" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Self Modulate" -msgstr "Rellenar" +msgstr "Modulación Automática" #: scene/2d/canvas_item.cpp msgid "Show Behind Parent" msgstr "" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Show On Top" -msgstr "Mostrar Origen" +msgstr "Mostrar Arriba" #: scene/2d/canvas_item.cpp scene/2d/light_occluder_2d.cpp #: scene/2d/tile_map.cpp -#, fuzzy msgid "Light Mask" -msgstr "Luz" +msgstr "Máscara de Luz" #: scene/2d/canvas_item.cpp msgid "Use Parent Material" @@ -20966,9 +20536,8 @@ msgstr "" "CollisionPolygon2D para definir su forma." #: scene/2d/collision_object_2d.cpp -#, fuzzy msgid "Pickable" -msgstr "Elegir Tile" +msgstr "Seleccionable" #: scene/2d/collision_polygon_2d.cpp msgid "" @@ -21001,29 +20570,27 @@ msgstr "" msgid "" "The One Way Collision property will be ignored when the parent is an Area2D." msgstr "" +"La propiedad Colisión en Una Dirección será ignorada cuando el padre sea un " +"Area2D." #: scene/2d/collision_polygon_2d.cpp -#, fuzzy msgid "Build Mode" -msgstr "Modo de Regla" +msgstr "Modo de Compilación" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp #: scene/3d/collision_polygon.cpp scene/3d/collision_shape.cpp #: scene/animation/animation_node_state_machine.cpp scene/gui/base_button.cpp #: scene/gui/texture_button.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Disabled" -msgstr "Desactivar Elemento" +msgstr "Desactivado" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp -#, fuzzy msgid "One Way Collision" -msgstr "Crear Polígono de Colisión" +msgstr "Colisión en Una Dirección" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp -#, fuzzy msgid "One Way Collision Margin" -msgstr "Crear Polígono de Colisión" +msgstr "Margen de Colisión en Una Dirección" #: scene/2d/collision_shape_2d.cpp msgid "" @@ -21072,15 +20639,13 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp scene/main/timer.cpp -#, fuzzy msgid "One Shot" -msgstr "Nodo OneShot" +msgstr "Un Disparo" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Preprocess" -msgstr "Post procesado" +msgstr "Preproceso" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -21099,9 +20664,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Fixed FPS" -msgstr "Ver FPS" +msgstr "FPS Fijos" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -21115,9 +20679,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Local Coords" -msgstr "Proyectos Locales" +msgstr "Coordenadas Locales" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -21126,9 +20689,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Emission Shape" -msgstr "Máscara de Emisión" +msgstr "Forma de la Emisión" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21136,26 +20698,22 @@ msgid "Sphere Radius" msgstr "Radio de la Esfera" #: scene/2d/cpu_particles_2d.cpp -#, fuzzy msgid "Rect Extents" -msgstr "Gizmos" +msgstr "Extender Completo" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp -#, fuzzy msgid "Normals" -msgstr "Formato" +msgstr "Normales" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Align Y" -msgstr "Asignar" +msgstr "Alineación Y" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Direction" -msgstr "Direcciones" +msgstr "Dirección" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21165,15 +20723,13 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Initial Velocity" -msgstr "Inicializar" +msgstr "Velocidad Inicial" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Velocity Random" -msgstr "Velocidad" +msgstr "Velocidad Aleatoria" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp servers/physics_2d_server.cpp @@ -21183,27 +20739,23 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Velocity Curve" -msgstr "Velocidad" +msgstr "Curva de Velocidad" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Orbit Velocity" -msgstr "Vista de Órbita Derecha" +msgstr "Velocidad de la Órbita" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Linear Accel" -msgstr "Lineal" +msgstr "Aceleración Lineal" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Accel" -msgstr "Acceso" +msgstr "Aceleración" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21212,9 +20764,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Accel Curve" -msgstr "Partir Curva" +msgstr "Curva de Aceleración" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21241,9 +20792,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Damping Curve" -msgstr "Partir Curva" +msgstr "Curva de Amortiguación" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp scene/3d/light.cpp #: scene/resources/particles_material.cpp @@ -21257,9 +20807,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Angle Curve" -msgstr "Cerrar Curva" +msgstr "Curva de Ángulo" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp msgid "Scale Amount" @@ -21270,15 +20819,13 @@ msgid "Scale Amount Random" msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp -#, fuzzy msgid "Scale Amount Curve" -msgstr "Escalar Desde Cursor" +msgstr "Curva de Cantidad de Escala" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Color Ramp" -msgstr "Colores" +msgstr "Rampa de Color" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21307,15 +20854,13 @@ msgstr "Curva de Variación" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Speed Random" -msgstr "Escala" +msgstr "Velocidad Aleatoria" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Speed Curve" -msgstr "Partir Curva" +msgstr "Curva de Velocidad" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21324,9 +20869,8 @@ msgstr "Desplazamiento Aleatorio" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Offset Curve" -msgstr "Cerrar Curva" +msgstr "Curva de Desplazamiento" #: scene/2d/joints_2d.cpp msgid "Node A and Node B must be PhysicsBody2Ds" @@ -21349,14 +20893,12 @@ msgid "Node A and Node B must be different PhysicsBody2Ds" msgstr "El Nodo A y el Nodo B deben ser diferentes PhysicsBody2D" #: scene/2d/joints_2d.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Node A" -msgstr "Nodos" +msgstr "Nodo A" #: scene/2d/joints_2d.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Node B" -msgstr "Nodos" +msgstr "Nodo B" #: scene/2d/joints_2d.cpp scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/light.cpp scene/3d/physics_body.cpp scene/3d/physics_joint.cpp @@ -21365,9 +20907,8 @@ msgid "Bias" msgstr "" #: scene/2d/joints_2d.cpp -#, fuzzy msgid "Disable Collision" -msgstr "Botón Desactivado" +msgstr "Desactivar Colisión" #: scene/2d/joints_2d.cpp scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Softness" @@ -21379,9 +20920,8 @@ msgid "Length" msgstr "" #: scene/2d/joints_2d.cpp -#, fuzzy msgid "Initial Offset" -msgstr "Inicializar" +msgstr "Desplazamiento Inicial" #: scene/2d/joints_2d.cpp scene/3d/vehicle_body.cpp msgid "Rest Length" @@ -21400,14 +20940,12 @@ msgstr "" "Texture\"." #: scene/2d/light_2d.cpp scene/3d/light.cpp scene/gui/reference_rect.cpp -#, fuzzy msgid "Editor Only" -msgstr "Editor" +msgstr "Sólo para el Editor" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Texture Scale" -msgstr "Región de Textura" +msgstr "Escala de Textura" #: scene/2d/light_2d.cpp scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/light.cpp scene/resources/environment.cpp @@ -21424,48 +20962,40 @@ msgid "Z Max" msgstr "" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Layer Min" -msgstr "Cambiar Tamaño de Cámara" +msgstr "Capa Mínima" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Layer Max" -msgstr "Capa" +msgstr "Capa Máxima" #: scene/2d/light_2d.cpp msgid "Item Cull Mask" msgstr "" #: scene/2d/light_2d.cpp scene/3d/light.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Shadow" -msgstr "Shader" +msgstr "Sombra" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Buffer Size" -msgstr "Vista Trasera" +msgstr "Tamaño del Buffer" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Gradient Length" -msgstr "Degradado Editado" +msgstr "Longitud del Gradiente" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Filter Smooth" -msgstr "Filtrar métodos" +msgstr "Filtro Suavizado" #: scene/2d/light_occluder_2d.cpp -#, fuzzy msgid "Closed" -msgstr "Cerrar" +msgstr "Cerrado" #: scene/2d/light_occluder_2d.cpp scene/resources/material.cpp -#, fuzzy msgid "Cull Mode" -msgstr "Modo de Regla" +msgstr "Modo de Sacrificio" #: scene/2d/light_occluder_2d.cpp msgid "" @@ -21481,47 +21011,40 @@ msgstr "" "polígono." #: scene/2d/line_2d.cpp -#, fuzzy msgid "Width Curve" -msgstr "Partir Curva" +msgstr "Curva de Ancho" #: scene/2d/line_2d.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Default Color" -msgstr "Por defecto" +msgstr "Color por Defecto" #: scene/2d/line_2d.cpp scene/resources/texture.cpp msgid "Fill" -msgstr "" +msgstr "Rellenar" #: scene/2d/line_2d.cpp scene/resources/texture.cpp -#, fuzzy msgid "Gradient" -msgstr "Degradado Editado" +msgstr "Gradiente" #: scene/2d/line_2d.cpp -#, fuzzy msgid "Texture Mode" -msgstr "Región de Textura" +msgstr "Modo de Textura" #: scene/2d/line_2d.cpp msgid "Capping" -msgstr "" +msgstr "Tapado" #: scene/2d/line_2d.cpp -#, fuzzy msgid "Joint Mode" -msgstr "Modo de Icono" +msgstr "Modo de Unión" #: scene/2d/line_2d.cpp -#, fuzzy msgid "Begin Cap Mode" -msgstr "Modo de Región" +msgstr "Iniciar Modo Cap" #: scene/2d/line_2d.cpp -#, fuzzy msgid "End Cap Mode" -msgstr "Modo de Ajuste:" +msgstr "Modo Tapón" #: scene/2d/line_2d.cpp scene/2d/polygon_2d.cpp scene/resources/style_box.cpp msgid "Border" @@ -21537,14 +21060,12 @@ msgstr "" #: scene/2d/line_2d.cpp scene/2d/polygon_2d.cpp #: scene/resources/dynamic_font.cpp -#, fuzzy msgid "Antialiased" -msgstr "Inicializar" +msgstr "Suavizado Espacial" #: scene/2d/multimesh_instance_2d.cpp scene/3d/multimesh_instance.cpp -#, fuzzy msgid "Multimesh" -msgstr "Multiplicar %s" +msgstr "Multimesh" #: scene/2d/navigation_2d.cpp scene/3d/baked_lightmap.cpp #: scene/3d/navigation.cpp scene/animation/root_motion_view.cpp @@ -21564,60 +21085,54 @@ msgid "" msgstr "" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Pathfinding" -msgstr "Vinculación" +msgstr "Pathfinding" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Path Desired Distance" -msgstr "Distancia de la Ruta U" +msgstr "Ruta Distancia Deseada" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Target Desired Distance" -msgstr "" +msgstr "Distancia Deseada del Objetivo" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Path Max Distance" -msgstr "Distancia Máxima de Ruta" +msgstr "Distancia Máxima de la Ruta" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Avoidance" -msgstr "Avanzado" +msgstr "Evasión" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Avoidance Enabled" -msgstr "Activar" +msgstr "Evasión Activada" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Neighbor Dist" -msgstr "" +msgstr "Dist. de Vecinos" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Max Neighbors" -msgstr "" +msgstr "Máximo de Vecinos" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Time Horizon" -msgstr "Voltear Horizontalmente" +msgstr "Horizonte del Tiempo" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Max Speed" msgstr "Velocidad Máxima" #: scene/2d/navigation_agent_2d.cpp -#, fuzzy msgid "" "The NavigationAgent2D can be used only under a Node2D inheriting parent node." -msgstr "El NavigationAgent2D sólo puede utilizarse bajo un nodo Node2D." +msgstr "" +"El NavigationAgent2D sólo puede utilizarse bajo un nodo padre hijo de Node2D." #: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_obstacle.cpp -#, fuzzy msgid "Estimate Radius" -msgstr "Cambiar Radio Externo de Torus" +msgstr "Estimación del Radio" #: scene/2d/navigation_obstacle_2d.cpp msgid "" @@ -21632,22 +21147,20 @@ msgid "" "A NavigationPolygon resource must be set or created for this node to work. " "Please set a property or draw a polygon." msgstr "" -"Se debe crear o asignar un recurso NavigationPolygon a este nodo para que " -"funcione. Por favor, establece la propiedad o dibuja un polígono." +"Un recurso NavigationPolygon debe ser establecido o creado para que este " +"nodo funcione. Por favor, establece una propiedad o dibuja un polígono." #: scene/2d/navigation_polygon.cpp msgid "Navpoly" -msgstr "" +msgstr "Navpoly" #: scene/2d/navigation_polygon.cpp scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Enter Cost" -msgstr "Centro Inferior" +msgstr "Introduce Costo" #: scene/2d/navigation_polygon.cpp scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Travel Cost" -msgstr "Viaje" +msgstr "Costo del Viaje" #: scene/2d/node_2d.cpp scene/2d/polygon_2d.cpp scene/3d/spatial.cpp #: scene/main/canvas_layer.cpp @@ -21655,9 +21168,8 @@ msgid "Rotation Degrees" msgstr "Grados de Rotación" #: scene/2d/node_2d.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Global Rotation" -msgstr "Constante Global" +msgstr "Rotación Global" #: scene/2d/node_2d.cpp msgid "Global Rotation Degrees" @@ -21668,41 +21180,37 @@ msgid "Global Scale" msgstr "Escala Global" #: scene/2d/node_2d.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Global Transform" -msgstr "Mantener transformación global" +msgstr "Transformación Global" #: scene/2d/node_2d.cpp -#, fuzzy msgid "Z As Relative" -msgstr "Ajuste Relativo" +msgstr "Z Como Relativo" #: scene/2d/parallax_background.cpp scene/gui/scroll_container.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Scroll" -msgstr "" +msgstr "Scroll" #: scene/2d/parallax_background.cpp msgid "Base Offset" msgstr "Desplazamiento Base" #: scene/2d/parallax_background.cpp -#, fuzzy msgid "Base Scale" -msgstr "Usar Ajuste de Escalado" +msgstr "Escala Base" #: scene/2d/parallax_background.cpp msgid "Limit Begin" -msgstr "" +msgstr "Inicio del Límite" #: scene/2d/parallax_background.cpp -#, fuzzy msgid "Limit End" -msgstr "Al Final" +msgstr "Fin del Límite" #: scene/2d/parallax_background.cpp msgid "Ignore Camera Zoom" -msgstr "" +msgstr "Ignorar Zoom de la Cámara" #: scene/2d/parallax_layer.cpp msgid "" @@ -21714,12 +21222,10 @@ msgstr "" #: scene/2d/parallax_layer.cpp scene/2d/physics_body_2d.cpp #: scene/3d/physics_body.cpp scene/3d/vehicle_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Motion" -msgstr "Acción" +msgstr "Movimiento" #: scene/2d/parallax_layer.cpp -#, fuzzy msgid "Mirroring" msgstr "Reflejar" @@ -21766,9 +21272,8 @@ msgstr "" "\"Particles Animation\" activado." #: scene/2d/particles_2d.cpp -#, fuzzy msgid "Visibility Rect" -msgstr "Modo de Prioridad" +msgstr "Visibilidad Rect" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "Process Material" @@ -21776,9 +21281,8 @@ msgstr "" #: scene/2d/path_2d.cpp scene/3d/path.cpp scene/resources/sky.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Curve" -msgstr "Partir Curva" +msgstr "Curva" #: scene/2d/path_2d.cpp msgid "PathFollow2D only works when set as a child of a Path2D node." @@ -21806,25 +21310,21 @@ msgid "Lookahead" msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/visual_instance.cpp -#, fuzzy msgid "Layers" -msgstr "Capa" +msgstr "Capas" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Constant Linear Velocity" -msgstr "Inicializar" +msgstr "Velocidad Lineal Constante" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Constant Angular Velocity" -msgstr "Inicializar" +msgstr "Velocidad Angular Constante" #: scene/2d/physics_body_2d.cpp scene/2d/tile_map.cpp scene/3d/physics_body.cpp #: scene/resources/physics_material.cpp -#, fuzzy msgid "Friction" -msgstr "Función" +msgstr "Fricción" #: scene/2d/physics_body_2d.cpp scene/2d/tile_map.cpp scene/3d/physics_body.cpp #: scene/resources/physics_material.cpp @@ -21837,9 +21337,8 @@ msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: scene/resources/world.cpp scene/resources/world_2d.cpp -#, fuzzy msgid "Default Gravity" -msgstr "Vista Previa Por Defecto" +msgstr "Gravedad por Defecto" #: scene/2d/physics_body_2d.cpp msgid "" @@ -21860,38 +21359,33 @@ msgid "Inertia" msgstr "Inercia" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Weight" -msgstr "Luz" +msgstr "Peso" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Gravity Scale" msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Custom Integrator" -msgstr "CustomNode" +msgstr "Integrador Personalizado" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Continuous CD" -msgstr "Continuo" +msgstr "CD Continuo" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Contacts Reported" msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Contact Monitor" -msgstr "Seleccionar Color" +msgstr "Monitor de Contacto" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Sleeping" -msgstr "Ajuste Inteligente" +msgstr "Resposo" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Can Sleep" @@ -21914,18 +21408,16 @@ msgid "Torque" msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Safe Margin" -msgstr "Asignar Margen" +msgstr "Margen de Seguridad" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Sync To Physics" msgstr "Sincronización Con La Física" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Moving Platform" -msgstr "Moviendo salida" +msgstr "Plataforma Móvil" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Apply Velocity On Leave" @@ -21935,24 +21427,21 @@ msgstr "" #: scene/3d/physics_body.cpp scene/gui/texture_button.cpp #: scene/resources/default_theme/default_theme.cpp #: scene/resources/line_shape_2d.cpp scene/resources/material.cpp -#, fuzzy msgid "Normal" -msgstr "Formato" +msgstr "Normal" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Remainder" msgstr "Recordatorio" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Local Shape" -msgstr "Idioma" +msgstr "Forma Local" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider" -msgstr "Modo de Colisión" +msgstr "Colisionador" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp @@ -21961,26 +21450,22 @@ msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider RID" -msgstr "RID inválido" +msgstr "Colisionador RID" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider Shape" -msgstr "Modo de Colisión" +msgstr "Forma de Colisión" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Collider Shape Index" -msgstr "Modo de Colisión" +msgstr "Índice de Formas de Colisión" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider Velocity" -msgstr "Vista de Órbita Derecha" +msgstr "Velocidad del Colisionador" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Collider Metadata" @@ -21991,28 +21476,24 @@ msgid "Invert" msgstr "" #: scene/2d/polygon_2d.cpp -#, fuzzy msgid "Vertex Colors" -msgstr "Vértice" +msgstr "Color de los Vértices" #: scene/2d/polygon_2d.cpp -#, fuzzy msgid "Internal Vertex Count" -msgstr "Crear Vértice Interno" +msgstr "Conteo de Vértices Internos" #: scene/2d/position_2d.cpp -#, fuzzy msgid "Gizmo Extents" -msgstr "Gizmos" +msgstr "Extensión de Gizmos" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp msgid "Exclude Parent" msgstr "" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp -#, fuzzy msgid "Cast To" -msgstr "Crear Nodo Shader" +msgstr "Lanzar A" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp msgid "Collide With" @@ -22031,24 +21512,20 @@ msgid "Path property must point to a valid Node2D node to work." msgstr "La propiedad Path debe apuntar a un nodo Node2D válido para funcionar." #: scene/2d/remote_transform_2d.cpp scene/3d/remote_transform.cpp -#, fuzzy msgid "Remote Path" -msgstr "Eliminar Punto" +msgstr "Ruta Remota" #: scene/2d/remote_transform_2d.cpp scene/3d/remote_transform.cpp -#, fuzzy msgid "Use Global Coordinates" -msgstr "Siguiente Coordenada" +msgstr "Utilizar Coordenadas Globales" #: scene/2d/skeleton_2d.cpp scene/3d/skeleton.cpp -#, fuzzy msgid "Rest" -msgstr "Reiniciar" +msgstr "Reposo" #: scene/2d/skeleton_2d.cpp -#, fuzzy msgid "Default Length" -msgstr "Theme Predeterminado" +msgstr "Longitud por Defecto" #: scene/2d/skeleton_2d.cpp msgid "This Bone2D chain should end at a Skeleton2D node." @@ -22075,14 +21552,12 @@ msgid "Vframes" msgstr "" #: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Frame Coords" -msgstr "Fotograma %" +msgstr "Coordenadas del Marco" #: scene/2d/sprite.cpp scene/resources/texture.cpp -#, fuzzy msgid "Filter Clip" -msgstr "Filtrar scripts" +msgstr "Filtrar Clips" #: scene/2d/tile_map.cpp msgid "" @@ -22095,44 +21570,36 @@ msgstr "" "RigidBody2D, KinematicBody2D, etc. para que puedan tener forma." #: scene/2d/tile_map.cpp -#, fuzzy msgid "Tile Set" -msgstr "TileSet" +msgstr "Tile Set" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Quadrant Size" -msgstr "Cambiar Tamaño de Cámara" +msgstr "Tamaño del Cuadrante" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Custom Transform" -msgstr "Transformar" +msgstr "Transformación Personalizada" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Half Offset" -msgstr "Inicializar" +msgstr "Medio Desplazamiento" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Tile Origin" -msgstr "Ver Origen" +msgstr "Origen de los Tiles" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Y Sort" -msgstr "Ordenar" +msgstr "Ordenar Y" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Show Collision" -msgstr "Colisión" +msgstr "Mostrar Colisión" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Compatibility Mode" -msgstr "Modo de Prioridad" +msgstr "Modo de Compatibilidad" #: scene/2d/tile_map.cpp msgid "Centered Textures" @@ -22143,32 +21610,28 @@ msgid "Cell Clip UV" msgstr "" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Use Parent" -msgstr "Modo de Colisión" +msgstr "Usar Padres" #: scene/2d/tile_map.cpp msgid "Use Kinematic" msgstr "" #: scene/2d/touch_screen_button.cpp -#, fuzzy msgid "Shape Centered" -msgstr "Ajustar al Centro del Nodo" +msgstr "Forma Centrada" #: scene/2d/touch_screen_button.cpp -#, fuzzy msgid "Shape Visible" -msgstr "Act./Desact. Visible" +msgstr "Forma Visible" #: scene/2d/touch_screen_button.cpp msgid "Passby Press" msgstr "" #: scene/2d/touch_screen_button.cpp -#, fuzzy msgid "Visibility Mode" -msgstr "Modo de Prioridad" +msgstr "Modo de Visibilidad" #: scene/2d/visibility_notifier_2d.cpp msgid "" @@ -22179,28 +21642,24 @@ msgstr "" "editada directamente como padre." #: scene/2d/visibility_notifier_2d.cpp scene/3d/visibility_notifier.cpp -#, fuzzy msgid "Pause Animations" -msgstr "Pegar Animación" +msgstr "Pausar Animaciones" #: scene/2d/visibility_notifier_2d.cpp scene/3d/visibility_notifier.cpp msgid "Freeze Bodies" msgstr "" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Pause Particles" -msgstr "Partículas" +msgstr "Pausar Partículas" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Pause Animated Sprites" -msgstr "Pegar Animación" +msgstr "Pausar Sprites Animados" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Process Parent" -msgstr "Activar Prioridad" +msgstr "Procesamiento de los Padres" #: scene/2d/visibility_notifier_2d.cpp msgid "Physics Process Parent" @@ -22211,9 +21670,8 @@ msgid "Reverb Bus" msgstr "" #: scene/3d/area.cpp -#, fuzzy msgid "Uniformity" -msgstr "Establecer Nombre de Uniform" +msgstr "Uniformidad" #: scene/3d/arvr_nodes.cpp msgid "ARVRCamera must have an ARVROrigin node as its parent." @@ -22240,9 +21698,8 @@ msgstr "" "un controlador real." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "Anchor ID" -msgstr "Sólo anclado" +msgstr "ID de Ancla" #: scene/3d/arvr_nodes.cpp msgid "ARVRAnchor must have an ARVROrigin node as its parent." @@ -22265,9 +21722,8 @@ msgid "World Scale" msgstr "Escala del Mundo" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Attenuation Model" -msgstr "Nodo de Animación" +msgstr "Modelo de Atenuación" #: scene/3d/audio_stream_player_3d.cpp msgid "Unit dB" @@ -22286,18 +21742,16 @@ msgid "Out Of Range Mode" msgstr "" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Emission Angle" -msgstr "Colores de Emisión" +msgstr "Ángulo de Emisión" #: scene/3d/audio_stream_player_3d.cpp msgid "Degrees" msgstr "Grados" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Filter Attenuation dB" -msgstr "Animación" +msgstr "Filtro de Atenuación dB" #: scene/3d/audio_stream_player_3d.cpp msgid "Attenuation Filter" @@ -22311,19 +21765,16 @@ msgstr "" #: scene/3d/audio_stream_player_3d.cpp #: servers/audio/effects/audio_effect_filter.cpp -#, fuzzy msgid "dB" -msgstr "B" +msgstr "dB" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Doppler" -msgstr "Activar Doppler" +msgstr "Doppler" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Tracking" -msgstr "Empaquetando" +msgstr "Seguimiento" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/reflection_probe.cpp @@ -22357,9 +21808,8 @@ msgstr "Hecho" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/reflection_probe.cpp scene/resources/box_shape.cpp #: scene/resources/rectangle_shape_2d.cpp -#, fuzzy msgid "Extents" -msgstr "Gizmos" +msgstr "Extensiones" #: scene/3d/baked_lightmap.cpp msgid "Tweaks" @@ -22382,66 +21832,56 @@ msgid "Use HDR" msgstr "" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Use Color" -msgstr "Colores" +msgstr "Usar Color" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Default Texels Per Unit" -msgstr "Theme Predeterminado" +msgstr "Texeles Por Unidad Predeterminados" #: scene/3d/baked_lightmap.cpp scene/resources/texture.cpp -#, fuzzy msgid "Atlas" -msgstr "Nuevo Atlas" +msgstr "Atlas" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Generate" -msgstr "General" +msgstr "Generar" #: scene/3d/baked_lightmap.cpp msgid "Max Size" msgstr "Tamaño Máximo" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Custom Sky" -msgstr "CustomNode" +msgstr "Cielo Personalizado" #: scene/3d/baked_lightmap.cpp msgid "Custom Sky Rotation Degrees" msgstr "Grados de Rotación del Cielo Personalizados" #: scene/3d/baked_lightmap.cpp scene/3d/ray_cast.cpp -#, fuzzy msgid "Custom Color" -msgstr "CustomNode" +msgstr "Color Personalizado" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Custom Energy" -msgstr "Mover Efecto de Bus" +msgstr "Energía Personalizada" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Min Light" -msgstr "Indentar a la Derecha" +msgstr "Luz Mínima" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -#, fuzzy msgid "Propagation" -msgstr "Navegación" +msgstr "Propagación" #: scene/3d/baked_lightmap.cpp msgid "Image Path" msgstr "" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Light Data" -msgstr "Con Datos" +msgstr "Datos de Iluminación" #: scene/3d/bone_attachment.cpp scene/3d/physics_body.cpp msgid "Bone Name" @@ -22456,14 +21896,12 @@ msgid "Cull Mask" msgstr "" #: scene/3d/camera.cpp -#, fuzzy msgid "Doppler Tracking" -msgstr "Pista de Propiedades" +msgstr "Seguimiento de Doppler" #: scene/3d/camera.cpp -#, fuzzy msgid "Projection" -msgstr "Proyecto" +msgstr "Proyección" #: scene/3d/camera.cpp msgid "FOV" @@ -22474,9 +21912,8 @@ msgid "Frustum Offset" msgstr "Offset de Frustum" #: scene/3d/camera.cpp -#, fuzzy msgid "Near" -msgstr "Más Cercano" +msgstr "Cercano" #: scene/3d/camera.cpp msgid "Far" @@ -22487,23 +21924,20 @@ msgstr "" #: scene/resources/shape.cpp scene/resources/style_box.cpp #: scene/resources/texture.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp -#, fuzzy msgid "Margin" -msgstr "Asignar Margen" +msgstr "Margen" #: scene/3d/camera.cpp -#, fuzzy msgid "Clip To" -msgstr "Clip Arriba" +msgstr "Recortar A" #: scene/3d/collision_object.cpp scene/3d/soft_body.cpp msgid "Ray Pickable" msgstr "" #: scene/3d/collision_object.cpp -#, fuzzy msgid "Capture On Drag" -msgstr "Captura" +msgstr "Captura Al Arrastrar" #: scene/3d/collision_object.cpp msgid "" @@ -22575,53 +22009,44 @@ msgstr "" "Billboard esté ajustado a \"Particle Billboard\"." #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Box Extents" -msgstr "Gizmos" +msgstr "Extensión de Cajas" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Radius" -msgstr "Máscara de Emisión" +msgstr "Radio del Anillo" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Inner Radius" -msgstr "Cambiar Radio Interno de Torus" +msgstr "Radio Interior del Anillo" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Height" -msgstr "Rotar a la Derecha" +msgstr "Altura del Anillo" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Axis" -msgstr "Advertencias" +msgstr "Eje del Anillo" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Rotate Y" -msgstr "Rotar" +msgstr "Rotar Y" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Disable Z" -msgstr "Desactivar Elemento" +msgstr "Desactivar Z" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp msgid "Flatness" msgstr "" #: scene/3d/cull_instance.cpp servers/visual_server.cpp -#, fuzzy msgid "Portals" -msgstr "Voltear Portales" +msgstr "Portales" #: scene/3d/cull_instance.cpp -#, fuzzy msgid "Portal Mode" -msgstr "Modo de Prioridad" +msgstr "Modo Portal" #: scene/3d/cull_instance.cpp msgid "Include In Bound" @@ -22632,9 +22057,8 @@ msgid "Allow Merging" msgstr "" #: scene/3d/cull_instance.cpp -#, fuzzy msgid "Autoplace Priority" -msgstr "Activar Prioridad" +msgstr "Prioridad de Autoemplazamiento" #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" @@ -22667,9 +22091,8 @@ msgid "Subdiv" msgstr "" #: scene/3d/gi_probe.cpp -#, fuzzy msgid "Dynamic Range" -msgstr "Librería Dinámica" +msgstr "Rango Dinámico" #: scene/3d/gi_probe.cpp scene/3d/light.cpp msgid "Normal Bias" @@ -22677,18 +22100,16 @@ msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Pixel Size" -msgstr "Ajuste de Píxeles" +msgstr "Tamaño de Píxeles" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Billboard" msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Shaded" -msgstr "Shader" +msgstr "Sombreado" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Double Sided" @@ -22699,9 +22120,8 @@ msgid "No Depth Test" msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/material.cpp -#, fuzzy msgid "Fixed Size" -msgstr "Vista Frontal" +msgstr "Tamaño Fijo" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Alpha Cut" @@ -22712,119 +22132,98 @@ msgid "Alpha Scissor Threshold" msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/material.cpp -#, fuzzy msgid "Render Priority" -msgstr "Activar Prioridad" +msgstr "Prioridad de Renderización" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Outline Render Priority" -msgstr "Activar Prioridad" +msgstr "Prioridad de Renderización del Contorno" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Outline Modulate" -msgstr "Forzar Modulación en Blanco" +msgstr "Modular Contorno" #: scene/3d/label_3d.cpp scene/resources/default_theme/default_theme.cpp #: scene/resources/dynamic_font.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Font" -msgstr "Fuentes" +msgstr "Fuente" #: scene/3d/label_3d.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Horizontal Alignment" -msgstr "Horizontal Activado" +msgstr "Alineación Horizontal" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Vertical Alignment" -msgstr "Filtrar señales" +msgstr "Alineación Vertical" #: scene/3d/label_3d.cpp scene/gui/dialogs.cpp scene/gui/label.cpp -#, fuzzy msgid "Autowrap" -msgstr "AutoLoad" +msgstr "Envoltura Automática" #: scene/3d/light.cpp -#, fuzzy msgid "Indirect Energy" -msgstr "Colores de Emisión" +msgstr "Energía Indirecta" #: scene/3d/light.cpp -#, fuzzy msgid "Negative" -msgstr "GDNative" +msgstr "Negativo" #: scene/3d/light.cpp scene/resources/material.cpp #: scene/resources/visual_shader.cpp -#, fuzzy msgid "Specular" -msgstr "Modo de Regla" +msgstr "Especular" #: scene/3d/light.cpp -#, fuzzy msgid "Bake Mode" -msgstr "Modo de Bitmask" +msgstr "Modo de Bakeo" #: scene/3d/light.cpp -#, fuzzy msgid "Contact" -msgstr "Seleccionar Color" +msgstr "Contacto" #: scene/3d/light.cpp -#, fuzzy msgid "Reverse Cull Face" -msgstr "Restablecer Volumen de Bus" +msgstr "Eliminar Caras Invertidas" #: scene/3d/light.cpp servers/visual_server.cpp -#, fuzzy msgid "Directional Shadow" -msgstr "Direcciones" +msgstr "Sombra Direccional" #: scene/3d/light.cpp -#, fuzzy msgid "Split 1" -msgstr "Dividir" +msgstr "Dividir 1" #: scene/3d/light.cpp -#, fuzzy msgid "Split 2" -msgstr "Dividir" +msgstr "Dividir 2" #: scene/3d/light.cpp -#, fuzzy msgid "Split 3" -msgstr "Dividir" +msgstr "Dividir 3" #: scene/3d/light.cpp msgid "Blend Splits" msgstr "Mezclar Divisiones" #: scene/3d/light.cpp -#, fuzzy msgid "Bias Split Scale" -msgstr "Usar Ajuste de Escalado" +msgstr "Escala de División del Sesgo" #: scene/3d/light.cpp -#, fuzzy msgid "Depth Range" -msgstr "Profundidad" +msgstr "Rango de Profundidad" #: scene/3d/light.cpp msgid "Omni" msgstr "" #: scene/3d/light.cpp -#, fuzzy msgid "Shadow Mode" -msgstr "Shader" +msgstr "Modo de Sombreado" #: scene/3d/light.cpp -#, fuzzy msgid "Shadow Detail" -msgstr "Mostrar Por Defecto" +msgstr "Detalle de la Sombra" #: scene/3d/light.cpp msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." @@ -22836,9 +22235,8 @@ msgid "Spot" msgstr "" #: scene/3d/light.cpp -#, fuzzy msgid "Angle Attenuation" -msgstr "Animación" +msgstr "Atenuación del Ángulo" #: scene/3d/mesh_instance.cpp msgid "Software Skinning" @@ -22856,43 +22254,38 @@ msgid "" msgstr "" #: scene/3d/navigation.cpp scene/resources/curve.cpp -#, fuzzy msgid "Up Vector" -msgstr "Vector" +msgstr "Vector Superior" #: scene/3d/navigation.cpp -#, fuzzy msgid "Cell Height" -msgstr "Prueba" +msgstr "Altura de la Celda" #: scene/3d/navigation_agent.cpp msgid "Agent Height Offset" msgstr "" #: scene/3d/navigation_agent.cpp -#, fuzzy msgid "Ignore Y" -msgstr "[Ignorar]" +msgstr "Ignorar Y" #: scene/3d/navigation_agent.cpp -#, fuzzy msgid "" "The NavigationAgent can be used only under a Spatial inheriting parent node." -msgstr "El NavigationAgent sólo puede utilizarse bajo un nodo spatial." +msgstr "" +"El NavigationAgent solo puede utilizarse en un nodo padre de tipo Spatial." #: scene/3d/navigation_mesh_instance.cpp scene/resources/mesh_library.cpp -#, fuzzy msgid "NavMesh" -msgstr "Calcular NavMesh" +msgstr "NavMesh" #: scene/3d/navigation_obstacle.cpp -#, fuzzy msgid "" "The NavigationObstacle only serves to provide collision avoidance to a " "Spatial inheriting parent object." msgstr "" -"El NavigationObstacle sólo sirve para evitar la colisión de un objeto " -"spatial." +"El NavigationObstacle solo sirve para evitar colisiones en un objeto padre " +"de tipo Spatial." #: scene/3d/occluder.cpp msgid "No shape is set." @@ -22943,9 +22336,8 @@ msgstr "" "Billboard esté ajustado a \"Particle Billboard\"." #: scene/3d/particles.cpp -#, fuzzy msgid "Visibility AABB" -msgstr "Cambiar Visibilidad" +msgstr "Visibilidad AABB" #: scene/3d/particles.cpp msgid "Draw Passes" @@ -22969,7 +22361,6 @@ msgstr "" "el recurso Curve de su Path padre." #: scene/3d/path.cpp -#, fuzzy msgid "Rotation Mode" msgstr "Modo de Rotación" @@ -22984,65 +22375,56 @@ msgstr "" "En su lugar, cambia el tamaño en las formas de colisión de los hijos." #: scene/3d/physics_body.cpp -#, fuzzy msgid "Axis Lock" -msgstr "Eje" +msgstr "Bloquear Ejes" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear X" -msgstr "Lineal" +msgstr "Lineal X" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Y" -msgstr "Lineal" +msgstr "Lineal Y" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Z" -msgstr "Lineal" +msgstr "Lineal Z" #: scene/3d/physics_body.cpp msgid "Angular X" -msgstr "" +msgstr "Angular X" #: scene/3d/physics_body.cpp msgid "Angular Y" -msgstr "" +msgstr "Angular Y" #: scene/3d/physics_body.cpp msgid "Angular Z" -msgstr "" +msgstr "Angular Z" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion X" -msgstr "Acción" +msgstr "Movimiento X" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion Y" -msgstr "Acción" +msgstr "Movimiento Y" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion Z" -msgstr "Acción" +msgstr "Movimiento Z" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Joint Constraints" -msgstr "Constantes" +msgstr "Restringir Articulaciones" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Impulse Clamp" msgstr "" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Swing Span" -msgstr "Guardar Escena" +msgstr "Expansión de Swing" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Twist Span" @@ -23054,147 +22436,124 @@ msgid "Relaxation" msgstr "Relajación" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Enabled" -msgstr "Filtrar señales" +msgstr "Límite Angular Activado" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Upper" -msgstr "Lineal" +msgstr "Límite Angular Superior" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Lower" -msgstr "Ortogonal Angular" +msgstr "Límite Angular Inferior" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Bias" -msgstr "Lineal" +msgstr "Sesgo de Límite Angular" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Softness" -msgstr "Animación" +msgstr "Límite Angular de Suavizado" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Relaxation" -msgstr "Animación" +msgstr "Relajación del Límite Angular" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Upper" -msgstr "Lineal" +msgstr "Límite Lineal Superior" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Lower" -msgstr "Lineal" +msgstr "Límite Lineal Inferior" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Softness" -msgstr "Lineal" +msgstr "Límite Lineal de Suavizado" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Restitution" -msgstr "Lineal" +msgstr "Restitución del Límite Lineal" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Damping" -msgstr "Lineal" +msgstr "Amortiguación de Límite Lineal" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Restitution" -msgstr "Animación" +msgstr "Restitución del Límite Angular" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Damping" -msgstr "Animación" +msgstr "Amortiguación de Límite Angular" #: scene/3d/physics_body.cpp msgid "X" -msgstr "" +msgstr "X" #: scene/3d/physics_body.cpp msgid "Y" -msgstr "" +msgstr "Y" #: scene/3d/physics_body.cpp msgid "Z" -msgstr "" +msgstr "Z" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Enabled" -msgstr "Lineal" +msgstr "Límite Lineal Activado" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Spring Enabled" -msgstr "Lineal" +msgstr "Amortiguador Lineal Activado" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Spring Stiffness" -msgstr "Lineal" +msgstr "Rigidez Lineal del Amortiguador" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Spring Damping" -msgstr "Lineal" +msgstr "Atenuación Lineal del Amortiguador" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Equilibrium Point" -msgstr "Lineal" +msgstr "Punto de Equilibrio Lineal" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Restitution" -msgstr "Descripción" +msgstr "Restitución Lineal" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Damping" -msgstr "Lineal" +msgstr "Amortiguación Lineal" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Restitution" -msgstr "Descripción" +msgstr "Restitución Angular" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Damping" -msgstr "Animación" +msgstr "Amortiguación Angular" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "ERP" -msgstr "" +msgstr "ERP" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Spring Enabled" -msgstr "Filtrar señales" +msgstr "Amortiguación Angular Activada" #: scene/3d/physics_body.cpp msgid "Angular Spring Stiffness" -msgstr "" +msgstr "Rigidez del Amortiguador Angular" #: scene/3d/physics_body.cpp msgid "Angular Spring Damping" -msgstr "" +msgstr "Amortiguación Angular del Muelle" #: scene/3d/physics_body.cpp msgid "Angular Equilibrium Point" -msgstr "" +msgstr "Punto de Equilibrio Angular" #: scene/3d/physics_body.cpp msgid "Body Offset" @@ -23225,9 +22584,8 @@ msgid "Solver" msgstr "" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Exclude Nodes" -msgstr "Eliminar Nodos" +msgstr "Excluir Nodos" #: scene/3d/physics_joint.cpp msgid "Params" @@ -23238,32 +22596,28 @@ msgid "Angular Limit" msgstr "" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper" -msgstr "Mayúsculas" +msgstr "Superior" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower" -msgstr "Minúsculas" +msgstr "Inferior" #: scene/3d/physics_joint.cpp msgid "Motor" -msgstr "" +msgstr "Motor" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Target Velocity" -msgstr "Vista de Órbita Derecha" +msgstr "Velocidad del Objetivo" #: scene/3d/physics_joint.cpp msgid "Max Impulse" msgstr "Impulso Máximo" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit" -msgstr "Lineal" +msgstr "Límite Lineal" #: scene/3d/physics_joint.cpp msgid "Upper Distance" @@ -23274,57 +22628,48 @@ msgid "Lower Distance" msgstr "Distancia Inferior" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Restitution" -msgstr "Descripción" +msgstr "Restitución" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motion" -msgstr "Inicializar" +msgstr "Movimiento Lineal" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Ortho" -msgstr "Ortogonal Trasera" +msgstr "Ortogonal Lineal" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper Angle" -msgstr "Mayúsculas" +msgstr "Ángulo Superior" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower Angle" -msgstr "Minúsculas" +msgstr "Ángulo Inferior" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Angular Motion" -msgstr "Animación" +msgstr "Movimiento Angular" #: scene/3d/physics_joint.cpp msgid "Angular Ortho" msgstr "Ortogonal Angular" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit X" -msgstr "Lineal" +msgstr "Límite Lineal X" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor X" -msgstr "Inicializar" +msgstr "Motor Lineal X" #: scene/3d/physics_joint.cpp msgid "Force Limit" msgstr "Forzar Límite" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Spring X" -msgstr "Lineal" +msgstr "Amortiguación Lineal X" #: scene/3d/physics_joint.cpp msgid "Equilibrium Point" @@ -23340,22 +22685,19 @@ msgstr "" #: scene/3d/physics_joint.cpp msgid "Angular Spring X" -msgstr "" +msgstr "Amortiguación Angular X" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit Y" -msgstr "Lineal" +msgstr "Límite Lineal Y" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor Y" -msgstr "Inicializar" +msgstr "Motor Lineal Y" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Spring Y" -msgstr "Lineal" +msgstr "Amortiguación Lineal Y" #: scene/3d/physics_joint.cpp msgid "Angular Limit Y" @@ -23367,22 +22709,19 @@ msgstr "" #: scene/3d/physics_joint.cpp msgid "Angular Spring Y" -msgstr "" +msgstr "Amortiguación Angular Y" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit Z" -msgstr "Lineal" +msgstr "Límite Lineal Z" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor Z" -msgstr "Inicializar" +msgstr "Motor Lineal Z" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Spring Z" -msgstr "Lineal" +msgstr "Amortiguación Lineal Z" #: scene/3d/physics_joint.cpp msgid "Angular Limit Z" @@ -23394,7 +22733,7 @@ msgstr "" #: scene/3d/physics_joint.cpp msgid "Angular Spring Z" -msgstr "" +msgstr "Amortiguación Angular Z" #: scene/3d/portal.cpp msgid "The RoomManager should not be a child or grandchild of a Portal." @@ -23421,14 +22760,12 @@ msgid "Linked Room" msgstr "Sala Vinculada" #: scene/3d/portal.cpp -#, fuzzy msgid "Use Default Margin" -msgstr "Por defecto" +msgstr "Usar Margen por Defecto" #: scene/3d/proximity_group.cpp -#, fuzzy msgid "Group Name" -msgstr "Agrupado" +msgstr "Nombre del Grupo" #: scene/3d/proximity_group.cpp msgid "Dispatch Mode" @@ -23439,47 +22776,40 @@ msgid "Grid Radius" msgstr "Radio de Cuadrícula" #: scene/3d/ray_cast.cpp -#, fuzzy msgid "Debug Shape" -msgstr "Depurador" +msgstr "Depurar Shape" #: scene/3d/ray_cast.cpp scene/resources/style_box.cpp msgid "Thickness" msgstr "" #: scene/3d/reflection_probe.cpp scene/main/viewport.cpp -#, fuzzy msgid "Update Mode" -msgstr "Modo de Rotación" +msgstr "Modo de Actualización" #: scene/3d/reflection_probe.cpp msgid "Origin Offset" msgstr "Desplazamiento de Origen" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Box Projection" -msgstr "Proyecto" +msgstr "Proyección de Cajas" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Enable Shadows" -msgstr "Activar Ajuste" +msgstr "Activar Sombras" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Ambient Color" -msgstr "Seleccionar Color" +msgstr "Color de Ambiente" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Ambient Energy" -msgstr "Colores de Emisión" +msgstr "Energía Ambiental" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Ambient Contrib" -msgstr "Indentar a la Derecha" +msgstr "Contribución Ambiental" #: scene/3d/remote_transform.cpp msgid "" @@ -23523,9 +22853,8 @@ msgid "Bound" msgstr "" #: scene/3d/room_group.cpp -#, fuzzy msgid "Roomgroup Priority" -msgstr "Prioridad" +msgstr "Prioridad del Roomgroup" #: scene/3d/room_group.cpp msgid "The RoomManager should not be placed inside a RoomGroup." @@ -23559,80 +22888,68 @@ msgstr "" #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp #: scene/animation/animation_tree_player.cpp #: servers/audio/effects/audio_effect_delay.cpp -#, fuzzy msgid "Active" -msgstr "Acción" +msgstr "Activo" #: scene/3d/room_manager.cpp msgid "Roomlist" msgstr "" #: scene/3d/room_manager.cpp servers/visual_server.cpp -#, fuzzy msgid "PVS" -msgstr "FPS" +msgstr "PVS" #: scene/3d/room_manager.cpp -#, fuzzy msgid "PVS Mode" -msgstr "Modo desplazamiento lateral" +msgstr "Modo PVS" #: scene/3d/room_manager.cpp -#, fuzzy msgid "PVS Filename" -msgstr "Archivo ZIP" +msgstr "Nombre del Archivo PVS" #: scene/3d/room_manager.cpp servers/visual_server.cpp msgid "Gameplay" msgstr "" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Gameplay Monitor" -msgstr "Monitor" +msgstr "Monitor de Juego" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Use Secondary PVS" -msgstr "Usar Ajuste de Escalado" +msgstr "Usar PVS Secundario" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Merge Meshes" -msgstr "Malla" +msgstr "Fusionar Mallas" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Show Margins" -msgstr "Mostrar Origen" +msgstr "Mostrar Márgenes" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Debug Sprawl" -msgstr "Depurar" +msgstr "Depurar Extensión" #: scene/3d/room_manager.cpp msgid "Overlap Warning Threshold" msgstr "" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Preview Camera" -msgstr "Vista Previa" +msgstr "Vista previa de la Cámara" #: scene/3d/room_manager.cpp msgid "Portal Depth Limit" msgstr "" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Default Portal Margin" -msgstr "Asignar Margen" +msgstr "Margen del Portal por Defecto" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Roaming Expansion Margin" -msgstr "Expandir Todo" +msgstr "Margen de Expansión del Roaming" #: scene/3d/room_manager.cpp msgid "" @@ -23685,43 +23002,36 @@ msgstr "" "Asegúrate de que todas las rooms contienen geometría o límites manuales." #: scene/3d/skeleton.cpp scene/resources/skin.cpp -#, fuzzy msgid "Pose" -msgstr "Copiar Pose" +msgstr "Pose" #: scene/3d/skeleton.cpp -#, fuzzy msgid "Bound Children" -msgstr "Hijos Editables" +msgstr "Hijos Vinculados" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Pinned Points" -msgstr "Fijado %s" +msgstr "Puntos de Anclaje" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Attachments" -msgstr "Gizmos" +msgstr "Adjuntos" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Point Index" -msgstr "Obtener Índice" +msgstr "Índice de Puntos" #: scene/3d/soft_body.cpp msgid "Spatial Attachment Path" msgstr "" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Physics Enabled" -msgstr "Fotogramas de Física %" +msgstr "Física Activada" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Parent Collision Ignore" -msgstr "Crear Polígono de Colisión" +msgstr "Ignorar Colisión de los Padres" #: scene/3d/soft_body.cpp msgid "Simulation Precision" @@ -23774,36 +23084,32 @@ msgstr "" "En su lugar, cambia el tamaño en las formas de colisión de los hijos." #: scene/3d/spatial.cpp -#, fuzzy msgid "Global Translation" -msgstr "Mantener transformación global" +msgstr "Transformación Global" #: scene/3d/spatial.cpp msgid "Matrix" -msgstr "" +msgstr "Matriz" #: scene/3d/spatial.cpp -#, fuzzy msgid "Gizmo" -msgstr "Gizmos" +msgstr "Gizmo" #: scene/3d/spatial_velocity_tracker.cpp -#, fuzzy msgid "Track Physics Step" -msgstr "Fotogramas de Física %" +msgstr "Paso de Física de Pistas" #: scene/3d/spring_arm.cpp msgid "Spring Length" -msgstr "" +msgstr "Cantidad de Amortiguación" #: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp msgid "Opacity" msgstr "" #: scene/3d/sprite_3d.cpp scene/resources/material.cpp -#, fuzzy msgid "Transparent" -msgstr "Transponer" +msgstr "Transparente" #: scene/3d/sprite_3d.cpp msgid "" @@ -23822,14 +23128,12 @@ msgstr "" "Por favor, úselo como hijo de un VehicleBody." #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Per-Wheel Motion" -msgstr "Botón Bajar la Rueda" +msgstr "Movimiento por Rueda" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Engine Force" -msgstr "Documentación Online" +msgstr "Fuerza del Motor" #: scene/3d/vehicle_body.cpp msgid "Brake" @@ -23860,19 +23164,16 @@ msgid "Roll Influence" msgstr "" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Friction Slip" -msgstr "Función" +msgstr "Deslizamiento por Fricción" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Suspension" -msgstr "Expresión" +msgstr "Suspensión" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Max Force" -msgstr "Error" +msgstr "Fuerza Máxima" #: scene/3d/visibility_notifier.cpp msgid "AABB" @@ -23899,14 +23200,12 @@ msgid "Extra Cull Margin" msgstr "Margen de Sacrificio Extra" #: scene/3d/visual_instance.cpp -#, fuzzy msgid "Baked Light" -msgstr "Calcular Lightmaps" +msgstr "Bakear Luces" #: scene/3d/visual_instance.cpp -#, fuzzy msgid "Generate Lightmap" -msgstr "Generando Lightmaps" +msgstr "Generar Lightmap" #: scene/3d/visual_instance.cpp msgid "Lightmap Scale" @@ -23962,9 +23261,8 @@ msgid "Animation not found: '%s'" msgstr "No se encontró la animación: '%s'" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Mix Mode" -msgstr "Nodo Mix" +msgstr "Modo Mix" #: scene/animation/animation_blend_tree.cpp msgid "Fadein Time" @@ -23991,24 +23289,20 @@ msgid "Random Delay" msgstr "Retraso Aleatorio" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Add Amount" -msgstr "Cantidad" +msgstr "Añadir Cantidad" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Blend Amount" -msgstr "Cantidad de Escala" +msgstr "Cantidad de Mezcla" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Seek Position" -msgstr "Establecer Posición de Entrada de Curva" +msgstr "Buscar Posición" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Input Count" -msgstr "Añadir Puerto de Entrada" +msgstr "Conteo de Entradas" #: scene/animation/animation_blend_tree.cpp #: scene/animation/animation_node_state_machine.cpp @@ -24016,56 +23310,48 @@ msgid "Xfade Time" msgstr "Tiempo de Fundido Cruzado" #: scene/animation/animation_node_state_machine.cpp -#, fuzzy msgid "Switch Mode" -msgstr "Cambiar" +msgstr "Modo de Conmutación" #: scene/animation/animation_node_state_machine.cpp -#, fuzzy msgid "Auto Advance" -msgstr "Establecer avance automático" +msgstr "Auto Avance" #: scene/animation/animation_node_state_machine.cpp -#, fuzzy msgid "Advance Condition" -msgstr "Opciones Avanzadas" +msgstr "Condición de Avance" #: scene/animation/animation_player.cpp msgid "Anim Apply Reset" msgstr "Aplicar Reset de la Animación" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Current Animation" -msgstr "Establecer Animación" +msgstr "Animación Actual" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Assigned Animation" -msgstr "Añadir Animación" +msgstr "Animación Asignada" #: scene/animation/animation_player.cpp msgid "Reset On Save" msgstr "" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Current Animation Length" -msgstr "Cambiar Duración de la Animación" +msgstr "Duración Actual de la Animación" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Current Animation Position" -msgstr "Añadir Punto de Animación" +msgstr "Posición Actual de la Animación" #: scene/animation/animation_player.cpp msgid "Playback Options" msgstr "Opciones de Reproducción" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Default Blend Time" -msgstr "Theme Predeterminado" +msgstr "Tiempo de Mezcla por Defecto" #: scene/animation/animation_player.cpp msgid "Method Call Mode" @@ -24106,67 +23392,56 @@ msgid "Tree Root" msgstr "Raíz del Árbol" #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Anim Player" -msgstr "Fijar AnimationPlayer" +msgstr "Reproductor de Animación" #: scene/animation/animation_tree.cpp msgid "Root Motion" msgstr "" #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Track" -msgstr "Agregar Pista" +msgstr "Pista" #: scene/animation/animation_tree_player.cpp msgid "This node has been deprecated. Use AnimationTree instead." msgstr "Este nodo ha quedado obsoleto. Usa AnimationTree en su lugar." #: scene/animation/animation_tree_player.cpp -#, fuzzy msgid "Playback" msgstr "Reproducir" #: scene/animation/animation_tree_player.cpp -#, fuzzy msgid "Master Player" -msgstr "Pegar Parámetros" +msgstr "Reproductor Principal" #: scene/animation/animation_tree_player.cpp -#, fuzzy msgid "Base Path" -msgstr "Ruta de Exportación" +msgstr "Ruta Base" #: scene/animation/root_motion_view.cpp -#, fuzzy msgid "Animation Path" -msgstr "Animación" +msgstr "Ruta de la Animación" #: scene/animation/root_motion_view.cpp -#, fuzzy msgid "Zero Y" -msgstr "Cero" +msgstr "Cero Y" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Root Bone" -msgstr "Nombre del nodo raíz" +msgstr "Hueso Raíz" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Tip Bone" -msgstr "Huesos" +msgstr "Punta del Hueso" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Interpolation" -msgstr "Modo de Interpolación" +msgstr "Interpolación" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Override Tip Basis" -msgstr "Anulaciones" +msgstr "Anular Base de la Punta" #: scene/animation/skeleton_ik.cpp msgid "Use Magnet" @@ -24177,54 +23452,46 @@ msgid "Magnet" msgstr "" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Target Node" -msgstr "Reemparentar nodo" +msgstr "Nodo Objetivo" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Max Iterations" -msgstr "Crear Función" +msgstr "Iteraciones Máximas" #: scene/animation/tween.cpp msgid "Playback Process Mode" msgstr "" #: scene/animation/tween.cpp -#, fuzzy msgid "Playback Speed" -msgstr "Reproducir Escena" +msgstr "Velocidad de Reproducción" #: scene/audio/audio_stream_player.cpp -#, fuzzy msgid "Mix Target" -msgstr "Objetivo" +msgstr "Objetivo de la Mezcla" #: scene/gui/aspect_ratio_container.cpp scene/gui/range.cpp #: servers/audio/effects/audio_effect_compressor.cpp -#, fuzzy msgid "Ratio" -msgstr "Mantener Proporciones" +msgstr "Proporción" #: scene/gui/aspect_ratio_container.cpp scene/gui/texture_button.cpp #: scene/gui/texture_rect.cpp -#, fuzzy msgid "Stretch Mode" -msgstr "Modo de Selección" +msgstr "Modo de Estiramiento" #: scene/gui/aspect_ratio_container.cpp scene/gui/box_container.cpp msgid "Alignment" msgstr "" #: scene/gui/base_button.cpp -#, fuzzy msgid "Shortcut In Tooltip" -msgstr "Mostrar Origen" +msgstr "Atajo en el Tooltip" #: scene/gui/base_button.cpp -#, fuzzy msgid "Action Mode" -msgstr "Modo de Icono" +msgstr "Modo de Acción" #: scene/gui/base_button.cpp msgid "Enabled Focus Mode" @@ -24235,38 +23502,33 @@ msgid "Keep Pressed Outside" msgstr "" #: scene/gui/base_button.cpp scene/gui/shortcut.cpp -#, fuzzy msgid "Shortcut" -msgstr "Atajos" +msgstr "Atajo" #: scene/gui/base_button.cpp -#, fuzzy msgid "Group" -msgstr "Grupos" +msgstr "Grupo" #: scene/gui/button.cpp scene/gui/label.cpp -#, fuzzy msgid "Clip Text" -msgstr "Copiar Texto" +msgstr "Texto del Clip" #: scene/gui/button.cpp scene/gui/label.cpp scene/gui/line_edit.cpp #: scene/gui/spin_box.cpp msgid "Align" -msgstr "" +msgstr "Alinear" #: scene/gui/button.cpp msgid "Icon Align" -msgstr "" +msgstr "Alinear Icono" #: scene/gui/button.cpp -#, fuzzy msgid "Expand Icon" -msgstr "Expandir Todo" +msgstr "Expandir Icono" #: scene/gui/center_container.cpp -#, fuzzy msgid "Use Top Left" -msgstr "Superior Izquierda" +msgstr "Usar Superior Izquierda" #: scene/gui/color_picker.cpp msgid "" @@ -24279,34 +23541,28 @@ msgstr "" "Clic der: Borrar configuración predeterminada" #: scene/gui/color_picker.cpp -#, fuzzy msgid "Edit Alpha" -msgstr "Editar Polígono" +msgstr "Editar Alfa" #: scene/gui/color_picker.cpp -#, fuzzy msgid "HSV Mode" -msgstr "Modo de Selección" +msgstr "Modo HSV" #: scene/gui/color_picker.cpp -#, fuzzy msgid "Raw Mode" -msgstr "Modo desplazamiento lateral" +msgstr "Modo Raw" #: scene/gui/color_picker.cpp -#, fuzzy msgid "Deferred Mode" -msgstr "Diferido" +msgstr "Modo Diferido" #: scene/gui/color_picker.cpp -#, fuzzy msgid "Presets Enabled" -msgstr "Ajustes preestablecidos" +msgstr "Preajustes Activados" #: scene/gui/color_picker.cpp -#, fuzzy msgid "Presets Visible" -msgstr "Act./Desact. Visible" +msgstr "Preajustes Visibles" #: scene/gui/color_picker.cpp msgid "Pick a color from the editor window." @@ -24336,9 +23592,8 @@ msgstr "" "sencillo." #: scene/gui/control.cpp -#, fuzzy msgid "Theme Overrides" -msgstr "Anulaciones" +msgstr "Anulación de Temas" #: scene/gui/control.cpp msgid "" @@ -24350,14 +23605,12 @@ msgstr "" "Filtro del Ratón en \"Stop\" o \"Pass\"." #: scene/gui/control.cpp -#, fuzzy msgid "Anchor" -msgstr "Sólo anclado" +msgstr "Anclaje" #: scene/gui/control.cpp -#, fuzzy msgid "Grow Direction" -msgstr "Direcciones" +msgstr "Dirección de Crecimiento" #: scene/gui/control.cpp scene/resources/navigation_mesh.cpp msgid "Min Size" @@ -24368,40 +23621,36 @@ msgid "Pivot Offset" msgstr "Pivote de Desplazamiento" #: scene/gui/control.cpp -#, fuzzy msgid "Clip Content" -msgstr "Constante de Clase" +msgstr "Contenido del Clip" #: scene/gui/control.cpp scene/resources/visual_shader_nodes.cpp msgid "Hint" msgstr "" #: scene/gui/control.cpp -#, fuzzy msgid "Tooltip" -msgstr "Herramientas" +msgstr "Tooltip" #: scene/gui/control.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Focus" -msgstr "Foco en Ruta" +msgstr "Foco" #: scene/gui/control.cpp msgid "Neighbour Left" -msgstr "" +msgstr "Vecino Izquierda" #: scene/gui/control.cpp msgid "Neighbour Top" -msgstr "" +msgstr "Vecino Superior" #: scene/gui/control.cpp msgid "Neighbour Right" -msgstr "" +msgstr "Vecino Derecha" #: scene/gui/control.cpp -#, fuzzy msgid "Neighbour Bottom" -msgstr "Centro Inferior" +msgstr "Vecino Inferior" #: scene/gui/control.cpp msgid "Next" @@ -24428,23 +23677,20 @@ msgid "Size Flags" msgstr "Tamaño de los Indicadores" #: scene/gui/control.cpp -#, fuzzy msgid "Stretch Ratio" -msgstr "Modo de Selección" +msgstr "Relación de Estiramiento" #: scene/gui/control.cpp -#, fuzzy msgid "Theme Type Variation" -msgstr "Propiedades del Theme" +msgstr "Propiedades del Tema" #: scene/gui/dialogs.cpp msgid "Window Title" msgstr "" #: scene/gui/dialogs.cpp -#, fuzzy msgid "Dialog" -msgstr "Diálogo XForm" +msgstr "Diálogo" #: scene/gui/dialogs.cpp msgid "Hide On OK" @@ -24459,18 +23705,16 @@ msgid "Please Confirm..." msgstr "Por favor, Confirma..." #: scene/gui/file_dialog.cpp -#, fuzzy msgid "Mode Overrides Title" -msgstr "Elemento de Anulación" +msgstr "Sobreescritura" #: scene/gui/file_dialog.cpp msgid "Must use a valid extension." msgstr "Debe tener una extensión válida." #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Right Disconnects" -msgstr "Desconectar" +msgstr "Desconexión Correcta" #: scene/gui/graph_edit.cpp msgid "Scroll Offset" @@ -24481,24 +23725,20 @@ msgid "Snap Distance" msgstr "Ajustar Distancia" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom Min" -msgstr "Acercar Zoom" +msgstr "Zoom Mínimo" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom Max" -msgstr "Acercar Zoom" +msgstr "Zoom Máximo" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom Step" -msgstr "Alejar Zoom" +msgstr "Paso Zoom" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Show Zoom Label" -msgstr "Mostrar Huesos" +msgstr "Mostrar Etiqueta Zoom" #: scene/gui/graph_edit.cpp scene/gui/text_edit.cpp #: scene/resources/default_theme/default_theme.cpp @@ -24510,58 +23750,50 @@ msgid "Enable grid minimap." msgstr "Activar minimapa de cuadrícula." #: scene/gui/graph_node.cpp -#, fuzzy msgid "Show Close" -msgstr "Mostrar Huesos" +msgstr "Mostrar Cerrar" #: scene/gui/graph_node.cpp scene/gui/option_button.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Selected" -msgstr "Seleccionar" +msgstr "Seleccionado" #: scene/gui/graph_node.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Comment" -msgstr "Confirmar" +msgstr "Comentario" #: scene/gui/graph_node.cpp msgid "Overlay" msgstr "" #: scene/gui/grid_container.cpp scene/gui/item_list.cpp scene/gui/tree.cpp -#, fuzzy msgid "Columns" -msgstr "Volumen" +msgstr "Columnas" #: scene/gui/item_list.cpp scene/gui/popup_menu.cpp scene/gui/text_edit.cpp #: scene/gui/tree.cpp scene/main/viewport.cpp -#, fuzzy msgid "Timers" -msgstr "Tiempo" +msgstr "Temporizadores" #: scene/gui/item_list.cpp scene/gui/popup_menu.cpp scene/gui/tree.cpp msgid "Incremental Search Max Interval Msec" msgstr "" #: scene/gui/item_list.cpp scene/gui/tree.cpp -#, fuzzy msgid "Allow Reselect" -msgstr "Aplicar Restablecer" +msgstr "Permitir Volver A Seleccionar" #: scene/gui/item_list.cpp scene/gui/tree.cpp -#, fuzzy msgid "Allow RMB Select" -msgstr "Rellenar Selección" +msgstr "Permitir Selección Con Botón Derecho Del Ratón" #: scene/gui/item_list.cpp msgid "Max Text Lines" msgstr "" #: scene/gui/item_list.cpp -#, fuzzy msgid "Auto Height" -msgstr "Prueba" +msgstr "Altura Automática" #: scene/gui/item_list.cpp msgid "Max Columns" @@ -24580,23 +23812,20 @@ msgid "Icon Scale" msgstr "Escala de Icono" #: scene/gui/item_list.cpp -#, fuzzy msgid "Fixed Icon Size" -msgstr "Vista Frontal" +msgstr "Tamaño Fijo de Icono" #: scene/gui/label.cpp -#, fuzzy msgid "V Align" -msgstr "Asignar" +msgstr "Alineamiento V" #: scene/gui/label.cpp scene/gui/rich_text_label.cpp msgid "Visible Characters" msgstr "Caracteres Visibles" #: scene/gui/label.cpp scene/gui/rich_text_label.cpp -#, fuzzy msgid "Percent Visible" -msgstr "Act./Desact. Visible" +msgstr "Porcentaje Visible" #: scene/gui/label.cpp msgid "Lines Skipped" @@ -24623,34 +23852,28 @@ msgid "Expand To Text Length" msgstr "" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Context Menu Enabled" -msgstr "Ayuda Contextual" +msgstr "Menú Contextual Activado" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Virtual Keyboard Enabled" -msgstr "Filtrar señales" +msgstr "Teclado Virtual Activado" #: scene/gui/line_edit.cpp -#, fuzzy msgid "Clear Button Enabled" -msgstr "Filtrar señales" +msgstr "Botón de Borrado Activado" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Shortcut Keys Enabled" -msgstr "Atajos" +msgstr "Atajos Activados" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Middle Mouse Paste Enabled" -msgstr "Filtrar señales" +msgstr "Pegar Con Botón Intermedio Ratón Activado" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Selecting Enabled" -msgstr "Sólo selección" +msgstr "Selección Activada" #: scene/gui/line_edit.cpp scene/gui/rich_text_label.cpp #: scene/gui/text_edit.cpp @@ -24658,14 +23881,12 @@ msgid "Deselect On Focus Loss Enabled" msgstr "" #: scene/gui/line_edit.cpp -#, fuzzy msgid "Right Icon" -msgstr "Botón Derecho" +msgstr "Icono Derecho" #: scene/gui/line_edit.cpp -#, fuzzy msgid "Placeholder" -msgstr "Cargar Como Placeholder" +msgstr "Marcador" #: scene/gui/line_edit.cpp msgid "Alpha" @@ -24688,24 +23909,20 @@ msgid "Underline" msgstr "" #: scene/gui/menu_button.cpp -#, fuzzy msgid "Switch On Hover" -msgstr "Cambiar" +msgstr "Cambiar Al Pasar Por Encima" #: scene/gui/nine_patch_rect.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Draw Center" -msgstr "Centro" +msgstr "Dibujar al Centro" #: scene/gui/nine_patch_rect.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Region Rect" -msgstr "Establecer Region Rect" +msgstr "Región Rectángulo" #: scene/gui/nine_patch_rect.cpp -#, fuzzy msgid "Patch Margin" -msgstr "Asignar Margen" +msgstr "Parche de Margen" #: scene/gui/nine_patch_rect.cpp scene/resources/style_box.cpp msgid "Axis Stretch" @@ -24724,14 +23941,12 @@ msgstr "" "como Stretch en su lugar." #: scene/gui/popup.cpp -#, fuzzy msgid "Popup" -msgstr "Rellenar" +msgstr "Popup" #: scene/gui/popup.cpp -#, fuzzy msgid "Exclusive" -msgstr "Inclusivo" +msgstr "Exclusivo" #: scene/gui/popup.cpp msgid "" @@ -24744,28 +23959,24 @@ msgstr "" "edición, pero se esconderán al iniciar." #: scene/gui/popup_menu.cpp -#, fuzzy msgid "Hide On Item Selection" -msgstr "Centrar Selección" +msgstr "Ocultar Al Seleccionar Elemento" #: scene/gui/popup_menu.cpp -#, fuzzy msgid "Hide On Checkable Item Selection" -msgstr "Eliminar Selección de GridMap" +msgstr "Ocultar Al Seleccionar Elemento Activable" #: scene/gui/popup_menu.cpp -#, fuzzy msgid "Hide On State Item Selection" -msgstr "Eliminar Selección" +msgstr "Ocultar Al Seleccionar Elemento de Estado" #: scene/gui/popup_menu.cpp msgid "Submenu Popup Delay" msgstr "" #: scene/gui/popup_menu.cpp -#, fuzzy msgid "Allow Search" -msgstr "Buscar" +msgstr "Permitir Búsqueda" #: scene/gui/progress_bar.cpp msgid "Percent" @@ -24776,28 +23987,24 @@ msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Si \"Exp Edit\" está activado, \"Min Value\" debe ser mayor que 0." #: scene/gui/range.cpp scene/resources/curve.cpp -#, fuzzy msgid "Min Value" -msgstr "Fijar Valor" +msgstr "Valor Mínimo" #: scene/gui/range.cpp scene/resources/curve.cpp -#, fuzzy msgid "Max Value" -msgstr "Valor" +msgstr "Valor Máximo" #: scene/gui/range.cpp msgid "Page" msgstr "Página" #: scene/gui/range.cpp -#, fuzzy msgid "Exp Edit" -msgstr "Editar" +msgstr "Editar Exp" #: scene/gui/range.cpp -#, fuzzy msgid "Rounded" -msgstr "Agrupado" +msgstr "Redondeado" #: scene/gui/range.cpp msgid "Allow Greater" @@ -24808,24 +24015,20 @@ msgid "Allow Lesser" msgstr "" #: scene/gui/reference_rect.cpp -#, fuzzy msgid "Border Color" -msgstr "Cambiar Nombre del Elemento Color" +msgstr "Color Del Borde" #: scene/gui/reference_rect.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Border Width" -msgstr "Píxeles del Borde" +msgstr "Anchura Del Borde" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Relative Index" -msgstr "Obtener Índice" +msgstr "Índice Relativo" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Absolute Index" -msgstr "Auto Sangría" +msgstr "Índice Absoluto" #: scene/gui/rich_text_effect.cpp msgid "Elapsed Time" @@ -24834,7 +24037,7 @@ msgstr "Tiempo Transcurrido" #: scene/gui/rich_text_effect.cpp #, fuzzy msgid "Env" -msgstr "Fin" +msgstr "Env" #: scene/gui/rich_text_effect.cpp msgid "Character" @@ -24853,9 +24056,8 @@ msgid "Tab Size" msgstr "Tamaño de Tabulación" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Fit Content Height" -msgstr "Pintar Peso de Huesos" +msgstr "Ajustar Altura Del Contenido" #: scene/gui/rich_text_label.cpp msgid "Scroll Active" @@ -24866,23 +24068,20 @@ msgid "Scroll Following" msgstr "" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Selection Enabled" -msgstr "Sólo selección" +msgstr "Selección Activada" #: scene/gui/rich_text_label.cpp scene/gui/text_edit.cpp msgid "Override Selected Font Color" msgstr "Sobrescribir Color de Fuente Seleccionada" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Custom Effects" -msgstr "Mover Efecto de Bus" +msgstr "Efectos Personalizados" #: scene/gui/scroll_bar.cpp -#, fuzzy msgid "Custom Step" -msgstr "CustomNode" +msgstr "Paso Personalizado" #: scene/gui/scroll_container.cpp msgid "" @@ -24895,18 +24094,16 @@ msgstr "" "manualmente el tamaño mínimo personalizado." #: scene/gui/scroll_container.cpp -#, fuzzy msgid "Follow Focus" -msgstr "Llenar superficie" +msgstr "Seguir Focus" #: scene/gui/scroll_container.cpp msgid "Horizontal Enabled" msgstr "Horizontal Activado" #: scene/gui/scroll_container.cpp -#, fuzzy msgid "Vertical Enabled" -msgstr "Filtrar señales" +msgstr "Vertical Activada" #: scene/gui/scroll_container.cpp msgid "Default Scroll Deadzone" @@ -24917,9 +24114,8 @@ msgid "Scrollable" msgstr "" #: scene/gui/slider.cpp -#, fuzzy msgid "Tick Count" -msgstr "Seleccionar Color" +msgstr "Cantidad De Marcas" #: scene/gui/slider.cpp msgid "Ticks On Borders" @@ -24938,14 +24134,12 @@ msgid "Split Offset" msgstr "Desplazamiento de División" #: scene/gui/split_container.cpp scene/gui/tree.cpp -#, fuzzy msgid "Collapsed" -msgstr "Colapsar Todo" +msgstr "Colapsado" #: scene/gui/split_container.cpp -#, fuzzy msgid "Dragger Visibility" -msgstr "Cambiar Visibilidad" +msgstr "Visibilidad de los Arrastradores" #: scene/gui/tab_container.cpp scene/gui/tabs.cpp msgid "Tab Align" @@ -24956,9 +24150,8 @@ msgid "Current Tab" msgstr "Pestaña Actual" #: scene/gui/tab_container.cpp -#, fuzzy msgid "Tabs Visible" -msgstr "Act./Desact. Visible" +msgstr "Pestañas Visibles" #: scene/gui/tab_container.cpp msgid "All Tabs In Front" @@ -24985,33 +24178,28 @@ msgid "Readonly" msgstr "" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Bookmark Gutter" -msgstr "Marcadores" +msgstr "Canalón de Marcadores" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Breakpoint Gutter" -msgstr "Saltar Breakpoints" +msgstr "Canalón de Puntos de Ruptura" #: scene/gui/text_edit.cpp msgid "Fold Gutter" -msgstr "Plegar Gutter" +msgstr "Canalón Plegable" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Drag And Drop Selection Enabled" -msgstr "Sólo selección" +msgstr "Selección de Arrastrar y Soltar Activada" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Hiding Enabled" -msgstr "Activar" +msgstr "Ocultación Activada" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Wrap Enabled" -msgstr "Activar" +msgstr "Ajuste Activado" #: scene/gui/text_edit.cpp msgid "Scroll Vertical" @@ -25026,9 +24214,8 @@ msgid "Draw" msgstr "Dibujar" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Block Mode" -msgstr "Desbloquear Nodo" +msgstr "Modo Bloque" #: scene/gui/text_edit.cpp msgid "Moving By Right Click" @@ -25047,34 +24234,29 @@ msgid "Hover" msgstr "" #: scene/gui/texture_button.cpp -#, fuzzy msgid "Focused" -msgstr "Foco en Ruta" +msgstr "Enfocado" #: scene/gui/texture_button.cpp -#, fuzzy msgid "Click Mask" -msgstr "Modo de Colisión" +msgstr "Máscara de Clic" #: scene/gui/texture_button.cpp scene/gui/texture_rect.cpp #: scene/gui/video_player.cpp -#, fuzzy msgid "Expand" -msgstr "Expandir Todo" +msgstr "Expandir" #: scene/gui/texture_progress.cpp msgid "Under" msgstr "" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Over" -msgstr "Sobreescribir" +msgstr "Sobre" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Progress" -msgstr "Propiedades del Theme" +msgstr "Progreso" #: scene/gui/texture_progress.cpp msgid "Progress Offset" @@ -25093,43 +24275,36 @@ msgid "Radial Fill" msgstr "" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Initial Angle" -msgstr "Inicializar" +msgstr "Ángulo Inicial" #: scene/gui/texture_progress.cpp msgid "Fill Degrees" msgstr "Completar Grados" #: scene/gui/texture_progress.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Center Offset" -msgstr "Centro Izquierda" +msgstr "Desplazamiento Central" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Nine Patch Stretch" -msgstr "Modo de Interpolación" +msgstr "Estiramiento de Nine Patch" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Stretch Margin Left" -msgstr "Asignar Margen" +msgstr "Estiramiento de Margen Izquierdo" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Stretch Margin Top" -msgstr "Asignar Margen" +msgstr "Estiramiento de Margen Superior" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Stretch Margin Right" -msgstr "Asignar Margen" +msgstr "Estiramiento de Margen Derecho" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Stretch Margin Bottom" -msgstr "Modo de Selección" +msgstr "Estiramiento de Margen Inferior" #: scene/gui/tree.cpp msgid "Custom Minimum Height" @@ -25140,14 +24315,12 @@ msgid "(Other)" msgstr "(Otros)" #: scene/gui/tree.cpp -#, fuzzy msgid "Column Titles Visible" -msgstr "Act./Desact. Visible" +msgstr "Títulos de Columnas Visibles" #: scene/gui/tree.cpp -#, fuzzy msgid "Hide Folding" -msgstr "Botón Desactivado" +msgstr "Plegado de Pieles" #: scene/gui/tree.cpp msgid "Hide Root" @@ -25158,43 +24331,36 @@ msgid "Drop Mode Flags" msgstr "" #: scene/gui/video_player.cpp -#, fuzzy msgid "Audio Track" -msgstr "Agregar Pista" +msgstr "Pista de Audio" #: scene/gui/video_player.cpp scene/main/scene_tree.cpp scene/main/timer.cpp msgid "Paused" -msgstr "" +msgstr "Pausado" #: scene/gui/video_player.cpp -#, fuzzy msgid "Buffering Msec" -msgstr "Vista Trasera" +msgstr "Buffering Msec" #: scene/gui/video_player.cpp -#, fuzzy msgid "Stream Position" -msgstr "Establecer Posición de Entrada de Curva" +msgstr "Posición del Stream" #: scene/gui/viewport_container.cpp -#, fuzzy msgid "Stretch Shrink" -msgstr "Buscar" +msgstr "Encogimiento por Estiramiento" #: scene/main/canvas_layer.cpp -#, fuzzy msgid "Follow Viewport" -msgstr "Mostrar Viewport" +msgstr "Seguir el Viewport" #: scene/main/http_request.cpp -#, fuzzy msgid "Download File" -msgstr "Descargar" +msgstr "Descargar Archivo" #: scene/main/http_request.cpp -#, fuzzy msgid "Download Chunk Size" -msgstr "Descargando" +msgstr "Descargar Tamaño del Fragmento" #: scene/main/http_request.cpp msgid "Body Size Limit" @@ -25215,89 +24381,76 @@ msgid "" msgstr "" #: scene/main/node.cpp -#, fuzzy msgid "Name Num Separator" -msgstr "Separador con nombre" +msgstr "Separador Numérico del Nombre" #: scene/main/node.cpp msgid "Name Casing" msgstr "" #: scene/main/node.cpp -#, fuzzy msgid "Editor Description" -msgstr "Descripción" +msgstr "Descripción del Editor" #: scene/main/node.cpp -#, fuzzy msgid "Pause Mode" -msgstr "Modo desplazamiento lateral" +msgstr "Modo Pausa" #: scene/main/node.cpp -#, fuzzy msgid "Physics Interpolation Mode" -msgstr "Modo de Interpolación" +msgstr "Modo de Interpolación Física" #: scene/main/node.cpp -#, fuzzy msgid "Display Folded" -msgstr "Mostrar Sin Sombreado" +msgstr "Vista Plegada" #: scene/main/node.cpp -#, fuzzy msgid "Filename" -msgstr "Renombrar" +msgstr "Nombre del Archivo" #: scene/main/node.cpp msgid "Owner" msgstr "Propietario" #: scene/main/node.cpp scene/main/scene_tree.cpp -#, fuzzy msgid "Multiplayer" -msgstr "Multiplicar %s" +msgstr "Multijugador" #: scene/main/node.cpp msgid "Custom Multiplayer" msgstr "Multijugador Personalizado" #: scene/main/node.cpp -#, fuzzy msgid "Process Priority" -msgstr "Activar Prioridad" +msgstr "Prioridad del Proceso" #: scene/main/scene_tree.cpp scene/main/timer.cpp -#, fuzzy msgid "Time Left" -msgstr "Superior Izquierda" +msgstr "Tiempo Restante" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Debug Collisions Hint" -msgstr "Modo de Colisión" +msgstr "Sugerencia de Depuración de Colisiones" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Debug Navigation Hint" -msgstr "Modo de Navegación" +msgstr "Sugerencia de Depuración de Navegación" #: scene/main/scene_tree.cpp msgid "Use Font Oversampling" msgstr "" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Edited Scene Root" -msgstr "Nueva Raíz de Escena" +msgstr "Escena Raíz Editada" #: scene/main/scene_tree.cpp msgid "Root" msgstr "" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Multiplayer Poll" -msgstr "Multiplicar %s" +msgstr "Encuesta Multijugador" #: scene/main/scene_tree.cpp scene/resources/mesh_library.cpp #: scene/resources/shape_2d.cpp @@ -25309,32 +24462,28 @@ msgid "Shape Color" msgstr "" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Contact Color" -msgstr "Seleccionar Color" +msgstr "Color de Contacto" #: scene/main/scene_tree.cpp msgid "Geometry Color" msgstr "" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Disabled Geometry Color" -msgstr "Desactivar Elemento" +msgstr "Color de la Geometría Desactivada" #: scene/main/scene_tree.cpp msgid "Max Contacts Displayed" msgstr "" #: scene/main/scene_tree.cpp scene/resources/shape_2d.cpp -#, fuzzy msgid "Draw 2D Outlines" -msgstr "Crear Outline" +msgstr "Dibujar Contornos 2D" #: scene/main/scene_tree.cpp servers/visual_server.cpp -#, fuzzy msgid "Reflections" -msgstr "Direcciones" +msgstr "Reflexiones" #: scene/main/scene_tree.cpp msgid "Atlas Size" @@ -25365,9 +24514,8 @@ msgid "Use 32 BPC Depth" msgstr "" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Default Environment" -msgstr "Ver Entorno" +msgstr "Entorno por Defecto" #: scene/main/scene_tree.cpp msgid "" @@ -25378,9 +24526,8 @@ msgstr "" "(Rendering -> Environment -> Default Environment) no se ha podido cargar." #: scene/main/scene_tree.cpp -#, fuzzy msgid "Enable Object Picking" -msgstr "Activar Papel Cebolla" +msgstr "Activar Selección de Objetos" #: scene/main/timer.cpp msgid "" @@ -25400,9 +24547,8 @@ msgid "Autostart" msgstr "Inicio Automático" #: scene/main/viewport.cpp -#, fuzzy msgid "Viewport Path" -msgstr "Ruta de Exportación" +msgstr "Ruta del Viewport" #: scene/main/viewport.cpp msgid "" @@ -25420,65 +24566,64 @@ msgid "" "Effects.\n" "HDR will be disabled for this Viewport." msgstr "" +"Este Viewport tiene HDR habilitado, pero su uso está establecido en 2D o 2D " +"sin muestreo.\n" +"El HDR solo está soportado en los Viewports que tienen su uso establecido en " +"3D o 3D Sin Efectos.\n" +"El HDR estará desactivado para esta ventana." #: scene/main/viewport.cpp msgid "ARVR" -msgstr "" +msgstr "ARVR" #: scene/main/viewport.cpp -#, fuzzy msgid "Size Override Stretch" -msgstr "Elemento de Anulación" +msgstr "Anulación del Tamaño de Estiramiento" #: scene/main/viewport.cpp msgid "Own World" -msgstr "" +msgstr "Mundo Propio" #: scene/main/viewport.cpp scene/resources/world_2d.cpp msgid "World" -msgstr "" +msgstr "Mundo" #: scene/main/viewport.cpp msgid "World 2D" -msgstr "" +msgstr "Mundo 2D" #: scene/main/viewport.cpp -#, fuzzy msgid "Transparent BG" -msgstr "Transponer" +msgstr "Fondo Transparente" #: scene/main/viewport.cpp -#, fuzzy msgid "Handle Input Locally" -msgstr "Cambiar Valor de Entrada" +msgstr "Manejar Entradas Localmente" #: scene/main/viewport.cpp msgid "FXAA" -msgstr "" +msgstr "FXAA" #: scene/main/viewport.cpp #, fuzzy msgid "Debanding" -msgstr "Vinculación" +msgstr "Debanding" #: scene/main/viewport.cpp -#, fuzzy msgid "Disable 3D" -msgstr "Desactivar Elemento" +msgstr "Desactivar 3D" #: scene/main/viewport.cpp -#, fuzzy msgid "Keep 3D Linear" -msgstr "Izquierda Lineal" +msgstr "Mantener 3D Lineal" #: scene/main/viewport.cpp msgid "Render Direct To Screen" -msgstr "" +msgstr "Renderización Directa en Pantalla" #: scene/main/viewport.cpp -#, fuzzy msgid "Debug Draw" -msgstr "Depurar" +msgstr "Depurar Dibujo" #: scene/main/viewport.cpp msgid "Render Target" @@ -25489,34 +24634,28 @@ msgid "V Flip" msgstr "" #: scene/main/viewport.cpp -#, fuzzy msgid "Clear Mode" -msgstr "Modo de Regla" +msgstr "Modo de Limpieza" #: scene/main/viewport.cpp -#, fuzzy msgid "Enable 2D" -msgstr "Activar" +msgstr "Activar 2D" #: scene/main/viewport.cpp -#, fuzzy msgid "Enable 3D" -msgstr "Activar" +msgstr "Activar 3D" #: scene/main/viewport.cpp -#, fuzzy msgid "Object Picking" -msgstr "Activar Papel Cebolla" +msgstr "Selección de Objetos" #: scene/main/viewport.cpp -#, fuzzy msgid "Disable Input" -msgstr "Desactivar Elemento" +msgstr "Desactivar Entrada" #: scene/main/viewport.cpp servers/visual_server.cpp -#, fuzzy msgid "Shadow Atlas" -msgstr "Nuevo Atlas" +msgstr "Sombra del Atlas" #: scene/main/viewport.cpp msgid "Quad 0" @@ -25535,78 +24674,66 @@ msgid "Quad 3" msgstr "" #: scene/main/viewport.cpp -#, fuzzy msgid "Canvas Transform" -msgstr "Reestablecer Transformación" +msgstr "Transformación del Canvas" #: scene/main/viewport.cpp -#, fuzzy msgid "Global Canvas Transform" -msgstr "Mantener transformación global" +msgstr "Transformación Global del Canvas" #: scene/main/viewport.cpp msgid "Tooltip Delay (sec)" -msgstr "" +msgstr "Retraso del Tooltip (sec)" #: scene/register_scene_types.cpp #, fuzzy msgid "Swap OK Cancel" -msgstr "Cancelar UI" +msgstr "Intercambio OK Cancelar" #: scene/register_scene_types.cpp -#, fuzzy msgid "Layer Names" -msgstr "Nombre" +msgstr "Nombres de las Capas" #: scene/register_scene_types.cpp -#, fuzzy msgid "2D Render" -msgstr "Renderización" +msgstr "Renderización 2D" #: scene/register_scene_types.cpp -#, fuzzy msgid "3D Render" -msgstr "Renderización" +msgstr "Renderización 3D" #: scene/register_scene_types.cpp -#, fuzzy msgid "2D Physics" -msgstr "Física" +msgstr "Física 2D" #: scene/register_scene_types.cpp -#, fuzzy msgid "3D Physics" -msgstr "Física" +msgstr "Física 3D" #: scene/register_scene_types.cpp -#, fuzzy msgid "2D Navigation" -msgstr "Navegación" +msgstr "Navegación 2D" #: scene/register_scene_types.cpp -#, fuzzy msgid "3D Navigation" -msgstr "Navegación" +msgstr "Navegación 3D" #: scene/register_scene_types.cpp msgid "Use hiDPI" msgstr "" #: scene/register_scene_types.cpp -#, fuzzy msgid "Custom" -msgstr "CustomNode" +msgstr "Personalizado" #: scene/register_scene_types.cpp -#, fuzzy msgid "Custom Font" -msgstr "CustomNode" +msgstr "Fuente Personalizada" #: scene/resources/audio_stream_sample.cpp #: servers/audio/effects/audio_stream_generator.cpp servers/audio_server.cpp -#, fuzzy msgid "Mix Rate" -msgstr "Nodo Mix" +msgstr "Tasa de Mezcla" #: scene/resources/audio_stream_sample.cpp msgid "Stereo" @@ -25617,9 +24744,8 @@ msgid "Segments" msgstr "Segmentos" #: scene/resources/curve.cpp -#, fuzzy msgid "Bake Resolution" -msgstr "Media Resolución" +msgstr "Bakear Resolución" #: scene/resources/curve.cpp msgid "Bake Interval" @@ -25630,77 +24756,64 @@ msgid "Panel" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color" -msgstr "Seleccionar Color" +msgstr "Color de la Fuente" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Pressed" -msgstr "Color Hueso 1" +msgstr "Color de la Fuente Presionada" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Hover" -msgstr "Color Hueso 1" +msgstr "Color de la Fuente por Encima" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Focus" -msgstr "Llenar superficie" +msgstr "Color de la Fuente Enfocada" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Disabled" -msgstr "Clip Deshabilitado" +msgstr "Color de la Fuente Desactivada" #: scene/resources/default_theme/default_theme.cpp msgid "H Separation" msgstr "Separación en H" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Underline Spacing" -msgstr "Espaciado de Línea" +msgstr "Espaciado del Subrayado" #: scene/resources/default_theme/default_theme.cpp msgid "Arrow" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Arrow Margin" -msgstr "Asignar Margen" +msgstr "Margen de la Flecha" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Hover Pressed" -msgstr "Preset" +msgstr "Presionado por Encima" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Checked Disabled" -msgstr "Chequeable" +msgstr "Marcado Desactivado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Unchecked" -msgstr "Chequeado" +msgstr "Sin marcar" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Unchecked Disabled" -msgstr "Desactivar Elemento" +msgstr "Sin marcar Desactivado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Radio Checked" -msgstr "Chequeado" +msgstr "Radio Marcado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Radio Checked Disabled" -msgstr "(Editor Desactivado)" +msgstr "Radio Marcado Desactivado" #: scene/resources/default_theme/default_theme.cpp msgid "Radio Unchecked" @@ -25721,27 +24834,23 @@ msgstr "" #: scene/resources/default_theme/default_theme.cpp #, fuzzy msgid "On Disabled" -msgstr "Desactivar Elemento" +msgstr "Desactivado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Off" -msgstr "Desplazamiento" +msgstr "Apagado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Off Disabled" -msgstr "Desactivar Elemento" +msgstr "Apagado Desactivado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Shadow" -msgstr "Color Hueso 1" +msgstr "Color de la Sombra de la Fuente" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Outline Modulate" -msgstr "Forzar Modulación en Blanco" +msgstr "Modulación del Contorno de la Fuente" #: scene/resources/default_theme/default_theme.cpp msgid "Shadow Offset X" @@ -25752,59 +24861,50 @@ msgid "Shadow Offset Y" msgstr "Desplazamiento de la Sombra en Y" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Shadow As Outline" -msgstr "Mostrar Contorno Anterior" +msgstr "Sombra como Contorno" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Selected" -msgstr "Desbloquear Seleccionado" +msgstr "Color de Fuente Seleccionada" #: scene/resources/default_theme/default_theme.cpp msgid "Font Color Uneditable" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Cursor Color" -msgstr "CustomNode" +msgstr "Color del Cursor" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Clear Button Color" -msgstr "Filtrar señales" +msgstr "Limpiar Color del Botón" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Clear Button Color Pressed" -msgstr "Filtrar señales" +msgstr "Limpiar Color del Botón Presionado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Minimum Spaces" -msgstr "Escena Principal" +msgstr "Espacios Mínimos" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "BG" -msgstr "B" +msgstr "BG" #: scene/resources/default_theme/default_theme.cpp msgid "FG" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Tab" -msgstr "Tab 1" +msgstr "Tab" #: scene/resources/default_theme/default_theme.cpp #: scene/resources/dynamic_font.cpp scene/resources/world.cpp #: scene/resources/world_2d.cpp -#, fuzzy msgid "Space" -msgstr "Escena Principal" +msgstr "Espacio" #: scene/resources/default_theme/default_theme.cpp msgid "Folded" @@ -25819,9 +24919,8 @@ msgid "Font Color Readonly" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Completion Lines" -msgstr "Completar" +msgstr "Finalización de Líneas" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25880,9 +24979,8 @@ msgid "Decrement Pressed" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Slider" -msgstr "Modo de Colisión" +msgstr "Deslizador" #: scene/resources/default_theme/default_theme.cpp msgid "Grabber Area" @@ -26321,13 +25419,12 @@ msgid "Mono Font" msgstr "Fuente Principal" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Table H Separation" -msgstr "Separación de Tabla H" +msgstr "Separación H de Tabla" #: scene/resources/default_theme/default_theme.cpp msgid "Table V Separation" -msgstr "Separación de Tabla V" +msgstr "Separación V de Tabla" #: scene/resources/default_theme/default_theme.cpp msgid "Margin Left" @@ -27600,7 +26697,7 @@ msgstr "Margen de Conexión de Bordes" #: scene/resources/world_2d.cpp msgid "Canvas" -msgstr "" +msgstr "Lienzo" #: servers/arvr/arvr_interface.cpp msgid "Is Primary" diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index de1187f08f..10a562d0b8 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -20,13 +20,14 @@ # M3CG <cgmario1999@gmail.com>, 2021, 2022. # Manuel González <mgoopazo@gmail.com>, 2021. # emnrx <emanuelermancia@gmail.com>, 2022. +# Mau_Restor <restor@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-06-21 15:56+0000\n" -"Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: Mau_Restor <restor@gmail.com>\n" "Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/" "godot-engine/godot/es_AR/>\n" "Language: es_AR\n" @@ -34,7 +35,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -268,9 +269,8 @@ msgid "Network Peer" msgstr "Profiler de Red" #: core/io/multiplayer_api.cpp scene/animation/animation_player.cpp -#, fuzzy msgid "Root Node" -msgstr "Nombre del nodo raíz" +msgstr "Nodo raíz" #: core/io/networked_multiplayer_peer.cpp msgid "Refuse New Connections" @@ -302,7 +302,7 @@ msgstr "" #: core/io/stream_peer.cpp msgid "Data Array" -msgstr "" +msgstr "Array de datos" #: core/io/stream_peer_ssl.cpp msgid "Blocking Handshake" @@ -331,9 +331,8 @@ msgstr "" "No hay suficientes bytes para decodificar bytes, o el formato es inválido." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %d (not passed) in expression" -msgstr "Entrada inválida %i (no se transmitió) en la expresión" +msgstr "Entrada inválida %d (no se transmitió) en la expresión" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -362,7 +361,7 @@ msgstr "En la llamada a '%s':" #: core/math/random_number_generator.cpp #: modules/opensimplex/open_simplex_noise.cpp msgid "Seed" -msgstr "" +msgstr "Semilla" #: core/math/random_number_generator.cpp #, fuzzy @@ -371,16 +370,15 @@ msgstr "Estado" #: core/message_queue.cpp msgid "Message Queue" -msgstr "" +msgstr "Cola de mesajes" #: core/message_queue.cpp msgid "Max Size (KB)" -msgstr "" +msgstr "Tamaño máximo (KB)" #: core/os/input.cpp -#, fuzzy msgid "Mouse Mode" -msgstr "Modo Mover" +msgstr "Modo Mouse" #: core/os/input.cpp #, fuzzy @@ -409,9 +407,8 @@ msgid "Meta" msgstr "Meta" #: core/os/input_event.cpp -#, fuzzy msgid "Command" -msgstr "Comunidad" +msgstr "Comando" #: core/os/input_event.cpp #, fuzzy @@ -440,7 +437,7 @@ msgstr "Unicode" #: core/os/input_event.cpp msgid "Echo" -msgstr "" +msgstr "Echo" #: core/os/input_event.cpp scene/gui/base_button.cpp msgid "Button Mask" @@ -464,7 +461,7 @@ msgstr "Dobleclick" #: core/os/input_event.cpp msgid "Tilt" -msgstr "" +msgstr "Inclinación" #: core/os/input_event.cpp #, fuzzy @@ -477,9 +474,8 @@ msgid "Pen Inverted" msgstr "Invertir" #: core/os/input_event.cpp -#, fuzzy msgid "Relative" -msgstr "Ajuste Relativo" +msgstr "Relativo" #: core/os/input_event.cpp scene/2d/camera_2d.cpp scene/2d/cpu_particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/interpolated_camera.cpp @@ -537,7 +533,7 @@ msgstr "Velocidad" #: core/os/input_event.cpp msgid "Instrument" -msgstr "" +msgstr "Instrumento" #: core/os/input_event.cpp msgid "Controller Number" @@ -545,7 +541,7 @@ msgstr "Número de Controlador" #: core/os/input_event.cpp msgid "Controller Value" -msgstr "" +msgstr "Valor del controlador" #: core/project_settings.cpp editor/editor_node.cpp main/main.cpp #: platform/iphone/export/export.cpp platform/osx/export/export.cpp @@ -617,9 +613,8 @@ msgstr "Nombre de Directorio de Usuario Personalizado" #: core/project_settings.cpp main/main.cpp #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #: platform/uwp/os_uwp.cpp -#, fuzzy msgid "Display" -msgstr "Mostrar Todo" +msgstr "Mostrar" #: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp #: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp @@ -638,17 +633,15 @@ msgstr "Altura" #: core/project_settings.cpp msgid "Always On Top" -msgstr "" +msgstr "Siempre encima" #: core/project_settings.cpp -#, fuzzy msgid "Test Width" -msgstr "Izquierda Ancha" +msgstr "probar ancho" #: core/project_settings.cpp -#, fuzzy msgid "Test Height" -msgstr "Prueba" +msgstr "probar altura" #: core/project_settings.cpp editor/animation_track_editor.cpp #: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp @@ -686,14 +679,12 @@ msgid "Script Templates Search Path" msgstr "Ruta de Búsqueda de Plantillas de Scripts" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Autoload On Startup" -msgstr "Sistema de Control de Versiones" +msgstr "Al iniciar el Sistema de Control de Versiones" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Plugin Name" -msgstr "Control de Versiones" +msgstr "Nombre del sistema de control de versiones" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp @@ -702,17 +693,15 @@ msgstr "Entrada" #: core/project_settings.cpp msgid "UI Accept" -msgstr "" +msgstr "Aceptar Interfaz del usuario" #: core/project_settings.cpp -#, fuzzy msgid "UI Select" -msgstr "Seleccionar" +msgstr "Seleccionar Interfaz de Usuario" #: core/project_settings.cpp -#, fuzzy msgid "UI Cancel" -msgstr "Cancelar" +msgstr "Cancelar la interfaz de usuario" #: core/project_settings.cpp #, fuzzy @@ -754,12 +743,11 @@ msgstr "" #: core/project_settings.cpp msgid "UI Home" -msgstr "" +msgstr "Inicio de la interfaz de usuario" #: core/project_settings.cpp -#, fuzzy msgid "UI End" -msgstr "Al Final" +msgstr "Al Final de la interfaz de usuario" #: core/project_settings.cpp main/main.cpp modules/bullet/register_types.cpp #: modules/bullet/space_bullet.cpp scene/2d/physics_body_2d.cpp @@ -817,7 +805,7 @@ msgstr "Filtros" #: core/project_settings.cpp scene/main/viewport.cpp msgid "Sharpen Intensity" -msgstr "" +msgstr "Intensidad de la nitidez" #: core/project_settings.cpp editor/editor_export.cpp editor/editor_node.cpp #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp @@ -867,7 +855,7 @@ msgstr "Nivel de Compresión" #: core/project_settings.cpp msgid "Window Log Size" -msgstr "" +msgstr "medida del registro de la ventana" #: core/project_settings.cpp msgid "Zlib" @@ -890,9 +878,8 @@ msgid "TCP" msgstr "TCP" #: core/register_core_types.cpp -#, fuzzy msgid "Connect Timeout Seconds" -msgstr "Conexiones al método:" +msgstr "Tiempo de espera en segundos de la conexion" #: core/register_core_types.cpp msgid "Packet Peer Stream" @@ -917,9 +904,8 @@ msgid "Resource" msgstr "Recursos" #: core/resource.cpp -#, fuzzy msgid "Local To Scene" -msgstr "Cerrar Escena" +msgstr "Local a la escena" #: core/resource.cpp editor/dependency_editor.cpp #: editor/editor_autoload_settings.cpp editor/plugins/path_editor_plugin.cpp @@ -1200,9 +1186,8 @@ msgid "Type" msgstr "Tipo" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "Setear Handle" +msgstr "En manejo" #: editor/animation_track_editor.cpp #, fuzzy @@ -1353,9 +1338,8 @@ msgid "Time (s):" msgstr "Tiempo (s): " #: editor/animation_track_editor.cpp -#, fuzzy msgid "Position:" -msgstr "Posición del Panel" +msgstr "Posición:" #: editor/animation_track_editor.cpp #, fuzzy @@ -2168,14 +2152,15 @@ msgstr "Favoritos:" msgid "Recent:" msgstr "Recientes:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Buscar:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Coincidencias:" @@ -2235,8 +2220,8 @@ msgstr "Buscar Reemplazo de Recurso:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2815,7 +2800,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Copiar Ruta del Nodo" #: editor/editor_export.cpp @@ -5645,6 +5630,10 @@ msgid "Drag And Drop Selection" msgstr "Selección de GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11932,6 +11921,11 @@ msgid "New Animation" msgstr "Nueva Animación" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrar métodos" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocidad:" @@ -20748,15 +20742,15 @@ msgstr "No se pudo encontrar la keystore, no se puedo exportar." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Archivo ejecutable no válido." #: platform/windows/export/export.cpp #, fuzzy @@ -20780,15 +20774,15 @@ msgstr "Nombre inválido." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Archivo ejecutable no válido." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/et.po b/editor/translations/et.po index b355c9c343..3976c9f0bd 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -2154,14 +2154,15 @@ msgstr "Lemmikud:" msgid "Recent:" msgstr "Hiljutised:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Otsi:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Vasted:" @@ -2217,8 +2218,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2788,7 +2789,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Kopeeri sõlme tee" #: editor/editor_export.cpp @@ -5487,6 +5488,10 @@ msgid "Drag And Drop Selection" msgstr "Kopeeri valik" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11589,6 +11594,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Kustuta animatsioon?" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20003,15 +20013,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Vigane nimi." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20033,15 +20043,15 @@ msgstr "Vigane nimi." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Vigane nimi." #: platform/windows/export/export.cpp msgid "Failed to remove temporary file \"%s\"." diff --git a/editor/translations/eu.po b/editor/translations/eu.po index fc753e6cb9..3e69f3c4b9 100644 --- a/editor/translations/eu.po +++ b/editor/translations/eu.po @@ -2116,14 +2116,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2179,8 +2180,8 @@ msgstr "Bilatu ordezko baliabidea:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2755,8 +2756,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Kargatu animazioa" #: editor/editor_export.cpp #, fuzzy @@ -5393,6 +5395,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11467,6 +11473,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Ezabatu animazioa?" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19805,15 +19816,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Animazio izen baliogabea!" #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -19835,15 +19846,15 @@ msgstr "Animazio izen baliogabea!" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Animazio izen baliogabea!" #: platform/windows/export/export.cpp msgid "Failed to remove temporary file \"%s\"." diff --git a/editor/translations/fa.po b/editor/translations/fa.po index f43848b065..86b847e530 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -2198,14 +2198,15 @@ msgstr "برگزیدهها:" msgid "Recent:" msgstr "اخیر:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "جستجو:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "تطبیقها:" @@ -2265,8 +2266,8 @@ msgstr "منبع جایگزینی را جستجو کن:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2839,7 +2840,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "کپی کردن مسیر node" #: editor/editor_export.cpp @@ -5549,6 +5550,10 @@ msgid "Drag And Drop Selection" msgstr "انتخاب شده را حذف کن" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11962,6 +11967,11 @@ msgid "New Animation" msgstr "تغییر نام انیمیشن" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "حالت صافی:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20742,15 +20752,15 @@ msgstr "نمیتواند یک پوشه ایجاد شود." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "باید از یک پسوند معتبر استفاده شود." #: platform/windows/export/export.cpp #, fuzzy @@ -20774,15 +20784,15 @@ msgstr "نام نامعتبر." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "باید از یک پسوند معتبر استفاده شود." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/fi.po b/editor/translations/fi.po index b83c7d11fa..db841ef48a 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -2216,14 +2216,15 @@ msgstr "Suosikit:" msgid "Recent:" msgstr "Viimeaikaiset:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Hae:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Osumat:" @@ -2283,8 +2284,8 @@ msgstr "Etsi korvaava resurssi:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2863,7 +2864,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Kopioi solmun polku" #: editor/editor_export.cpp @@ -5676,6 +5677,10 @@ msgid "Drag And Drop Selection" msgstr "Ruudukon valinta" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11950,6 +11955,11 @@ msgid "New Animation" msgstr "Uusi animaatio" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Suodata metodeja" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Nopeus:" @@ -20746,17 +20756,17 @@ msgstr "Keystorea ei löytynyt, ei voida viedä." #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" "rcedit-työkalu täytyy olla konfiguroituna editorin asetuksissa (Export > " "Windows > Rcedit) ikonin tai sovelluksen tietojen muuttamiseksi." #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Virheellinen käynnistystiedosto." #: platform/windows/export/export.cpp #, fuzzy @@ -20781,17 +20791,17 @@ msgstr "Virheellinen nimi." #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" "rcedit-työkalu täytyy olla konfiguroituna editorin asetuksissa (Export > " "Windows > Rcedit) ikonin tai sovelluksen tietojen muuttamiseksi." #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Virheellinen käynnistystiedosto." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/fil.po b/editor/translations/fil.po index c4e02900d7..0a154fd6ae 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -2088,14 +2088,15 @@ msgstr "Mga Paborito:" msgid "Recent:" msgstr "Kamakailan:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Paghahanap:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2151,8 +2152,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2711,8 +2712,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Pagulit ng Animation" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5310,6 +5312,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11321,6 +11327,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Pagulit ng Animation" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19491,14 +19502,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19520,14 +19530,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/fr.po b/editor/translations/fr.po index e4f5a2feff..88c4966b54 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -101,13 +101,14 @@ # Arnaud Lier <arnaud@ric-rac.org>, 2022. # Jérémie Guegain <mirejai@orange.fr>, 2022. # cwulveryck <cwulveryck@online.fr>, 2022. +# Helix Sir <vincentbarkmann@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-16 06:20+0000\n" -"Last-Translator: cwulveryck <cwulveryck@online.fr>\n" +"PO-Revision-Date: 2022-08-05 01:04+0000\n" +"Last-Translator: Helix Sir <vincentbarkmann@gmail.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" "Language: fr\n" @@ -147,11 +148,11 @@ msgstr "Lissage de Delta" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode" -msgstr "Mode d'Utilisation Faible du Processeur" +msgstr "Mode d'utilisation faible du processeur" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode Sleep (µsec)" -msgstr "Mode d'Utilisation Faible du Processeur (µs)" +msgstr "Mode d'utilisation faible du processeur Veille (µsec)" #: core/bind/core_bind.cpp main/main.cpp platform/uwp/os_uwp.cpp msgid "Keep Screen On" @@ -244,9 +245,8 @@ msgid "Time Scale" msgstr "Echelle de temps" #: core/bind/core_bind.cpp main/main.cpp -#, fuzzy msgid "Physics Jitter Fix" -msgstr "Correction de la physique gigue" +msgstr "Correction des sursauts de physique" #: core/bind/core_bind.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Error" @@ -316,9 +316,8 @@ msgid "Page Size" msgstr "Taille de page" #: core/io/file_access_network.cpp -#, fuzzy msgid "Page Read Ahead" -msgstr "Page lue devant" +msgstr "Pré-lecture de page" #: core/io/http_client.cpp msgid "Blocking Mode Enabled" @@ -329,9 +328,8 @@ msgid "Connection" msgstr "Connexion" #: core/io/http_client.cpp -#, fuzzy msgid "Read Chunk Size" -msgstr "Lire la taille du tronçon" +msgstr "Taile des tronçons de lecture" #: core/io/marshalls.cpp msgid "Object ID" @@ -375,7 +373,7 @@ msgstr "Taille maximale du tampon de sortie" #: core/io/packet_peer.cpp msgid "Stream Peer" -msgstr "" +msgstr "Pair de flux" #: core/io/stream_peer.cpp msgid "Big Endian" @@ -488,9 +486,8 @@ msgid "Command" msgstr "Commande" #: core/os/input_event.cpp -#, fuzzy msgid "Physical" -msgstr " (physique)" +msgstr "Physique" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp @@ -500,7 +497,7 @@ msgstr "Pressé" #: core/os/input_event.cpp msgid "Scancode" -msgstr "Scancode" +msgstr "Code de scan" #: core/os/input_event.cpp msgid "Physical Scancode" @@ -543,9 +540,8 @@ msgid "Pressure" msgstr "Pression" #: core/os/input_event.cpp -#, fuzzy msgid "Pen Inverted" -msgstr "Inverser" +msgstr "Stylo Inversé" #: core/os/input_event.cpp msgid "Relative" @@ -624,7 +620,7 @@ msgstr "Application" #: core/project_settings.cpp main/main.cpp msgid "Config" -msgstr "Config" +msgstr "Configuration" #: core/project_settings.cpp msgid "Project Settings Override" @@ -731,9 +727,8 @@ msgid "Editor" msgstr "Éditeur" #: core/project_settings.cpp -#, fuzzy msgid "Main Run Args" -msgstr "Arguments de la scène principale :" +msgstr "Paramètres d'exécution du programme principal" #: core/project_settings.cpp msgid "Scene Naming" @@ -797,9 +792,8 @@ msgid "UI Down" msgstr "Bas" #: core/project_settings.cpp -#, fuzzy msgid "UI Page Up" -msgstr "Page Haut" +msgstr "Page Haut (Interface)" #: core/project_settings.cpp msgid "UI Page Down" @@ -835,9 +829,8 @@ msgid "3D" msgstr "3D" #: core/project_settings.cpp -#, fuzzy msgid "Smooth Trimesh Collision" -msgstr "Collision Lisse Trimesh" +msgstr "Lissage de Collision Trimesh" #: core/project_settings.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles2/rasterizer_scene_gles2.cpp @@ -918,9 +911,8 @@ msgid "Compression Level" msgstr "Niveau de Compression" #: core/project_settings.cpp -#, fuzzy msgid "Window Log Size" -msgstr "Taille de la fenêtre du journal" +msgstr "Taille du journal de la fenêtre" #: core/project_settings.cpp msgid "Zlib" @@ -948,10 +940,9 @@ msgstr "Délai d'expiration de la connexion en secondes" #: core/register_core_types.cpp msgid "Packet Peer Stream" -msgstr "" +msgstr "Flux de pair de paquet" #: core/register_core_types.cpp -#, fuzzy msgid "Max Buffer (Power of 2)" msgstr "Tampon Max (puissance de 2)" @@ -993,7 +984,6 @@ msgid "Test" msgstr "Test" #: core/translation.cpp scene/resources/font.cpp -#, fuzzy msgid "Fallback" msgstr "Repli" @@ -1036,12 +1026,12 @@ msgstr "Tampons" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Canvas Polygon Buffer Size (KB)" -msgstr "" +msgstr "Taille du tampon des polygones du canevas (Ko)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Canvas Polygon Index Buffer Size (KB)" -msgstr "" +msgstr "Taille de l'index des polygones du canevas (Ko)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp editor/editor_settings.cpp @@ -1057,15 +1047,13 @@ msgstr "2D" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Snapping" -msgstr "Magnétisme intelligent" +msgstr "Magnétisme" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Use GPU Pixel Snap" -msgstr "Aligner au pixel près" +msgstr "Arrondissement GPU au pixel le plus proche" #: drivers/gles2/rasterizer_scene_gles2.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp @@ -1074,9 +1062,8 @@ msgstr "Taille du tampon immédiat (Ko)" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp -#, fuzzy msgid "Lightmapping" -msgstr "Précalculer les lightmaps" +msgstr "Cartographie des lumières" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp @@ -1100,7 +1087,6 @@ msgid "Max Lights Per Object" msgstr "Maximum de lumières par objet" #: drivers/gles3/rasterizer_scene_gles3.cpp -#, fuzzy msgid "Subsurface Scattering" msgstr "Transluminescence" @@ -1122,13 +1108,12 @@ msgid "Follow Surface" msgstr "Suivre la surface" #: drivers/gles3/rasterizer_scene_gles3.cpp -#, fuzzy msgid "Weight Samples" msgstr "Échantillons de poids" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Voxel Cone Tracing" -msgstr "" +msgstr "Traçage de cone voxel" #: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp msgid "High Quality" @@ -1136,7 +1121,7 @@ msgstr "Haute Qualité" #: drivers/gles3/rasterizer_storage_gles3.cpp msgid "Blend Shape Max Buffer Size (KB)" -msgstr "" +msgstr "Taille max du tampon de mélange de formes" #. TRANSLATORS: Adjective, refers to the mode for Bezier handles (Free, Balanced, Mirror). #: editor/animation_bezier_editor.cpp @@ -1193,7 +1178,7 @@ msgstr "Modifier le temps de l’image-clé" #: editor/animation_track_editor.cpp msgid "Anim Change Transition" -msgstr "Changer la transition de l’animation" +msgstr "Transition de changement de l’animation" #: editor/animation_track_editor.cpp msgid "Anim Change Transform" @@ -1253,14 +1238,12 @@ msgid "Type" msgstr "Type" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "Définir la poignée" +msgstr "Poignée d'entrée" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out Handle" -msgstr "Définir la poignée" +msgstr "Poignée de sortie" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp @@ -1274,7 +1257,6 @@ msgid "Start Offset" msgstr "Décalage du Départ" #: editor/animation_track_editor.cpp -#, fuzzy msgid "End Offset" msgstr "Décalage à la fin" @@ -1289,9 +1271,8 @@ msgid "Animation" msgstr "Animation" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Easing" -msgstr "Ease in-out" +msgstr "Transition entrée-sortie" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -1430,38 +1411,32 @@ msgid "(Invalid, expected type: %s)" msgstr "(Invalide, type attendu : %s)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Easing:" -msgstr "Ease in-out" +msgstr "Transition entrée-sortie :" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In-Handle:" -msgstr "Définir la poignée" +msgstr "Poignée d'entrée :" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out-Handle:" -msgstr "Définir la poignée" +msgstr "Poignée de sortie :" #: editor/animation_track_editor.cpp msgid "Stream:" msgstr "Flux :" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Start (s):" -msgstr "Redémarrer (s) :" +msgstr "Début (s) :" #: editor/animation_track_editor.cpp -#, fuzzy msgid "End (s):" -msgstr "Fondu entrant (s) :" +msgstr "Fin (s) :" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation Clip:" -msgstr "Animations :" +msgstr "Clip d'animation :" #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" @@ -1549,9 +1524,8 @@ msgid "Editors" msgstr "Éditeurs" #: editor/animation_track_editor.cpp editor/editor_settings.cpp -#, fuzzy msgid "Confirm Insert Track" -msgstr "Insérer une piste et clé d’animation" +msgstr "Confirmer l'ajout de piste" #. TRANSLATORS: %s will be replaced by a phrase describing the target of track. #: editor/animation_track_editor.cpp @@ -2218,14 +2192,15 @@ msgstr "Favoris :" msgid "Recent:" msgstr "Récents :" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Rechercher :" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Correspondances :" @@ -2285,8 +2260,8 @@ msgstr "Recherche ressource de remplacement :" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2866,8 +2841,8 @@ msgid "Project export for platform:" msgstr "Exportation du projet pour la plateforme :" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "Terminé avec des erreurs." +msgid "Completed with warnings." +msgstr "Terminé avec des avertissements." #: editor/editor_export.cpp msgid "Completed successfully." @@ -2987,9 +2962,8 @@ msgid "64 Bits" msgstr "64 Bits" #: editor/editor_export.cpp -#, fuzzy msgid "Embed PCK" -msgstr "PCK Intégré" +msgstr "Intégrer PCK" #: editor/editor_export.cpp platform/osx/export/export.cpp msgid "Texture Format" @@ -3028,9 +3002,8 @@ msgid "Custom release template not found." msgstr "Modèle de version personnalisée introuvable." #: editor/editor_export.cpp -#, fuzzy msgid "Prepare Template" -msgstr "Gérer les modèles" +msgstr "Préparer le modèle type" #: editor/editor_export.cpp platform/osx/export/export.cpp msgid "The given export path doesn't exist." @@ -3046,9 +3019,8 @@ msgstr "La copie du modèle d'exportation a échoué." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp -#, fuzzy msgid "PCK Embedding" -msgstr "Intégration du PCK" +msgstr "Intégration PCK" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." @@ -3269,9 +3241,8 @@ msgid "Manage Editor Feature Profiles" msgstr "Gérer les profils de fonctionnalités de l'éditeur" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Default Feature Profile" -msgstr "Profil des fonctionnalités de Godot" +msgstr "Profil de fonctionalités par défaut" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -3382,7 +3353,6 @@ msgid "Show Hidden Files" msgstr "Afficher les fichiers cachés" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Disable Overwrite Warning" msgstr "Désactiver l'avertissement de réécriture" @@ -3687,25 +3657,21 @@ msgid "Read Only" msgstr "Lecture Seule" #: editor/editor_inspector.cpp editor/plugins/item_list_editor_plugin.cpp -#, fuzzy msgid "Checkable" -msgstr "Item à cocher" +msgstr "Cochable" #: editor/editor_inspector.cpp editor/plugins/item_list_editor_plugin.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Checked" -msgstr "Item coché" +msgstr "Coché" #: editor/editor_inspector.cpp -#, fuzzy msgid "Draw Red" -msgstr "Appels de dessin :" +msgstr "Dessiner en rouge" #: editor/editor_inspector.cpp -#, fuzzy msgid "Keying" -msgstr "Jouer" +msgstr "En train de taper" #: editor/editor_inspector.cpp msgid "Pin value" @@ -4079,10 +4045,8 @@ msgid "Save & Reload" msgstr "Sauvegarder & Recharger" #: editor/editor_node.cpp -#, fuzzy msgid "Save changes to '%s' before reloading?" -msgstr "" -"Sauvegarder les modifications effectuées dans « %s » avant de recharger ?" +msgstr "Sauvegarder les modifications dans '%s' avant de recharger ?" #: editor/editor_node.cpp msgid "Save & Close" @@ -4201,11 +4165,9 @@ msgid "Open Project Manager?" msgstr "Ouvrir le gestionnaire de projets ?" #: editor/editor_node.cpp -#, fuzzy msgid "Save changes to the following scene(s) before reloading?" msgstr "" -"Sauvegarder les modifications sur la (les) scène(s) suivante(s) avant de " -"quitter ?" +"Sauvegarder les modifications de scène(s) suivante(s) avant de recharger ?" #: editor/editor_node.cpp msgid "Save & Quit" @@ -4410,9 +4372,8 @@ msgid "Interface" msgstr "Interface" #: editor/editor_node.cpp editor/editor_settings.cpp -#, fuzzy msgid "Scene Tabs" -msgstr "Basculer entre onglets de scène" +msgstr "Onglets de scène" #: editor/editor_node.cpp msgid "Always Show Close Button" @@ -4447,7 +4408,6 @@ msgid "Save On Focus Loss" msgstr "Enregistrer lorsque le focus est perdu" #: editor/editor_node.cpp editor/editor_settings.cpp -#, fuzzy msgid "Save Each Scene On Quit" msgstr "Enregistrer toutes les scènes à la fermeture" @@ -4469,12 +4429,10 @@ msgid "Update Vital Only" msgstr "Changements de matériau" #: editor/editor_node.cpp -#, fuzzy msgid "Localize Settings" -msgstr "Localisation" +msgstr "Traduction des réglages" #: editor/editor_node.cpp -#, fuzzy msgid "Restore Scenes On Load" msgstr "Restaurer les scènes au chargement" @@ -4487,7 +4445,6 @@ msgid "Inspector" msgstr "Inspecteur" #: editor/editor_node.cpp -#, fuzzy msgid "Default Property Name Style" msgstr "Style par défaut des noms de propriétés" @@ -4496,12 +4453,10 @@ msgid "Default Float Step" msgstr "Pas par défaut des flottant" #: editor/editor_node.cpp scene/gui/tree.cpp -#, fuzzy msgid "Disable Folding" -msgstr "Bouton désactivé" +msgstr "Désactiver le repliage" #: editor/editor_node.cpp -#, fuzzy msgid "Auto Unfold Foreign Scenes" msgstr "Déplier automatiquement les scènes étrangères" @@ -4510,7 +4465,6 @@ msgid "Horizontal Vector2 Editing" msgstr "Édition horizontale de Vector2" #: editor/editor_node.cpp -#, fuzzy msgid "Horizontal Vector Types Editing" msgstr "Édition de Types de Vecteur Horizontal" @@ -4519,12 +4473,10 @@ msgid "Open Resources In Current Inspector" msgstr "Ouvrir les ressources dans l'inspecteur actuel" #: editor/editor_node.cpp -#, fuzzy msgid "Resources To Open In New Inspector" msgstr "Ressources à ouvrir dans un nouvel inspecteur" #: editor/editor_node.cpp -#, fuzzy msgid "Default Color Picker Mode" msgstr "Mode par défaut du sélectionneur de couleur" @@ -5186,14 +5138,12 @@ msgid "Debugger" msgstr "Débogueur" #: editor/editor_profiler.cpp -#, fuzzy msgid "Profiler Frame History Size" msgstr "Taille de l'historique de la trame du profileur" #: editor/editor_profiler.cpp -#, fuzzy msgid "Profiler Frame Max Functions" -msgstr "Renommer la fonction" +msgstr "Nombre maximum de fonctions par trame de profileur" #: editor/editor_properties.cpp msgid "Edit Text:" @@ -5408,12 +5358,10 @@ msgid "Code Font Size" msgstr "Taille de la police du code" #: editor/editor_settings.cpp -#, fuzzy msgid "Font Antialiased" -msgstr "Anticrénelage appliqué sur la police" +msgstr "Police anticrénelée" #: editor/editor_settings.cpp -#, fuzzy msgid "Font Hinting" msgstr "Indication de police" @@ -5434,18 +5382,16 @@ msgid "Dim Editor On Dialog Popup" msgstr "Assombrir l'éditeur à l'ouverture d'un dialogue" #: editor/editor_settings.cpp main/main.cpp -#, fuzzy msgid "Low Processor Mode Sleep (µsec)" -msgstr "Mode de faible latence Processeur" +msgstr "Veille du Mode faible latence Processeur (µsec)" #: editor/editor_settings.cpp msgid "Unfocused Low Processor Mode Sleep (µsec)" -msgstr "" +msgstr "Veille du mode d'utilisation faible du processeur quand inactif (µsec)" #: editor/editor_settings.cpp -#, fuzzy msgid "Separate Distraction Mode" -msgstr "Mode Sans Distraction" +msgstr "Mode distraction séparée" #: editor/editor_settings.cpp msgid "Automatically Open Screenshots" @@ -5453,7 +5399,7 @@ msgstr "Ouvrir automatiquement les captures d'écran" #: editor/editor_settings.cpp msgid "Max Array Dictionary Items Per Page" -msgstr "" +msgstr "Nombre maximum d'articles tableau de dictionnaire par page" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp scene/gui/control.cpp @@ -5474,9 +5420,8 @@ msgid "Base Color" msgstr "Couleur de Base" #: editor/editor_settings.cpp -#, fuzzy msgid "Accent Color" -msgstr "Prélever une couleur" +msgstr "Couleur d'accentuation" #: editor/editor_settings.cpp scene/resources/environment.cpp msgid "Contrast" @@ -5484,69 +5429,59 @@ msgstr "Contraste" #: editor/editor_settings.cpp msgid "Relationship Line Opacity" -msgstr "" +msgstr "Opacité des lignes de relation" #: editor/editor_settings.cpp -#, fuzzy msgid "Highlight Tabs" -msgstr "Enregistrement des lightmaps" +msgstr "Surligner les onglets" #: editor/editor_settings.cpp -#, fuzzy msgid "Border Size" -msgstr "Pixels de bordure" +msgstr "Taille de bordure" #: editor/editor_settings.cpp -#, fuzzy msgid "Use Graph Node Headers" -msgstr "Utiliser les en-tête de noeud Graph" +msgstr "Utiliser les en-têtes de graphes des nœuds" #: editor/editor_settings.cpp -#, fuzzy msgid "Additional Spacing" -msgstr "Bouclage de l’animation" +msgstr "Espacement supplémentaire" #: editor/editor_settings.cpp msgid "Custom Theme" msgstr "Thème Personnalisé" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Script Button" -msgstr "Molette bouton droit" +msgstr "Afficher le bouton script" #: editor/editor_settings.cpp -#, fuzzy msgid "Directories" -msgstr "Directions" +msgstr "Dossiers" #: editor/editor_settings.cpp -#, fuzzy msgid "Autoscan Project Path" -msgstr "Chemin du projet :" +msgstr "Scan auto du chemin du projet" #: editor/editor_settings.cpp msgid "Default Project Path" msgstr "Chemin du Projet par Défaut" #: editor/editor_settings.cpp -#, fuzzy msgid "On Save" -msgstr "Enregistrer" +msgstr "À l'enregistrement" #: editor/editor_settings.cpp msgid "Compress Binary Resources" msgstr "Compresser les ressources binaires" #: editor/editor_settings.cpp -#, fuzzy msgid "Safe Save On Backup Then Rename" -msgstr "Sauvegarde sécurisée lors de l'archivage puis renommer" +msgstr "Sauvegarde sécurisée lors de l'archivage avant de renommer" #: editor/editor_settings.cpp -#, fuzzy msgid "File Dialog" -msgstr "Dialogue XForm" +msgstr "Fenêtre de sélection de fichiers" #: editor/editor_settings.cpp msgid "Thumbnail Size" @@ -5554,21 +5489,19 @@ msgstr "Taille de la vignette" #: editor/editor_settings.cpp msgid "Docks" -msgstr "" +msgstr "S'attache" #: editor/editor_settings.cpp msgid "Scene Tree" msgstr "une arborescence, arbre des scènes" #: editor/editor_settings.cpp -#, fuzzy msgid "Start Create Dialog Fully Expanded" -msgstr "Lancer le dialogue de Création totalement expandu" +msgstr "Lancer le dialogue de création complètement déplié" #: editor/editor_settings.cpp -#, fuzzy msgid "Always Show Folders" -msgstr "Toujours afficher la grille" +msgstr "Toujours afficher les dossiers" #: editor/editor_settings.cpp msgid "Property Editor" @@ -5579,29 +5512,24 @@ msgid "Auto Refresh Interval" msgstr "Intervalle d’autorafraîchissement" #: editor/editor_settings.cpp -#, fuzzy msgid "Subresource Hue Tint" -msgstr "Ressources secondaires" +msgstr "Teinte des sous-ressources" #: editor/editor_settings.cpp -#, fuzzy msgid "Color Theme" -msgstr "Thème de l'éditeur" +msgstr "Thème de couleurs" #: editor/editor_settings.cpp scene/3d/label_3d.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Line Spacing" msgstr "Espace entre les lignes" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp #: modules/gdscript/editor/gdscript_highlighter.cpp -#, fuzzy msgid "Highlighting" -msgstr "Éclairage direct" +msgstr "Surlignage" #: editor/editor_settings.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Syntax Highlighting" msgstr "Coloration syntaxique" @@ -5614,32 +5542,28 @@ msgid "Highlight Current Line" msgstr "Mettre en évidence la ligne actuelle" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Highlight Type Safe Lines" -msgstr "Surligner les lignes Typées" +msgstr "Surligner les lignes à types sûrs" #: editor/editor_settings.cpp -#, fuzzy msgid "Indent" -msgstr "Indenter vers la gauche" +msgstr "Indenter" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp msgid "Auto Indent" msgstr "Indentation automatique" #: editor/editor_settings.cpp -#, fuzzy msgid "Convert Indent On Save" -msgstr "Convertir indentations en espaces" +msgstr "Convertir les indentations à l'enregistrement" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Draw Tabs" msgstr "Montrer les tabulations" #: editor/editor_settings.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Draw Spaces" -msgstr "Appels de dessin :" +msgstr "Afficher les espaces" #: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/tile_map.cpp @@ -5657,9 +5581,8 @@ msgid "V Scroll Speed" msgstr "Vitesse du défilement vertical" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Minimap" -msgstr "Afficher l'origine" +msgstr "Afficher la minimap" #: editor/editor_settings.cpp msgid "Minimap Width" @@ -5667,12 +5590,15 @@ msgstr "Largeur de la mini-carte" #: editor/editor_settings.cpp msgid "Mouse Extra Buttons Navigate History" -msgstr "" +msgstr "Boutons additionnels de la souris déplacent dans l'historique" #: editor/editor_settings.cpp -#, fuzzy msgid "Drag And Drop Selection" -msgstr "Sélection de la GridMap" +msgstr "Sélection glisser/déposer" + +#: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "Rester sur l’éditeur de script en sélectionnant un nœud" #: editor/editor_settings.cpp msgid "Appearance" @@ -5683,21 +5609,18 @@ msgid "Show Line Numbers" msgstr "Afficher les Numéros de Ligne" #: editor/editor_settings.cpp -#, fuzzy msgid "Line Numbers Zero Padded" -msgstr "Numéro de ligne :" +msgstr "Numéros de lignes avec remplissage en zéros" #: editor/editor_settings.cpp msgid "Show Bookmark Gutter" msgstr "Montrer le bandeau de marque-page" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Breakpoint Gutter" -msgstr "Passer les points d'arrêt" +msgstr "Afficher le bandeau de points d’arrêt" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Info Gutter" msgstr "Montrer le bandeau d'information" @@ -5707,26 +5630,25 @@ msgstr "Rétrécir le code" #: editor/editor_settings.cpp msgid "Word Wrap" -msgstr "" +msgstr "Retour à la ligne des mots" #: editor/editor_settings.cpp msgid "Show Line Length Guidelines" -msgstr "" +msgstr "Montrer les guides de longueur de ligne" #: editor/editor_settings.cpp msgid "Line Length Guideline Soft Column" -msgstr "" +msgstr "Colonne douce des guides de longueur de ligne" #: editor/editor_settings.cpp msgid "Line Length Guideline Hard Column" -msgstr "" +msgstr "Colonne dure des guides de longueur de ligne" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp msgid "Script List" msgstr "Liste des Scripts" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Members Overview" msgstr "Montrer l'ensemble des Membres" @@ -5735,19 +5657,16 @@ msgid "Files" msgstr "Fichiers" #: editor/editor_settings.cpp -#, fuzzy msgid "Trim Trailing Whitespace On Save" -msgstr "Supprimer les espaces de fin de ligne" +msgstr "Retirer les espaces de fin de ligne à l'enregistrement" #: editor/editor_settings.cpp -#, fuzzy msgid "Autosave Interval Secs" -msgstr "Intervalle entre les auto-sauvegarde (en secondes)" +msgstr "Intervalle entre les sauvegardes automatiques (en secondes)" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Restore Scripts On Load" -msgstr "Restaurer les scripts lors du chargement" +msgstr "Restaurer les scripts au chargement" #: editor/editor_settings.cpp msgid "Auto Reload And Parse Scripts On Save" @@ -5756,16 +5675,15 @@ msgstr "" #: editor/editor_settings.cpp msgid "Auto Reload Scripts On External Change" -msgstr "" +msgstr "Recharger automatiquement les scripts sur changement externe" #: editor/editor_settings.cpp -#, fuzzy msgid "Create Signal Callbacks" -msgstr "Forcer les replis du shader" +msgstr "Créer des rappels de signaux" #: editor/editor_settings.cpp msgid "Sort Members Outline Alphabetically" -msgstr "" +msgstr "Trier le contour des membres alphabétiquement" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Cursor" @@ -5788,9 +5706,8 @@ msgid "Caret Blink Speed" msgstr "Vitesse du clignotement du caret" #: editor/editor_settings.cpp -#, fuzzy msgid "Right Click Moves Caret" -msgstr "Clic droit pour ajouter un point" +msgstr "Clic droit déplace le caret" #: editor/editor_settings.cpp modules/gdscript/gdscript.cpp #: modules/gdscript/gdscript_editor.cpp @@ -5812,31 +5729,27 @@ msgstr "Délai d'auto-complétion du code" #: editor/editor_settings.cpp msgid "Put Callhint Tooltip Below Current Line" -msgstr "" +msgstr "Placer l'info-bulle d'appel sous la ligne actuelle" #: editor/editor_settings.cpp msgid "Callhint Tooltip Offset" -msgstr "" +msgstr "Décalage des info-bulles d'appel" #: editor/editor_settings.cpp -#, fuzzy msgid "Complete File Paths" -msgstr "Copier le chemin du nœud" +msgstr "Compléter les chemins de fichiers" #: editor/editor_settings.cpp modules/gdscript/gdscript_editor.cpp -#, fuzzy msgid "Add Type Hints" -msgstr "Ajouter un type" +msgstr "Ajouter des indices de type" #: editor/editor_settings.cpp -#, fuzzy msgid "Use Single Quotes" -msgstr "Nouvelle Simple Tuile" +msgstr "Utiliser des simples guillemets" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Help Index" -msgstr "Afficher les aides" +msgstr "Afficher l'index d'aide" #: editor/editor_settings.cpp msgid "Help Font Size" @@ -5847,7 +5760,6 @@ msgid "Help Source Font Size" msgstr "Taille de la police de l'aide de la source" #: editor/editor_settings.cpp -#, fuzzy msgid "Help Title Font Size" msgstr "Taille de la police du titre Aide" @@ -5856,9 +5768,8 @@ msgid "Grid Map" msgstr "Grille" #: editor/editor_settings.cpp modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Pick Distance" -msgstr "Choisissez distance :" +msgstr "Choisissez la distance" #: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp msgid "Preview Size" @@ -5873,32 +5784,27 @@ msgid "Secondary Grid Color" msgstr "Couleur de la grille secondaire" #: editor/editor_settings.cpp -#, fuzzy msgid "Selection Box Color" -msgstr "Sélection uniquement" +msgstr "Couleur de la boîte de sélection" #: editor/editor_settings.cpp editor/plugins/path_editor_plugin.cpp #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp -#, fuzzy msgid "3D Gizmos" -msgstr "Gadgets" +msgstr "Manipulateurs 3D" #: editor/editor_settings.cpp editor/plugins/path_editor_plugin.cpp #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp -#, fuzzy msgid "Gizmo Colors" -msgstr "Couleurs d'émission" +msgstr "Couleurs des manipulateurs" #: editor/editor_settings.cpp -#, fuzzy msgid "Instanced" -msgstr "Instance" +msgstr "Instancié" #: editor/editor_settings.cpp modules/gltf/gltf_node.cpp #: scene/3d/physics_body.cpp -#, fuzzy msgid "Joint" -msgstr "Point" +msgstr "Jointure" #: editor/editor_settings.cpp scene/2d/collision_shape_2d.cpp #: scene/2d/cpu_particles_2d.cpp scene/2d/touch_screen_button.cpp @@ -5910,9 +5816,8 @@ msgid "Shape" msgstr "Forme" #: editor/editor_settings.cpp -#, fuzzy msgid "Primary Grid Steps" -msgstr "Pas de la grille :" +msgstr "Pas de la grille principale" #: editor/editor_settings.cpp msgid "Grid Size" @@ -5928,55 +5833,47 @@ msgstr "Niveau minimal de division de la grille" #: editor/editor_settings.cpp msgid "Grid Division Level Bias" -msgstr "" +msgstr "Niveau de biais de la division de grille" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid XZ Plane" -msgstr "Peinture GridMap" +msgstr "Plan XZ de la grille" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid XY Plane" -msgstr "Peinture GridMap" +msgstr "Plan XY de la grille" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid YZ Plane" -msgstr "Peinture GridMap" +msgstr "Plan YZ de la grille" #: editor/editor_settings.cpp msgid "Default FOV" msgstr "FOV par défaut" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Z Near" -msgstr "Thème par défaut" +msgstr "Z proche par défaut" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Z Far" -msgstr "Défaut" +msgstr "Z distant par défaut" #: editor/editor_settings.cpp msgid "Lightmap Baking Number Of CPU Threads" msgstr "Nombre de fils CPU pour calculer les cartes de lumières" #: editor/editor_settings.cpp -#, fuzzy msgid "Navigation Scheme" -msgstr "Mode Navigation" +msgstr "Schéma de navigation" #: editor/editor_settings.cpp -#, fuzzy msgid "Invert Y Axis" -msgstr "Modifier l'axe Y" +msgstr "Inverser l'axe Y" #: editor/editor_settings.cpp -#, fuzzy msgid "Invert X Axis" -msgstr "Modifier l'axe X" +msgstr "Inverser l'axe X" #: editor/editor_settings.cpp msgid "Zoom Style" @@ -5991,14 +5888,12 @@ msgid "Emulate 3 Button Mouse" msgstr "Émuler souris à 3 boutons" #: editor/editor_settings.cpp -#, fuzzy msgid "Orbit Modifier" -msgstr "Trier par date de modification (moins récent au plus récent)" +msgstr "Modificateur d'orbite" #: editor/editor_settings.cpp -#, fuzzy msgid "Pan Modifier" -msgstr "Mode navigation" +msgstr "Modificateur panoramique" #: editor/editor_settings.cpp msgid "Zoom Modifier" @@ -6015,11 +5910,11 @@ msgstr "Mode Navigation" #: editor/editor_settings.cpp msgid "Orbit Sensitivity" -msgstr "" +msgstr "Sensibilité de l'orbite" #: editor/editor_settings.cpp msgid "Orbit Inertia" -msgstr "" +msgstr "Inertie de l'orbite" #: editor/editor_settings.cpp msgid "Translation Inertia" @@ -6030,152 +5925,128 @@ msgid "Zoom Inertia" msgstr "Inertie du Zoom" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook" -msgstr "Vue libre haut" +msgstr "Vue libre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Navigation Scheme" -msgstr "Créer un maillage de navigation" +msgstr "Schéma de navigation en vue libre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Sensitivity" -msgstr "Vue libre gauche" +msgstr "Sensibilité de la vue libre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Inertia" -msgstr "Vue libre gauche" +msgstr "Inertie de la vue libre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Base Speed" -msgstr "Modificateur de vitesse de la vue libre" +msgstr "Vitesse de base de la vue libre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Activation Modifier" -msgstr "Ralentissement de la vue libre" +msgstr "Modificateur d'activation de la vue libre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Speed Zoom Link" -msgstr "Modificateur de vitesse de la vue libre" +msgstr "Lien de zoom rapide de la vue libre" #: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp msgid "Grid Color" msgstr "Couleur de la Grille" #: editor/editor_settings.cpp -#, fuzzy msgid "Guides Color" -msgstr "Prélever une couleur" +msgstr "Couleur des guides" #: editor/editor_settings.cpp -#, fuzzy msgid "Smart Snapping Line Color" -msgstr "Magnétisme intelligent" +msgstr "Couleur de ligne du magnétisme intelligent" #: editor/editor_settings.cpp msgid "Bone Width" msgstr "Largeur des os" #: editor/editor_settings.cpp -#, fuzzy msgid "Bone Color 1" -msgstr "Renommer l'item de couleur" +msgstr "Couleur d'os 1" #: editor/editor_settings.cpp -#, fuzzy msgid "Bone Color 2" -msgstr "Renommer l'item de couleur" +msgstr "Couleur d'os 2" #: editor/editor_settings.cpp -#, fuzzy msgid "Bone Selected Color" -msgstr "Configurer le profil sélectionné :" +msgstr "Couleur de l'os sélectionnée" #: editor/editor_settings.cpp msgid "Bone IK Color" -msgstr "" +msgstr "Couleur de cinématique inverse d'os" #: editor/editor_settings.cpp -#, fuzzy msgid "Bone Outline Color" -msgstr "Couleur de bordure de l'Os" +msgstr "Couleur de contour d'os" #: editor/editor_settings.cpp -#, fuzzy msgid "Bone Outline Size" -msgstr "Taille du contour :" +msgstr "Taille du contour de l'os" #: editor/editor_settings.cpp -#, fuzzy msgid "Viewport Border Color" msgstr "Couleur de bordure de la fenêtre d'affichage" #: editor/editor_settings.cpp -#, fuzzy msgid "Constrain Editor View" msgstr "Restreindre la fenêtre d'Éditeur" #: editor/editor_settings.cpp msgid "Simple Panning" -msgstr "" +msgstr "Panoramique simple" #: editor/editor_settings.cpp msgid "Scroll To Pan" -msgstr "" +msgstr "Panoramique au défilement" #: editor/editor_settings.cpp -#, fuzzy msgid "Pan Speed" msgstr "Vitesse Panoramique" #: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Poly Editor" -msgstr "Éditeur UV de polygones 2D" +msgstr "Éditeur de polygones" #: editor/editor_settings.cpp msgid "Point Grab Radius" -msgstr "" +msgstr "Rayon de saisie par point" #: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Show Previous Outline" -msgstr "Plan précédent" +msgstr "Montrer le contour précédent" #: editor/editor_settings.cpp editor/scene_tree_dock.cpp -#, fuzzy msgid "Autorename Animation Tracks" -msgstr "Renommer l'animation" +msgstr "Renommer les pistes d'animation automatiquement" #: editor/editor_settings.cpp msgid "Default Create Bezier Tracks" -msgstr "" +msgstr "Créer pistes de Bézier par défaut" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Create Reset Tracks" -msgstr "Créer des pistes RESET" +msgstr "Créer pistes de réinitialisation par défaut" #: editor/editor_settings.cpp -#, fuzzy msgid "Onion Layers Past Color" -msgstr "Couleur de couche Oignon précedente" +msgstr "Couleur des couches d'oignon précedentes" #: editor/editor_settings.cpp -#, fuzzy msgid "Onion Layers Future Color" -msgstr "Couleur de la couche d'Oignon suivante" +msgstr "Couleur des couches d'oignon suivantes" #: editor/editor_settings.cpp -#, fuzzy msgid "Visual Editors" -msgstr "Editeur de groupe" +msgstr "Éditeurs visuels" #: editor/editor_settings.cpp msgid "Minimap Opacity" @@ -6192,18 +6063,16 @@ msgid "Rect" msgstr "Rect" #: editor/editor_settings.cpp -#, fuzzy msgid "Rect Custom Position" -msgstr "Définir la position de sortie de la courbe" +msgstr "Position du Rect personnalisée" #: editor/editor_settings.cpp platform/android/export/export_plugin.cpp msgid "Screen" msgstr "Écran" #: editor/editor_settings.cpp -#, fuzzy msgid "Auto Save" -msgstr "Coupe automatique" +msgstr "Sauvegarde auto" #: editor/editor_settings.cpp msgid "Save Before Running" @@ -6220,14 +6089,12 @@ msgstr "Hôte distant" #: editor/editor_settings.cpp #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Remote Port" -msgstr "Supprimer un point" +msgstr "Port distant" #: editor/editor_settings.cpp -#, fuzzy msgid "Editor SSL Certificates" -msgstr "Paramètres de l'éditeur" +msgstr "Certificats SSL de l’éditeur" #: editor/editor_settings.cpp msgid "HTTP Proxy" @@ -6255,7 +6122,7 @@ msgstr "Ordre de Tri" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Symbol Color" -msgstr "" +msgstr "Couleur de symbole" #: editor/editor_settings.cpp msgid "Keyword Color" @@ -6263,29 +6130,27 @@ msgstr "Couleur des mots-clés" #: editor/editor_settings.cpp msgid "Control Flow Keyword Color" -msgstr "" +msgstr "Couleur de mot clé de contrôle de flux" #: editor/editor_settings.cpp -#, fuzzy msgid "Base Type Color" -msgstr "Changer le type de base" +msgstr "Couleur de base des types" #: editor/editor_settings.cpp msgid "Engine Type Color" -msgstr "" +msgstr "Couleur de type du moteur" #: editor/editor_settings.cpp msgid "User Type Color" -msgstr "" +msgstr "Couleur de type utilisateur" #: editor/editor_settings.cpp msgid "Comment Color" msgstr "Couleur des commentaires" #: editor/editor_settings.cpp -#, fuzzy msgid "String Color" -msgstr "Stockage du fichier :" +msgstr "Couleur des chaînes de caractères" #: editor/editor_settings.cpp platform/javascript/export/export.cpp #: platform/uwp/export/export.cpp @@ -6294,9 +6159,8 @@ msgid "Background Color" msgstr "Couleur d’Arrière-Plan" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Completion Background Color" -msgstr "Couleur de fond invalide." +msgstr "Couleur d'arrière-plan de complétion" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -6324,23 +6188,20 @@ msgid "Line Number Color" msgstr "Couleur du Numéro de Ligne" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Safe Line Number Color" -msgstr "Numéro de ligne :" +msgstr "Couleur des nombres des lignes sûres" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Caret Color" msgstr "Couleur du caret" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Caret Background Color" -msgstr "Couleur de fond invalide." +msgstr "Couleur d'arrière-plan de caret" #: editor/editor_settings.cpp -#, fuzzy msgid "Text Selected Color" -msgstr "Supprimer la selection" +msgstr "Couleur de texte sélectionné" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Selection Color" @@ -6348,7 +6209,7 @@ msgstr "Couleur de la Sélection" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Brace Mismatch Color" -msgstr "" +msgstr "Couleur des erreur de fermeture d'accolades" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Current Line Color" @@ -6356,26 +6217,23 @@ msgstr "Couleur de la Ligne Actuelle" #: editor/editor_settings.cpp msgid "Line Length Guideline Color" -msgstr "" +msgstr "Couleur du guide de longueur de ligne" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Word Highlighted Color" -msgstr "Coloration syntaxique" +msgstr "Couleur de surlignage des mots" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Number Color" msgstr "Couleur des nombres" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Function Color" -msgstr "Fonction" +msgstr "Couleur des fonctions" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Member Variable Color" -msgstr "Renommer la variable" +msgstr "Couleur des variables de membres" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -6383,33 +6241,28 @@ msgid "Mark Color" msgstr "Prélever une couleur" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Bookmark Color" -msgstr "Signets" +msgstr "Couleur des signets" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Breakpoint Color" -msgstr "Point d'arrêts" +msgstr "Couleur des point d'arrêts" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Executing Line Color" msgstr "Couleur de la ligne d’exécution" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Code Folding Color" -msgstr "" +msgstr "Couleur du repliage de code" #: editor/editor_settings.cpp -#, fuzzy msgid "Search Result Color" -msgstr "Résultats de recherche" +msgstr "Couleur des résultats de recherche" #: editor/editor_settings.cpp -#, fuzzy msgid "Search Result Border Color" -msgstr "Résultats de recherche" +msgstr "Couleur de bordure des résultats de recherche" #: editor/editor_spin_slider.cpp msgid "Hold %s to round to integers. Hold Shift for more precise changes." @@ -6422,9 +6275,8 @@ msgid "Flat" msgstr "Plat" #: editor/editor_spin_slider.cpp -#, fuzzy msgid "Hide Slider" -msgstr "Mode collision" +msgstr "Cacher la barre de défilement" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" @@ -6722,7 +6574,6 @@ msgstr "" "téléchargement est terminé." #: editor/fileserver/editor_file_server.cpp -#, fuzzy msgid "File Server" msgstr "Serveur de fichiers" @@ -7101,7 +6952,7 @@ msgstr "Collada" #: editor/import/editor_import_collada.cpp msgid "Use Ambient" -msgstr "" +msgstr "Utiliser ambiant" #: editor/import/resource_importer_bitmask.cpp msgid "Create From" @@ -7110,7 +6961,7 @@ msgstr "Créer à Partir de" #: editor/import/resource_importer_bitmask.cpp #: servers/audio/effects/audio_effect_compressor.cpp msgid "Threshold" -msgstr "" +msgstr "Seuil" #: editor/import/resource_importer_csv_translation.cpp #: editor/import/resource_importer_layered_texture.cpp @@ -7122,7 +6973,7 @@ msgstr "Compresser" #: editor/import/resource_importer_csv_translation.cpp msgid "Delimiter" -msgstr "" +msgstr "Délimiteur" #: editor/import/resource_importer_layered_texture.cpp #, fuzzy @@ -7160,9 +7011,8 @@ msgstr "Mipmaps" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Anisotropic" -msgstr "Anisotropie" +msgstr "Anisotrope" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp @@ -7170,9 +7020,8 @@ msgid "sRGB" msgstr "sRGB" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "Slices" -msgstr "Coupures" +msgstr "Tranches" #: editor/import/resource_importer_layered_texture.cpp #: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp @@ -7202,7 +7051,6 @@ msgstr "Décalage du maillage" #: editor/import/resource_importer_obj.cpp #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Octahedral Compression" msgstr "Compression Octaédrique" @@ -7276,9 +7124,8 @@ msgid "Storage" msgstr "Stockage" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Use Legacy Names" -msgstr "Utiliser des noms classiques" +msgstr "Utiliser les noms hérités" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp msgid "Materials" @@ -7298,9 +7145,8 @@ msgid "Ensure Tangents" msgstr "Modifier la tangente de courbes" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Light Baking" -msgstr "Pré-calculer les cartes de lumières" +msgstr "Pré-calculer les lumières" #: editor/import/resource_importer_scene.cpp msgid "Lightmap Texel Size" @@ -7308,24 +7154,21 @@ msgstr "Taille des Texels dans la carte de lumières" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp msgid "Skins" -msgstr "" +msgstr "Enveloppes" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Use Named Skins" -msgstr "Utiliser le magnétisme d'échelle" +msgstr "Utiliser les enveloppes nommées" #: editor/import/resource_importer_scene.cpp msgid "External Files" msgstr "Fichiers externes" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Store In Subdir" msgstr "Stocker dans un sous-dossier" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Filter Script" msgstr "Filtrer les scripts" @@ -7361,17 +7204,14 @@ msgid "Max Angular Error" msgstr "Erreur Angulaire Max" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Max Angle" -msgstr "Valeur" +msgstr "Angle maximal" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Remove Unused Tracks" -msgstr "Supprimer la piste d’animation" +msgstr "Retirer les pistes inutilisées" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Clips" msgstr "Clips d'animation" @@ -7459,7 +7299,7 @@ msgstr "Mode HDR" #: editor/import/resource_importer_texture.cpp msgid "BPTC LDR" -msgstr "" +msgstr "BPTC LDR" #: editor/import/resource_importer_texture.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp @@ -7477,9 +7317,8 @@ msgid "Fix Alpha Border" msgstr "Corriger la bordure alpha" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Premult Alpha" -msgstr "Modifier le polygone" +msgstr "Alpha pré-multiplié" #: editor/import/resource_importer_texture.cpp msgid "Hdr As Srgb" @@ -7523,13 +7362,12 @@ msgid "Import Mode" msgstr "Mode d'Importation" #: editor/import/resource_importer_texture_atlas.cpp -#, fuzzy msgid "Crop To Region" -msgstr "Définir la région de la tuile" +msgstr "Rogner vers la région" #: editor/import/resource_importer_texture_atlas.cpp msgid "Trim Alpha Border From Region" -msgstr "" +msgstr "Rogner les bordures alpha de la région" #: editor/import/resource_importer_wav.cpp scene/2d/physics_body_2d.cpp msgid "Force" @@ -7554,7 +7392,7 @@ msgstr "Taux maximal en Hz" #: editor/import/resource_importer_wav.cpp msgid "Trim" -msgstr "" +msgstr "Rogner" #: editor/import/resource_importer_wav.cpp msgid "Normalize" @@ -7662,7 +7500,6 @@ msgid "Raw" msgstr "Brut" #: editor/inspector_dock.cpp -#, fuzzy msgid "Capitalized" msgstr "Majuscule à chaque mot" @@ -8476,7 +8313,7 @@ msgstr "Mélange 1 :" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "X-Fade Time (s):" -msgstr "Durée du fondu (s) :" +msgstr "Durée du fondu croisé (s) :" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9717,7 +9554,6 @@ msgid "Swap GradientTexture2D Fill Points" msgstr "Échanger les points de remplissage du GradientTexture2D" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp -#, fuzzy msgid "Swap Gradient Fill Points" msgstr "Échanger les points de remplissage du dégradé" @@ -10015,14 +9851,12 @@ msgid "Update from Scene" msgstr "Mettre à jour depuis la scène" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Apply without Transforms" -msgstr "Appliquer la transformation du MeshInstance" +msgstr "Appliquer sans transformations" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Apply with Transforms" -msgstr "Appliquer la transformation du MeshInstance" +msgstr "Appliquer avec transformations" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." @@ -10899,9 +10733,8 @@ msgid "Exec Path" msgstr "Chemin d'exécution" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Script Temperature Enabled" -msgstr "Sélectionner le fichier de modèles" +msgstr "Température de script activée" #: editor/plugins/script_editor_plugin.cpp msgid "Highlight Current Script" @@ -10909,16 +10742,15 @@ msgstr "Mettre en évidence le script actuel" #: editor/plugins/script_editor_plugin.cpp msgid "Script Temperature History Size" -msgstr "" +msgstr "Taille de l'historique des températures de script" #: editor/plugins/script_editor_plugin.cpp msgid "Current Script Background Color" msgstr "Couleur d'Arrière-Plan du Script Actuel" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Group Help Pages" -msgstr "Groupe sélectionné" +msgstr "Pages d'aide de groupe" #: editor/plugins/script_editor_plugin.cpp msgid "Sort Scripts By" @@ -11751,11 +11583,11 @@ msgstr "Post" #: editor/plugins/spatial_editor_plugin.cpp msgid "Manipulator Gizmo Size" -msgstr "" +msgstr "Taille des manipulateurs" #: editor/plugins/spatial_editor_plugin.cpp msgid "Manipulator Gizmo Opacity" -msgstr "" +msgstr "Opacité des manipulateurs" #: editor/plugins/spatial_editor_plugin.cpp msgid "Show Viewport Rotation Gizmo" @@ -11916,6 +11748,10 @@ msgid "New Animation" msgstr "Nouvelle animation" #: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Filter animations" +msgstr "Filtrer les animations" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Vitesse :" @@ -12385,9 +12221,8 @@ msgid "Select Another Theme Resource:" msgstr "Sélectionnez une autre ressource Theme :" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Theme Resource" -msgstr "Ressource de Thème" +msgstr "Ressource de thème" #: editor/plugins/theme_editor_plugin.cpp msgid "Another Theme" @@ -12443,9 +12278,8 @@ msgid "Add Item Type" msgstr "Ajouter un item de type" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Set Variation Base Type" -msgstr "Définir type de variable" +msgstr "Définir le type parent de la variation" #: editor/plugins/theme_editor_plugin.cpp msgid "Set Base Type" @@ -12471,15 +12305,16 @@ msgstr "Surcharge tous les items de type par défaut." #: editor/plugins/theme_editor_plugin.cpp msgid "Select the variation base type from a list of available types." msgstr "" +"Choisissez le type parent de la variation depuis la liste des types " +"disponibles." #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "" "A type associated with a built-in class cannot be marked as a variation of " "another type." msgstr "" -"Un type affilié à une classe intégré ne peut pas être marqué comme une " -"variante d'un autre type." +"Un type affilié à une classe intégrée ne peut pas être marqué comme variante " +"d'un autre type." #: editor/plugins/theme_editor_plugin.cpp msgid "Theme:" @@ -12746,9 +12581,8 @@ msgid "Sort Tiles By Name" msgstr "Trier les tuiles par nom" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Bucket Fill Preview" -msgstr "Remplissage du seau" +msgstr "Aperçu du remplissage" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp @@ -13142,9 +12976,8 @@ msgid "Texture" msgstr "Texture" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tex Offset" -msgstr "Décalage d’Octet" +msgstr "Décalage de texture" #: editor/plugins/tile_set_editor_plugin.cpp modules/csg/csg_shape.cpp #: scene/2d/canvas_item.cpp scene/2d/particles_2d.cpp @@ -13158,14 +12991,12 @@ msgid "Modulate" msgstr "Moduler" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tile Mode" -msgstr "Basculer le mode" +msgstr "Mode de tuile" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Autotile Bitmask Mode" -msgstr "Mode Bitmask" +msgstr "Mode de masque d'octet de tuile auto" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Subtile Size" @@ -13196,28 +13027,24 @@ msgid "Selected Collision" msgstr "Collision sélectionné" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision One Way" -msgstr "Sélection uniquement" +msgstr "Collision à sens unique de la sélection" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision One Way Margin" -msgstr "Mode collision" +msgstr "Marge de collision à sens unique de la sélection" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Selected Navigation" msgstr "Navigation sélectionnée" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Occlusion" -msgstr "Sélectionner" +msgstr "Occultation de la sélection" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tileset Script" -msgstr "Filtrer les scripts" +msgstr "Script de palette de tuiles" #: editor/plugins/tile_set_editor_plugin.cpp msgid "TileSet" @@ -14440,7 +14267,7 @@ msgstr "Plus d'informations..." #: editor/project_export.cpp msgid "Export PCK/Zip..." -msgstr "Exporter le PCK/ZIP" +msgstr "Exporter le PCK/ZIP..." #: editor/project_export.cpp msgid "Export Project..." @@ -15506,7 +15333,7 @@ msgstr "Supprimer le nœud \"%s\" et ses enfants ?" #: editor/scene_tree_dock.cpp msgid "Delete node \"%s\"?" -msgstr "Supprimer le noeud \"%s\" ?" +msgstr "Supprimer le nœud \"%s\" ?" #: editor/scene_tree_dock.cpp msgid "" @@ -15683,7 +15510,7 @@ msgstr "Ressources secondaires" #: editor/scene_tree_dock.cpp msgid "Access as Scene Unique Name" -msgstr "" +msgstr "Accéder en tant que nom unique de scène" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance" @@ -15783,18 +15610,16 @@ msgid "Clear Inheritance? (No Undo!)" msgstr "Effacer l'héritage ? (Pas de retour en arrière !)" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Show Scene Tree Root Selection" -msgstr "Afficher la sélection de la racine de l'arborescence" +msgstr "Afficher la sélection de la racine de la hiérarchie de la scène" #: editor/scene_tree_dock.cpp msgid "Derive Script Globals By Name" -msgstr "" +msgstr "Dériver les Globals de scripts par nom" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Use Favorites Root Selection" -msgstr "Encadrer la sélection" +msgstr "Utiliser la sélection racine des favoris" #: editor/scene_tree_editor.cpp msgid "Toggle Visible" @@ -16116,7 +15941,7 @@ msgstr "Filtrer les variables de la pile" #: editor/script_editor_debugger.cpp msgid "Auto Switch To Remote Scene Tree" -msgstr "" +msgstr "Basculer automatiquement vers l'arborescence de scène distante" #: editor/script_editor_debugger.cpp msgid "Remote Scene Tree Refresh Interval" @@ -16124,7 +15949,7 @@ msgstr "Intervalle de rafraîchissement de l'arborescence distante" #: editor/script_editor_debugger.cpp msgid "Remote Inspect Refresh Interval" -msgstr "" +msgstr "Intervalle de rafraîchissement d'inspection distante" #: editor/script_editor_debugger.cpp msgid "Network Profiler" @@ -16222,9 +16047,8 @@ msgid "Change Light Radius" msgstr "Changer le rayon d'une lumière" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Stream Player 3D" -msgstr "Émetteur de flux sonore 3D" +msgstr "Émetteur de flux 3D" #: editor/spatial_editor_gizmos.cpp msgid "Change AudioStreamPlayer3D Emission Angle" @@ -16269,9 +16093,8 @@ msgid "GI Probe" msgstr "Sonde GI" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Baked Indirect Light" -msgstr "Éclairage indirect" +msgstr "Éclairage indirect pré-calculé" #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp msgid "Change Sphere Shape Radius" @@ -16310,22 +16133,20 @@ msgid "Navigation Edge Disabled" msgstr "Bord de la Navigation Désactivé" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Solid" -msgstr "Mode Navigation" +msgstr "Solide de navigation" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Solid Disabled" -msgstr "Mode Navigation" +msgstr "Solide de navigation désactivé" #: editor/spatial_editor_gizmos.cpp msgid "Joint Body A" -msgstr "" +msgstr "Jointure Corps A" #: editor/spatial_editor_gizmos.cpp msgid "Joint Body B" -msgstr "" +msgstr "Jointure Corps B" #: editor/spatial_editor_gizmos.cpp msgid "Room Edge" @@ -16333,7 +16154,7 @@ msgstr "Bord de la pièce" #: editor/spatial_editor_gizmos.cpp msgid "Room Overlap" -msgstr "" +msgstr "Chevauchement de salle" #: editor/spatial_editor_gizmos.cpp msgid "Set Room Point Position" @@ -16349,7 +16170,7 @@ msgstr "Bords du portail" #: editor/spatial_editor_gizmos.cpp msgid "Portal Arrow" -msgstr "" +msgstr "Flèche de portail" #: editor/spatial_editor_gizmos.cpp msgid "Set Portal Point Position" @@ -16377,44 +16198,38 @@ msgid "Set Occluder Sphere Position" msgstr "Définir la position de la sphère de l'occulteur" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Set Occluder Polygon Point Position" -msgstr "Définir la position du point du Portal" +msgstr "Définir la position ponctuelle du polygone occulteur" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Set Occluder Hole Point Position" -msgstr "Définir la position du point de la courbe" +msgstr "Définir la position ponctuelle du trou occulteur" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Polygon Front" -msgstr "Créer un polygone occulteur" +msgstr "Avant du polygone occulteur" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Polygon Back" -msgstr "Créer un polygone occulteur" +msgstr "Arrière du polygone occulteur" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Hole" -msgstr "Créer un polygone occulteur" +msgstr "Trou occulteur" #: main/main.cpp msgid "Godot Physics" -msgstr "" +msgstr "Calculs de physique de Godot" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp msgid "Use BVH" -msgstr "" +msgstr "Utiliser BVH" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp -#, fuzzy msgid "BVH Collision Margin" -msgstr "Mode collision" +msgstr "Marge de collision BVH" #: main/main.cpp msgid "Crash Handler" @@ -16450,7 +16265,7 @@ msgstr "Maximum d'avertissements par secondes" #: main/main.cpp msgid "Flush stdout On Print" -msgstr "" +msgstr "Vider stdout à l'impression" #: main/main.cpp servers/visual_server.cpp msgid "Logging" @@ -16490,11 +16305,11 @@ msgstr "" #: main/main.cpp msgid "DPI" -msgstr "" +msgstr "PPP" #: main/main.cpp msgid "Allow hiDPI" -msgstr "" +msgstr "Autoriser PPP élevé" #: main/main.cpp msgid "V-Sync" @@ -16538,7 +16353,7 @@ msgstr "" #: main/main.cpp msgid "Handheld" -msgstr "" +msgstr "Portable" #: main/main.cpp platform/javascript/export/export.cpp #: platform/uwp/export/export.cpp @@ -16578,7 +16393,7 @@ msgstr "Sortie Standard" #: main/main.cpp msgid "Print FPS" -msgstr "" +msgstr "Afficher les FPS" #: main/main.cpp msgid "Verbose stdout" @@ -16622,7 +16437,7 @@ msgstr "Pointage" #: main/main.cpp msgid "Touch Delay" -msgstr "" +msgstr "Retard d'appui" #: main/main.cpp servers/visual_server.cpp msgid "GLES3" @@ -16633,9 +16448,8 @@ msgid "Shaders" msgstr "Shaders" #: main/main.cpp -#, fuzzy msgid "Debug Shader Fallbacks" -msgstr "Forcer les replis du shader" +msgstr "Valeurs de repli du shader de débogage" #: main/main.cpp scene/3d/baked_lightmap.cpp scene/3d/camera.cpp #: scene/3d/world_environment.cpp scene/main/scene_tree.cpp @@ -16681,7 +16495,7 @@ msgstr "Icône native de Windows" #: main/main.cpp msgid "Buffering" -msgstr "" +msgstr "Mise en mémoire tampon" #: main/main.cpp msgid "Agile Event Flushing" @@ -16712,9 +16526,8 @@ msgid "Tooltip Position Offset" msgstr "Décalage de la position des info-bulles" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp -#, fuzzy msgid "Debugger Agent" -msgstr "Débogueur" +msgstr "Agent du débogueur" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp msgid "Wait For Debugger" @@ -16726,11 +16539,11 @@ msgstr "Délai d'Attente" #: main/main.cpp msgid "Runtime" -msgstr "" +msgstr "Exécution" #: main/main.cpp msgid "Unhandled Exception Policy" -msgstr "" +msgstr "Politique d'exceptions non gérées" #: main/main.cpp msgid "Main Loop Type" @@ -16754,14 +16567,12 @@ msgid "Auto Accept Quit" msgstr "Accepter automatiquement la fermeture" #: main/main.cpp scene/main/scene_tree.cpp -#, fuzzy msgid "Quit On Go Back" -msgstr "Retourner" +msgstr "Quitter au retour" #: main/main.cpp scene/main/viewport.cpp -#, fuzzy msgid "Snap Controls To Pixels" -msgstr "Aimanter aux flancs du nœud" +msgstr "Aimanter les contrôles aux pixels" #: main/main.cpp msgid "Dynamic Fonts" @@ -16769,7 +16580,7 @@ msgstr "Polices Dynamiques" #: main/main.cpp msgid "Use Oversampling" -msgstr "" +msgstr "Utiliser le suréchantillonnage" #: modules/bullet/register_types.cpp modules/bullet/space_bullet.cpp msgid "Active Soft World" @@ -16796,35 +16607,30 @@ msgid "Change Torus Outer Radius" msgstr "Changer le rayon extérieur de la tour" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Operation" -msgstr "Options" +msgstr "Opération" #: modules/csg/csg_shape.cpp msgid "Calculate Tangents" msgstr "Calculer les Tangentes" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Use Collision" -msgstr "Collision" +msgstr "Utiliser les collisions" #: modules/csg/csg_shape.cpp servers/physics_2d_server.cpp -#, fuzzy msgid "Collision Layer" -msgstr "Mode collision" +msgstr "Couche des collisions" #: modules/csg/csg_shape.cpp scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp #: scene/3d/ray_cast.cpp scene/3d/spring_arm.cpp #: scene/resources/navigation_mesh.cpp servers/physics_server.cpp -#, fuzzy msgid "Collision Mask" -msgstr "Mode collision" +msgstr "Masque de collisions" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Invert Faces" -msgstr "Modifier la casse" +msgstr "Inverses les faces" #: modules/csg/csg_shape.cpp scene/2d/navigation_agent_2d.cpp #: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_agent.cpp @@ -16842,57 +16648,50 @@ msgid "Radial Segments" msgstr "Segments radiaux" #: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Rings" -msgstr "Avertissements" +msgstr "Anneaux" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Smooth Faces" -msgstr "Progression douce" +msgstr "Adoucir les faces" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Sides" -msgstr "Afficher les guides" +msgstr "Côtés" #: modules/csg/csg_shape.cpp msgid "Cone" -msgstr "" +msgstr "Cone" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Inner Radius" -msgstr "Changer le rayon intérieur de la tour" +msgstr "Rayon intérieur" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Outer Radius" -msgstr "Changer le rayon extérieur de la tour" +msgstr "Rayon extérieur" #: modules/csg/csg_shape.cpp msgid "Ring Sides" -msgstr "" +msgstr "Côtés de l'anneau" #: modules/csg/csg_shape.cpp scene/2d/collision_polygon_2d.cpp #: scene/2d/light_occluder_2d.cpp scene/2d/polygon_2d.cpp #: scene/3d/collision_polygon.cpp -#, fuzzy msgid "Polygon" -msgstr "Polygones" +msgstr "Polygone" #: modules/csg/csg_shape.cpp msgid "Spin Degrees" -msgstr "" +msgstr "Degrés de tour" #: modules/csg/csg_shape.cpp msgid "Spin Sides" -msgstr "" +msgstr "Côtés du tour" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Node" -msgstr "Coller les nœuds" +msgstr "Noeud de chemin" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16901,35 +16700,31 @@ msgstr "Créer un vertex interne" #: modules/csg/csg_shape.cpp msgid "Path Interval" -msgstr "" +msgstr "Intervalle de chemin" #: modules/csg/csg_shape.cpp msgid "Path Simplify Angle" -msgstr "" +msgstr "Simplification d'angle de chemin" #: modules/csg/csg_shape.cpp msgid "Path Rotation" msgstr "Rotation du chemin" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Local" -msgstr "Rendre local" +msgstr "Chemin local" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Continuous U" -msgstr "Continu" +msgstr "Chemin Continu U" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path U Distance" -msgstr "Choisissez distance :" +msgstr "Distance du chemin U" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Joined" -msgstr "Rotation aléatoire :" +msgstr "Chemin joint" #: modules/enet/networked_multiplayer_enet.cpp msgid "Compression Mode" @@ -16949,7 +16744,7 @@ msgstr "Toujours ordonnée" #: modules/enet/networked_multiplayer_enet.cpp msgid "Server Relay" -msgstr "" +msgstr "Relais serveur" #: modules/enet/networked_multiplayer_enet.cpp msgid "DTLS Verify" @@ -16976,9 +16771,8 @@ msgid "Config File" msgstr "Fichier de Configuration" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Load Once" -msgstr "Charger une ressource" +msgstr "Charger une fois" #: modules/gdnative/gdnative.cpp #: modules/visual_script/visual_script_func_nodes.cpp @@ -17198,9 +16992,8 @@ msgid "Sparse Indices Byte Offset" msgstr "" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Sparse Indices Component Type" -msgstr "Analyse de la géométrie..." +msgstr "Type de composant d'indices épars" #: modules/gltf/gltf_accessor.cpp msgid "Sparse Values Buffer View" @@ -17274,9 +17067,8 @@ msgid "Blend Weights" msgstr "Précalculer les lightmaps" #: modules/gltf/gltf_mesh.cpp -#, fuzzy msgid "Instance Materials" -msgstr "Changements de matériau :" +msgstr "Matériaux d'instances" #: modules/gltf/gltf_node.cpp scene/3d/skeleton.cpp msgid "Parent" @@ -17289,25 +17081,21 @@ msgstr "Plateforme" #: modules/gltf/gltf_node.cpp scene/3d/mesh_instance.cpp msgid "Skin" -msgstr "" +msgstr "Enveloppe" #: modules/gltf/gltf_node.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Translation" -msgstr "Traductions" +msgstr "Translation" #: modules/gltf/gltf_node.cpp -#, fuzzy msgid "Children" -msgstr "Enfants modifiables" +msgstr "Enfants" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints" -msgstr "Point" +msgstr "Jointures" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Roots" msgstr "Racines" @@ -17316,48 +17104,42 @@ msgid "Unique Names" msgstr "Noms Uniques" #: modules/gltf/gltf_skeleton.cpp -#, fuzzy msgid "Godot Bone Node" -msgstr "Le nœud de la scène" +msgstr "Nœud d'os de Godot" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Skin Root" -msgstr "Nouvelle racine de scène" +msgstr "Racine de l'enveloppe" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints Original" -msgstr "Focaliser l'origine" +msgstr "Jointure à l'original" #: modules/gltf/gltf_skin.cpp msgid "Inverse Binds" -msgstr "" +msgstr "Inverser les liens" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Non Joints" -msgstr "Déplacer la jointure" +msgstr "Non jointures" #: modules/gltf/gltf_skin.cpp msgid "Joint I To Bone I" -msgstr "" +msgstr "Jointure I à os I" #: modules/gltf/gltf_skin.cpp msgid "Joint I To Name" -msgstr "" +msgstr "Jointure I à nom" #: modules/gltf/gltf_skin.cpp msgid "Godot Skin" -msgstr "" +msgstr "Enveloppe Godot" #: modules/gltf/gltf_spec_gloss.cpp -#, fuzzy msgid "Diffuse Img" msgstr "Image Diffuse" #: modules/gltf/gltf_spec_gloss.cpp -#, fuzzy msgid "Diffuse Factor" msgstr "Facteur de diffusion" @@ -17375,50 +17157,44 @@ msgstr "" #: modules/gltf/gltf_state.cpp msgid "Json" -msgstr "" +msgstr "Json" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Major Version" -msgstr "Version" +msgstr "Version majeure" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Minor Version" -msgstr "Version" +msgstr "Version mineure" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "GLB Data" -msgstr "Avec données" +msgstr "Données GLB" #: modules/gltf/gltf_state.cpp msgid "Use Named Skin Binds" -msgstr "" +msgstr "Utiliser les liens d'enveloppe par nom" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Buffer Views" -msgstr "Vue de derrière" +msgstr "Vues tampon" #: modules/gltf/gltf_state.cpp msgid "Accessors" -msgstr "" +msgstr "Accesseurs" #: modules/gltf/gltf_state.cpp msgid "Scene Name" msgstr "Nom de la Scène" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Root Nodes" -msgstr "Nom de nœud racine" +msgstr "Nœuds racines" #: modules/gltf/gltf_state.cpp scene/2d/particles_2d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_progress.cpp -#, fuzzy msgid "Textures" -msgstr "Fonctionnalités" +msgstr "Textures" #: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp msgid "Images" @@ -17429,42 +17205,36 @@ msgid "Cameras" msgstr "Caméras" #: modules/gltf/gltf_state.cpp servers/visual_server.cpp -#, fuzzy msgid "Lights" -msgstr "Lumière" +msgstr "Lumières" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Unique Animation Names" -msgstr "Nom de la nouvelle animation :" +msgstr "Noms d'animations uniques" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeletons" -msgstr "Squelette" +msgstr "Squelettes" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeleton To Node" -msgstr "Sélectionner un nœud" +msgstr "Squelette vers nœud" #: modules/gltf/gltf_state.cpp msgid "Animations" msgstr "Animations" #: modules/gltf/gltf_texture.cpp -#, fuzzy msgid "Src Image" -msgstr "Afficher les os" +msgstr "Image source" #: modules/gridmap/grid_map.cpp msgid "Mesh Library" msgstr "Librairie de maillages" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Physics Material" -msgstr "Image physique %" +msgstr "Matériau physique" #: modules/gridmap/grid_map.cpp scene/3d/visual_instance.cpp #, fuzzy @@ -17476,24 +17246,20 @@ msgid "Cell" msgstr "Cellule" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Octant Size" -msgstr "Vue de devant" +msgstr "Taille d'octant" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center X" -msgstr "Centre" +msgstr "X du centre" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Y" -msgstr "Centre" +msgstr "Y du centre" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Z" -msgstr "Centre" +msgstr "Z du centre" #: modules/gridmap/grid_map.cpp scene/2d/collision_object_2d.cpp #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp @@ -17502,17 +17268,15 @@ msgid "Mask" msgstr "Masque" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp -#, fuzzy msgid "Bake Navigation" -msgstr "Navigation" +msgstr "Pré-calculer la navigation" #: modules/gridmap/grid_map.cpp scene/2d/navigation_2d.cpp #: scene/2d/navigation_agent_2d.cpp scene/2d/navigation_polygon.cpp #: scene/2d/tile_map.cpp scene/3d/navigation.cpp scene/3d/navigation_agent.cpp #: scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Navigation Layers" -msgstr "Mode Navigation" +msgstr "Calques de navigation" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Plane" @@ -17700,7 +17464,6 @@ msgid "Loop Offset" msgstr "Décalage de Boucle" #: modules/mobile_vr/mobile_vr_interface.cpp -#, fuzzy msgid "Eye Height" msgstr "Hauteur de l’œil" @@ -17719,15 +17482,15 @@ msgstr "Afficher sans ombrage" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Oversample" -msgstr "" +msgstr "Suréchantillonner" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "K1" -msgstr "" +msgstr "K1" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "K2" -msgstr "" +msgstr "K2" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -17814,14 +17577,13 @@ msgstr "C'est fait !" #: modules/opensimplex/noise_texture.cpp msgid "Seamless" -msgstr "" +msgstr "Sans bord" #: modules/opensimplex/noise_texture.cpp msgid "As Normal Map" msgstr "En tant que carte de normales" #: modules/opensimplex/noise_texture.cpp -#, fuzzy msgid "Bump Strength" msgstr "Force du bossage" @@ -17830,12 +17592,10 @@ msgid "Noise" msgstr "Bruit" #: modules/opensimplex/noise_texture.cpp -#, fuzzy msgid "Noise Offset" -msgstr "Décalage de la grille :" +msgstr "Décalage du bruit" #: modules/opensimplex/open_simplex_noise.cpp -#, fuzzy msgid "Octaves" msgstr "Octaves" @@ -17844,28 +17604,24 @@ msgid "Period" msgstr "Période" #: modules/opensimplex/open_simplex_noise.cpp -#, fuzzy msgid "Persistence" -msgstr "Perspective" +msgstr "Persistance" #: modules/opensimplex/open_simplex_noise.cpp msgid "Lacunarity" -msgstr "" +msgstr "Lacunarité" #: modules/regex/regex.cpp -#, fuzzy msgid "Subject" msgstr "Sujet" #: modules/regex/regex.cpp -#, fuzzy msgid "Names" -msgstr "Nom" +msgstr "Noms" #: modules/regex/regex.cpp -#, fuzzy msgid "Strings" -msgstr "Paramètres :" +msgstr "Paramètres" #: modules/upnp/upnp.cpp msgid "Discover Multicast If" @@ -17873,39 +17629,35 @@ msgstr "" #: modules/upnp/upnp.cpp msgid "Discover Local Port" -msgstr "" +msgstr "Révéler le port local" #: modules/upnp/upnp.cpp msgid "Discover IPv6" msgstr "Découvrir IPv6" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "Description URL" -msgstr "Description" +msgstr "URL de description" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "Service Type" -msgstr "Définir type de variable" +msgstr "Type du service" #: modules/upnp/upnp_device.cpp msgid "IGD Control URL" -msgstr "" +msgstr "URL de contrôle IGD" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "IGD Service Type" -msgstr "Définir type de variable" +msgstr "Type de service IGD" #: modules/upnp/upnp_device.cpp msgid "IGD Our Addr" msgstr "" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "IGD Status" -msgstr "État" +msgstr "État IGD" #: modules/visual_script/visual_script.cpp msgid "" @@ -17946,9 +17698,8 @@ msgid "Stack overflow with stack depth:" msgstr "Débordement de pile avec profondeur de pile :" #: modules/visual_script/visual_script.cpp -#, fuzzy msgid "Visual Script" -msgstr "Rechercher VisualScript" +msgstr "Script graphique" #: modules/visual_script/visual_script_editor.cpp msgid "Change Signal Arguments" @@ -18284,9 +18035,8 @@ msgid "Return Enabled" msgstr "Exécutable" #: modules/visual_script/visual_script_flow_control.cpp -#, fuzzy msgid "Return Type" -msgstr "Retour" +msgstr "Type de retour" #: modules/visual_script/visual_script_flow_control.cpp #: scene/resources/visual_shader_nodes.cpp @@ -18334,7 +18084,6 @@ msgid "in order:" msgstr "dans l'ordre :" #: modules/visual_script/visual_script_flow_control.cpp -#, fuzzy msgid "Steps" msgstr "Pas" @@ -18356,9 +18105,8 @@ msgstr "Est-ce %s ?" #: modules/visual_script/visual_script_flow_control.cpp #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Base Script" -msgstr "Nouveau script" +msgstr "Script de base" #: modules/visual_script/visual_script_func_nodes.cpp msgid "On %s" @@ -18370,36 +18118,31 @@ msgstr "On Self" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_yield_nodes.cpp -#, fuzzy msgid "Call Mode" -msgstr "Mode mise à l'échelle" +msgstr "Mode d'appel" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Basic Type" -msgstr "Changer le type de base" +msgstr "Type simple" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_yield_nodes.cpp -#, fuzzy msgid "Node Path" -msgstr "Copier le chemin du nœud" +msgstr "Chemin de nœud" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Use Default Args" -msgstr "Réinitialiser" +msgstr "Utiliser les valeurs d'arguments par défaut" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Validate" msgstr "Valider" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "RPC Call Mode" -msgstr "Mode mise à l'échelle" +msgstr "Mode d'appel RPC" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Subtract %s" @@ -18438,14 +18181,12 @@ msgid "BitXor %s" msgstr "Ou-exclusif par bit %s" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Set Mode" -msgstr "Mode sélection" +msgstr "Définir le mode" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Assign Op" -msgstr "Assigner" +msgstr "Opérateur d'assignation" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp @@ -18462,9 +18203,8 @@ msgid "Base object is not a Node!" msgstr "L'objet de base n'est pas un nœud !" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Path does not lead to Node!" -msgstr "Le chemin ne mène pas au nœud !" +msgstr "Le chemin ne mène pas vers un nœud !" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name '%s' in node %s." @@ -18480,9 +18220,8 @@ msgstr "Composer le tableau" #: modules/visual_script/visual_script_nodes.cpp scene/resources/material.cpp #: scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Operator" -msgstr "Itérateur" +msgstr "Opérateur" #: modules/visual_script/visual_script_nodes.cpp msgid "Invalid argument of type:" @@ -18497,9 +18236,8 @@ msgid "a if cond, else b" msgstr "a if cond, else b" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Var Name" -msgstr "Nom" +msgstr "Nom de variable" #: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script:" @@ -18624,9 +18362,8 @@ msgid "%s sec(s)" msgstr "%s seconde(s)" #: modules/visual_script/visual_script_yield_nodes.cpp scene/main/timer.cpp -#, fuzzy msgid "Wait Time" -msgstr "Peindre la tuile" +msgstr "Temps d'attente" #: modules/visual_script/visual_script_yield_nodes.cpp msgid "WaitSignal" @@ -18641,16 +18378,14 @@ msgid "WaitInstanceSignal" msgstr "WaitInstanceSignal" #: modules/webrtc/webrtc_data_channel.cpp -#, fuzzy msgid "Write Mode" -msgstr "Mode prioritaire" +msgstr "Mode écriture" #: modules/webrtc/webrtc_data_channel.h msgid "WebRTC" msgstr "WebRTC" #: modules/webrtc/webrtc_data_channel.h -#, fuzzy msgid "Max Channel In Buffer (KB)" msgstr "Maximum de canal dans le tampon (Ko)" @@ -18663,61 +18398,52 @@ msgid "Trusted SSL Certificate" msgstr "Certificat SSL Fiable" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Client" -msgstr "Profileur réseau" +msgstr "Client WebSocket" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max In Buffer (KB)" -msgstr "Taille Maximale (KB)" +msgstr "Maximum tampon entrant (KB)" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max In Packets" -msgstr "Maximum par paquet" +msgstr "Maximum de paquets entrant" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max Out Buffer (KB)" -msgstr "Taille Maximale (KB)" +msgstr "Maximum tampon sortant (KB)" #: modules/websocket/websocket_macros.h msgid "Max Out Packets" -msgstr "" +msgstr "Maximum de paquets sortant" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Server" -msgstr "Profileur réseau" +msgstr "Server WebSocket" #: modules/websocket/websocket_server.cpp msgid "Bind IP" -msgstr "" +msgstr "Lier IP" #: modules/websocket/websocket_server.cpp -#, fuzzy msgid "Private Key" -msgstr "Chemin de la clé privée SSH" +msgstr "Clé privée" #: modules/websocket/websocket_server.cpp platform/javascript/export/export.cpp msgid "SSL Certificate" msgstr "Certificat SSL" #: modules/websocket/websocket_server.cpp -#, fuzzy msgid "CA Chain" -msgstr "Effacer la chaîne IK" +msgstr "Chaîne d’autorité de certificat (CA)" #: modules/websocket/websocket_server.cpp -#, fuzzy msgid "Handshake Timeout" -msgstr "Délai dépassé." +msgstr "Délai de poignée de main expiré" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Session Mode" -msgstr "Mode Région" +msgstr "Mode de session" #: modules/webxr/webxr_interface.cpp msgid "Required Features" @@ -18732,18 +18458,17 @@ msgid "Requested Reference Space Types" msgstr "" #: modules/webxr/webxr_interface.cpp +#, fuzzy msgid "Reference Space Type" -msgstr "" +msgstr "Type de référentiel spatial" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Visibility State" -msgstr "Basculer la visibilité" +msgstr "État de la visibilité" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Bounds Geometry" -msgstr "Réessayer" +msgstr "Géométrie des limites" #: modules/webxr/webxr_interface.cpp #, fuzzy @@ -18769,14 +18494,13 @@ msgstr "" #: platform/android/export/export.cpp msgid "Force System User" -msgstr "" +msgstr "Forcer l'utilisateur système" #: platform/android/export/export.cpp msgid "Shutdown ADB On Exit" -msgstr "" +msgstr "Fermer ADB à la sortie" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Launcher Icons" msgstr "Icônes du lanceur" @@ -18851,27 +18575,22 @@ msgid "Keystore" msgstr "Débogueur" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Debug User" -msgstr "Débogueur" +msgstr "Utilisateur de débogage" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Debug Password" -msgstr "Mot de passe" +msgstr "Mot de passe de débogage" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Release User" -msgstr "Publication (release)" +msgstr "Utilisateur de publication (release)" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Release Password" -msgstr "Mot de passe" +msgstr "Mot de passe de publication" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "One Click Deploy" msgstr "Déploiement en un clic" @@ -18884,18 +18603,16 @@ msgid "Code" msgstr "Code" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Package" -msgstr "Empaquetage" +msgstr "Paquetage" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp msgid "Unique Name" msgstr "Nom unique" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Signed" -msgstr "Signaux" +msgstr "Signé" #: platform/android/export/export_plugin.cpp msgid "Classify As Game" @@ -18906,9 +18623,8 @@ msgid "Retain Data On Uninstall" msgstr "Conserver les données lors de la désinstallation" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Exclude From Recents" -msgstr "Supprimer des nœuds" +msgstr "Exclure des récents" #: platform/android/export/export_plugin.cpp msgid "Graphics" @@ -18927,17 +18643,16 @@ msgid "XR Mode" msgstr "Mode XR" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Hand Tracking" -msgstr "Empaquetage" +msgstr "Suivi des mains" #: platform/android/export/export_plugin.cpp msgid "Hand Tracking Frequency" -msgstr "" +msgstr "Fréquence de suivi des mains" #: platform/android/export/export_plugin.cpp msgid "Passthrough" -msgstr "" +msgstr "Relais" #: platform/android/export/export_plugin.cpp msgid "Immersive Mode" @@ -18964,9 +18679,8 @@ msgid "Support Xlarge" msgstr "Support" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "User Data Backup" -msgstr "Interface utilisateur" +msgstr "Sauvegarde(backup) des données utilisateur" #: platform/android/export/export_plugin.cpp msgid "Allow" @@ -19199,20 +18913,17 @@ msgstr "" #: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Code Signing" -msgstr "Signaux" +msgstr "Signature du code" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "'apksigner' could not be found. Please check that the command is available " "in the Android SDK build-tools directory. The resulting %s is unsigned." msgstr "" -"Impossible de trouver 'apksigner'.\n" -"Veuillez vérifier que la commande est disponible dans le dossier build-tools " -"du SDK Android.\n" -"Le paquet sortant %s est non signé." +"Impossible de trouver 'apksigner'. Veuillez vérifier que la commande est " +"disponible dans le dossier build-tools du SDK Android. Le %s resultant n'est " +"pas signé." #: platform/android/export/export_plugin.cpp msgid "Signing debug %s..." @@ -19227,9 +18938,8 @@ msgid "Could not find keystore, unable to export." msgstr "Impossible de trouver le keystore, impossible d'exporter." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not start apksigner executable." -msgstr "Impossible de démarrer le sous-processus !" +msgstr "Impossible de le programme apksigner." #: platform/android/export/export_plugin.cpp msgid "'apksigner' returned with error #%d" @@ -19266,9 +18976,8 @@ msgstr "" "*.apk." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Unsupported export format!" -msgstr "Format d'export non supporté !\n" +msgstr "Format d'export non supporté !" #: platform/android/export/export_plugin.cpp msgid "" @@ -19280,28 +18989,24 @@ msgstr "" "menu 'Projet'." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Android build version mismatch: Template installed: %s, Godot version: %s. " "Please reinstall Android build template from 'Project' menu." msgstr "" -"La version d'Android ne correspond pas :\n" -" Modèle installé : %s\n" -" Version Godot : %s\n" -"Veuillez réinstaller la version d'Android depuis le menu 'Projet'." +"La version compilée d'Android ne correspond pas : Modèle type installé : %s, " +"Version de Godot : %s. Veuillez réinstaller le modèle type de compilation " +"d'Android depuis le menu 'Projet'." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Unable to overwrite res://android/build/res/*.xml files with project name." msgstr "" "Impossible d'écraser les fichiers res://android/build/res/*.xml avec le nom " -"du projet" +"du projet." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files to gradle project." -msgstr "Impossible d'exporter les fichiers du projet vers le projet gradle\n" +msgstr "Impossible d'exporter les fichiers du projet vers le projet gradle." #: platform/android/export/export_plugin.cpp msgid "Could not write expansion package file!" @@ -19312,15 +19017,13 @@ msgid "Building Android Project (gradle)" msgstr "Construire le Project Android (gradle)" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Building of Android project failed, check output for the error. " "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" "La construction du projet Android a échoué, vérifiez la sortie pour " -"l'erreur.\n" -"Sinon, visitez docs.godotengine.org pour la documentation de construction " -"Android." +"l'erreur. Sinon, visitez docs.godotengine.org pour la documentation de " +"construction Android." #: platform/android/export/export_plugin.cpp msgid "Moving output" @@ -19335,41 +19038,38 @@ msgstr "" "du projet gradle pour les journaux." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Package not found: \"%s\"." -msgstr "Paquet non trouvé : %s" +msgstr "Paquet non trouvé : \"%s\"." #: platform/android/export/export_plugin.cpp msgid "Creating APK..." msgstr "Création de l'APK..." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not find template APK to export: \"%s\"." msgstr "" -"Impossible de trouver le modèle de l'APK à exporter :\n" -"%s" +"La construction du projet Android a échoué, vérifiez la sortie pour " +"l'erreur. Sinon, visitez docs.godotengine.org pour la documentation de " +"construction Android." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Missing libraries in the export template for the selected architectures: %s. " "Please build a template with all required libraries, or uncheck the missing " "architectures in the export preset." msgstr "" "Bibliothèques manquantes dans le modèle d'exportation pour les architectures " -"sélectionnées : %s.\n" -"Veuillez construire un modèle avec toutes les bibliothèques requises, ou " -"désélectionner les architectures manquantes dans le préréglage d'exportation." +"sélectionnées : %s. Veuillez construire un modèle avec toutes les " +"bibliothèques requises, ou désélectionner les architectures manquantes dans " +"le préréglage d'exportation." #: platform/android/export/export_plugin.cpp msgid "Adding files..." msgstr "Ajout de fichiers..." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files." -msgstr "Impossible d'exporter les fichiers du projet" +msgstr "Impossible d'exporter les fichiers du projet." #: platform/android/export/export_plugin.cpp msgid "Aligning APK..." @@ -19409,7 +19109,7 @@ msgstr "iPad 2048 X 1536" #: platform/iphone/export/export.cpp msgid "Portrait Launch Screens" -msgstr "" +msgstr "Écrans de lancement en mode portrait" #: platform/iphone/export/export.cpp msgid "iPhone 640 X 960" @@ -19441,38 +19141,35 @@ msgstr "iPhone 1242 X 2208" #: platform/iphone/export/export.cpp msgid "App Store Team ID" -msgstr "" +msgstr "ID de groupe de l'App Store" #: platform/iphone/export/export.cpp msgid "Provisioning Profile UUID Debug" -msgstr "" +msgstr "UUID de provisionnement de profils en débogage" #: platform/iphone/export/export.cpp msgid "Code Sign Identity Debug" -msgstr "" +msgstr "Identité de signature de code en débogage" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Method Debug" -msgstr "Exporter avec debug" +msgstr "Méthode d'exportation en débogage" #: platform/iphone/export/export.cpp msgid "Provisioning Profile UUID Release" -msgstr "" +msgstr "UUID de provisionnement de profils en publication" #: platform/iphone/export/export.cpp msgid "Code Sign Identity Release" -msgstr "" +msgstr "Identité de signature de code en publication" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Method Release" -msgstr "Mode d'exportation :" +msgstr "Méthode d'exportation en publication" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Targeted Device Family" -msgstr "Famille de système cible" +msgstr "Famille de système ciblée" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp msgid "Info" @@ -19504,9 +19201,8 @@ msgid "Access Wi-Fi" msgstr "Accès Wi-Fi" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Push Notifications" -msgstr "Rotation aléatoire :" +msgstr "Notifications Push" #: platform/iphone/export/export.cpp msgid "User Data" @@ -19514,33 +19210,29 @@ msgstr "Données Utilisateur" #: platform/iphone/export/export.cpp msgid "Accessible From Files App" -msgstr "" +msgstr "Accessible depuis l'application Files" #: platform/iphone/export/export.cpp msgid "Accessible From iTunes Sharing" -msgstr "" +msgstr "Accessible depuis le partage iTunes" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp msgid "Privacy" msgstr "Confidentialité" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Camera Usage Description" -msgstr "Description" +msgstr "Description d'utilisation de la caméra" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Microphone Usage Description" -msgstr "Description des propriétés" +msgstr "Description d'utilisation du microphone" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Photolibrary Usage Description" -msgstr "Description des propriétés" +msgstr "Description d'utilisation de la bibliothèque d'image" #: platform/iphone/export/export.cpp -#, fuzzy msgid "iPhone 120 X 120" msgstr "iPhone 120 X 120" @@ -19558,19 +19250,19 @@ msgstr "iPad 152 X 152" #: platform/iphone/export/export.cpp msgid "iPad 167 X 167" -msgstr "" +msgstr "iPad 167 X 167" #: platform/iphone/export/export.cpp msgid "App Store 1024 X 1024" -msgstr "" +msgstr "App Store 1024 X 1024" #: platform/iphone/export/export.cpp msgid "Spotlight 40 X 40" -msgstr "" +msgstr "Projecteur 40 X 40" #: platform/iphone/export/export.cpp msgid "Spotlight 80 X 80" -msgstr "" +msgstr "Projecteur 80 X 80" #: platform/iphone/export/export.cpp msgid "Storyboard" @@ -19581,19 +19273,16 @@ msgid "Use Launch Screen Storyboard" msgstr "" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Image Scale Mode" -msgstr "Mode mise à l'échelle" +msgstr "Mode de mise à l'échelle d'image" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom Image @2x" -msgstr "Nœud Personnalisé" +msgstr "Image personnalisée @2x" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom Image @3x" -msgstr "Nœud Personnalisé" +msgstr "Image personnalisée @3x" #: platform/iphone/export/export.cpp msgid "Use Custom BG Color" @@ -19694,7 +19383,7 @@ msgstr "" #: platform/javascript/export/export.cpp msgid "Canvas Resize Policy" -msgstr "" +msgstr "Politique de redimensionnement du canevas" #: platform/javascript/export/export.cpp msgid "Focus Canvas On Start" @@ -19793,18 +19482,16 @@ msgid "Already signed!" msgstr "Déjà signé !" #: platform/osx/export/codesign.cpp -#, fuzzy msgid "Failed to process nested resources." -msgstr "Impossible de charger la ressource." +msgstr "Le traitement des ressources imbriquées a échoué." #: platform/osx/export/codesign.cpp msgid "Failed to create _CodeSignature subfolder." msgstr "Échec lors de la création du sous-dossier _CodeSignature." #: platform/osx/export/codesign.cpp -#, fuzzy msgid "Failed to get CodeResources hash." -msgstr "Impossible de charger la ressource." +msgstr "La récupération du hachage de CodeResources a échouée." #: platform/osx/export/codesign.cpp platform/osx/export/export.cpp #, fuzzy @@ -19816,7 +19503,6 @@ msgid "Invalid executable file." msgstr "Fichier exécutable invalide." #: platform/osx/export/codesign.cpp -#, fuzzy msgid "Can't resize signature load command." msgstr "Impossible de redimensionner la commande de chargement des signatures." @@ -19837,75 +19523,65 @@ msgid "App Category" msgstr "Catégorie de l'application" #: platform/osx/export/export.cpp -#, fuzzy msgid "High Res" msgstr "Haute Résolution" #: platform/osx/export/export.cpp -#, fuzzy msgid "Location Usage Description" -msgstr "Description" +msgstr "Description d'utilisation de la géolocalisation" #: platform/osx/export/export.cpp msgid "Address Book Usage Description" -msgstr "" +msgstr "Description d'utilisation du carnet d'adresse" #: platform/osx/export/export.cpp -#, fuzzy msgid "Calendar Usage Description" -msgstr "Description" +msgstr "Description d'utilisation du calendrier" #: platform/osx/export/export.cpp -#, fuzzy msgid "Photos Library Usage Description" -msgstr "Description des propriétés" +msgstr "Description d'utilisation de la bibliothèque photo" #: platform/osx/export/export.cpp -#, fuzzy msgid "Desktop Folder Usage Description" -msgstr "Descriptions des méthodes" +msgstr "Description d'utilisation du dossier Bureau" #: platform/osx/export/export.cpp -#, fuzzy msgid "Documents Folder Usage Description" -msgstr "Descriptions des méthodes" +msgstr "Description d'utilisation du dossier Documents" #: platform/osx/export/export.cpp msgid "Downloads Folder Usage Description" -msgstr "" +msgstr "Description d'utilisation du dossier Téléchargements" #: platform/osx/export/export.cpp msgid "Network Volumes Usage Description" -msgstr "" +msgstr "Description d'utilisation des disques réseau" #: platform/osx/export/export.cpp msgid "Removable Volumes Usage Description" -msgstr "" +msgstr "Description d'utilisation des disques amovibles" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Codesign" -msgstr "Nœud" +msgstr "Signature du code" #: platform/osx/export/export.cpp platform/uwp/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Identity" -msgstr "Indenter vers la gauche" +msgstr "Identité" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Timestamp" -msgstr "Temps" +msgstr "Horodatage" #: platform/osx/export/export.cpp msgid "Hardened Runtime" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Replace Existing Signature" -msgstr "Remplacer dans les fichiers" +msgstr "Remplacer la signature existante" #: platform/osx/export/export.cpp #, fuzzy @@ -19913,9 +19589,8 @@ msgid "Entitlements" msgstr "Gadgets" #: platform/osx/export/export.cpp -#, fuzzy msgid "Custom File" -msgstr "Nœud Personnalisé" +msgstr "Fichier personnalisé" #: platform/osx/export/export.cpp msgid "Allow JIT Code Execution" @@ -19950,43 +19625,37 @@ msgid "Photos Library" msgstr "Bibliothèque de photos" #: platform/osx/export/export.cpp -#, fuzzy msgid "Apple Events" -msgstr "Ajouter évènement" +msgstr "Événements Apple" #: platform/osx/export/export.cpp -#, fuzzy msgid "Debugging" msgstr "Débogage" #: platform/osx/export/export.cpp -#, fuzzy msgid "App Sandbox" msgstr "Bac à sable de l'application" #: platform/osx/export/export.cpp -#, fuzzy msgid "Network Server" -msgstr "Profileur réseau" +msgstr "Serveur réseau" #: platform/osx/export/export.cpp -#, fuzzy msgid "Network Client" -msgstr "Profileur réseau" +msgstr "Client réseau" #: platform/osx/export/export.cpp -#, fuzzy msgid "Device USB" -msgstr "Périphérique" +msgstr "Périphérique USB" #: platform/osx/export/export.cpp msgid "Device Bluetooth" -msgstr "" +msgstr "Périphérique Bluetooth" #: platform/osx/export/export.cpp #, fuzzy msgid "Files Downloads" -msgstr "Télécharger" +msgstr "Téléchargement de fichiers" #: platform/osx/export/export.cpp #, fuzzy @@ -20004,9 +19673,8 @@ msgid "Files Movies" msgstr "Filtrer les tuiles" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Custom Options" -msgstr "Options de bus" +msgstr "Options personnalisées" #: platform/osx/export/export.cpp #, fuzzy @@ -20015,31 +19683,27 @@ msgstr "Localisation" #: platform/osx/export/export.cpp msgid "Apple ID Name" -msgstr "" +msgstr "Nom Apple ID" #: platform/osx/export/export.cpp -#, fuzzy msgid "Apple ID Password" -msgstr "Mot de passe" +msgstr "Mot de passe Apple ID" #: platform/osx/export/export.cpp msgid "Apple Team ID" msgstr "Apple Team ID" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not open icon file \"%s\"." -msgstr "Impossible d'exporter les fichiers du projet" +msgstr "Impossible d'ouvrir le fichier d'icône \"%s\"." #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not start xcrun executable." -msgstr "Impossible de démarrer le sous-processus !" +msgstr "Impossible de démarrer le sous-processus." #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization failed." -msgstr "Localisation" +msgstr "Notarisation échouée." #: platform/osx/export/export.cpp msgid "Notarization request UUID: \"%s\"" @@ -20072,6 +19736,8 @@ msgstr "" #: platform/osx/export/export.cpp msgid "Timestamping is not compatible with ad-hoc signature, and was disabled!" msgstr "" +"L'horodatage n'est pas compatible avec la signature ad-hoc et a été " +"désactivé !" #: platform/osx/export/export.cpp msgid "" @@ -20084,7 +19750,7 @@ msgstr "" #: platform/osx/export/export.cpp msgid "Built-in CodeSign require regex module." -msgstr "" +msgstr "CodeSign intégré nécessite le module regex." #: platform/osx/export/export.cpp msgid "" @@ -20099,9 +19765,8 @@ msgid "No identity found." msgstr "Aucune identité trouvée." #: platform/osx/export/export.cpp -#, fuzzy msgid "Cannot sign file %s." -msgstr "Erreur lors de l'enregistrement du fichier : %s" +msgstr "Impossible de signer le fichier %s." #: platform/osx/export/export.cpp msgid "Relative symlinks are not supported, exported \"%s\" might be broken!" @@ -20110,17 +19775,14 @@ msgstr "" "cassé !" #: platform/osx/export/export.cpp -#, fuzzy msgid "DMG Creation" -msgstr "Directions" +msgstr "Création du DMG" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not start hdiutil executable." -msgstr "Impossible de démarrer le sous-processus !" +msgstr "Impossible de démarrer le programme hdiutil." #: platform/osx/export/export.cpp -#, fuzzy msgid "`hdiutil create` failed - file exists." msgstr "`hdiutil create` a échoué - le fichier existe." @@ -20129,19 +19791,16 @@ msgid "`hdiutil create` failed." msgstr "`hdiutil create` a échoué." #: platform/osx/export/export.cpp -#, fuzzy msgid "Creating app bundle" -msgstr "Création de l'aperçu" +msgstr "Création du paquet d'application" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not find template app to export: \"%s\"." -msgstr "Impossible de trouver le modèle de l'application à exporter :" +msgstr "Impossible de trouver le modèle de l'application à exporter : \"%s\"." #: platform/osx/export/export.cpp -#, fuzzy msgid "Invalid export format." -msgstr "Modèle d'exportation non valide :" +msgstr "Format d'export invalide." #: platform/osx/export/export.cpp msgid "" @@ -20168,10 +19827,13 @@ msgid "" "Ad-hoc signed applications require the 'Disable Library Validation' " "entitlement to load dynamic libraries." msgstr "" +"La signature d'applications ad-hoc nécessite la permission \"Désactiver la " +"validation de bibliothèque\" pour pouvoir charger dynamiquement les " +"bibliothèques." #: platform/osx/export/export.cpp msgid "Code signing bundle" -msgstr "" +msgstr "Paquet de signature du code" #: platform/osx/export/export.cpp msgid "Making DMG" @@ -20179,7 +19841,7 @@ msgstr "Création du DMG" #: platform/osx/export/export.cpp msgid "Code signing DMG" -msgstr "" +msgstr "DMG de signature du code" #: platform/osx/export/export.cpp msgid "Making ZIP" @@ -20198,14 +19860,12 @@ msgid "Sending archive for notarization" msgstr "Envoi de l'archive pour la certification" #: platform/osx/export/export.cpp -#, fuzzy msgid "ZIP Creation" -msgstr "Projet" +msgstr "Création ZIP" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not open file to read from path \"%s\"." -msgstr "Impossible d'exporter les fichiers du projet vers le projet gradle\n" +msgstr "Impossible d'ouvrir le fichier à lire au chemin \"%s\"." #: platform/osx/export/export.cpp msgid "Invalid bundle identifier:" @@ -20235,14 +19895,13 @@ msgstr "" "supporté." #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization: Code signing is required for notarization." -msgstr "Certification : signature du code requise." +msgstr "" +"Notarisation : La signature du code est nécessaire pour la notarisation." #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization: Hardened runtime is required for notarization." -msgstr "Certification : exécution renforcée requise." +msgstr "Notarisation : exécution renforcée nécessaire pour la notarisation." #: platform/osx/export/export.cpp #, fuzzy @@ -20284,6 +19943,8 @@ msgstr "" msgid "" "Timestamping is not compatible with ad-hoc signature, and will be disabled!" msgstr "" +"L'horodatage n'est pas compatible avec la signature ad-hoc et a été " +"désactivé !" #: platform/osx/export/export.cpp msgid "" @@ -20346,17 +20007,15 @@ msgstr "macOS" #: platform/osx/export/export.cpp msgid "Force Builtin Codesign" -msgstr "" +msgstr "Forcer CodeSign intégré" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Architecture" -msgstr "Ajouter une entrée architecture" +msgstr "Architecture" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Display Name" -msgstr "Tout afficher" +msgstr "Afficher le nom" #: platform/uwp/export/export.cpp msgid "Short Name" @@ -20364,36 +20023,31 @@ msgstr "Nom Abrégé" #: platform/uwp/export/export.cpp msgid "Publisher" -msgstr "" +msgstr "Publicateur" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Publisher Display Name" -msgstr "Nom d'affichage d'éditeur du paquet invalide." +msgstr "Nom d'affichage de l'éditeur du paquet" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Product GUID" -msgstr "GUID produit invalide." +msgstr "GUID du produit" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Publisher GUID" -msgstr "Effacé Guides" +msgstr "GUID du publicateur" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Signing" -msgstr "Signaux" +msgstr "Signature" #: platform/uwp/export/export.cpp msgid "Certificate" msgstr "Certificat" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Algorithm" -msgstr "Débogueur" +msgstr "Algorithme" #: platform/uwp/export/export.cpp msgid "Major" @@ -20404,23 +20058,20 @@ msgid "Minor" msgstr "Mineur" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Build" -msgstr "Mode Règle" +msgstr "Build" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Revision" -msgstr "Expression" +msgstr "Révision" #: platform/uwp/export/export.cpp msgid "Landscape" msgstr "Paysage" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Portrait" -msgstr "Retourner les Portals" +msgstr "Portrait" #: platform/uwp/export/export.cpp msgid "Landscape Flipped" @@ -20431,9 +20082,8 @@ msgid "Portrait Flipped" msgstr "Portrait Inversé" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Store Logo" -msgstr "Mode mise à l'échelle" +msgstr "Logo du magasin" #: platform/uwp/export/export.cpp msgid "Square 44 X 44 Logo" @@ -20456,14 +20106,12 @@ msgid "Wide 310 X 150 Logo" msgstr "Logo 310 X 150 Large" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Splash Screen" -msgstr "Appels de dessin :" +msgstr "Écran de chargement" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Tiles" -msgstr "Fichier" +msgstr "Tuiles" #: platform/uwp/export/export.cpp msgid "Show Name On Square 150 X 150" @@ -20547,32 +20195,28 @@ msgid "UWP" msgstr "UWP" #: platform/uwp/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Signtool" -msgstr "Signaux" +msgstr "Signtool" #: platform/uwp/export/export.cpp msgid "Debug Certificate" msgstr "Certificat de Débogage" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Debug Algorithm" -msgstr "Débogueur" +msgstr "Algorithme de débogage" #: platform/windows/export/export.cpp -#, fuzzy msgid "Failed to rename temporary file \"%s\"." -msgstr "Impossible de supprimer le fichier temporaire :" +msgstr "Impossible de renommer le fichier temporaire \"%s\"." #: platform/windows/export/export.cpp -#, fuzzy msgid "Identity Type" msgstr "Type d'identité" #: platform/windows/export/export.cpp msgid "Timestamp Server URL" -msgstr "" +msgstr "URL du serveur d'horodatage" #: platform/windows/export/export.cpp #, fuzzy @@ -20580,14 +20224,12 @@ msgid "Digest Algorithm" msgstr "Débogueur" #: platform/windows/export/export.cpp -#, fuzzy msgid "Modify Resources" -msgstr "Copier la ressource" +msgstr "Modifier les ressources" #: platform/windows/export/export.cpp -#, fuzzy msgid "File Version" -msgstr "Version" +msgstr "Version de fichier" #: platform/windows/export/export.cpp msgid "Product Version" @@ -20602,18 +20244,16 @@ msgid "Product Name" msgstr "Nom du produit" #: platform/windows/export/export.cpp -#, fuzzy msgid "File Description" -msgstr "Description" +msgstr "Description de fichier" #: platform/windows/export/export.cpp msgid "Trademarks" msgstr "Marques Déposées" #: platform/windows/export/export.cpp -#, fuzzy msgid "Resources Modification" -msgstr "Rotation aléatoire :" +msgstr "Modification de ressources" #: platform/windows/export/export.cpp #, fuzzy @@ -20628,61 +20268,52 @@ msgstr "Impossible de trouver le keystore, impossible d'exporter." #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" "L'outil « rcedit » doit être configuré dans les préférences de l'éditeur " "(Exporter > Windows > Rcedit) for modifier l'icône ou les informations de " "l'application." #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" -"rcedit n'a pas réussi à modifier l'exécutable :\n" -"%s" +msgid "rcedit failed to modify executable: %s." +msgstr "rcedit n'a pas réussi à modifier l'exécutable : %s." #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find signtool executable at \"%s\"." -msgstr "Impossible de trouver le keystore, impossible d'exporter." +msgstr "Impossible de trouver l’exécutable signtool à \"%s\"." #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find osslsigncode executable at \"%s\"." -msgstr "Impossible de trouver le keystore, impossible d'exporter." +msgstr "Impossible de trouver l’exécutable osslsigncode à \"%s\"." #: platform/windows/export/export.cpp -#, fuzzy msgid "Invalid identity type." -msgstr "Identifiant invalide :" +msgstr "Type d'identité invalide." #: platform/windows/export/export.cpp -#, fuzzy msgid "Invalid timestamp server." -msgstr "Nom invalide." +msgstr "Server d'horodatage invalide." #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" "L'outil « rcedit » doit être configuré dans les préférences de l'éditeur " "(Exporter > Windows > Rcedit) for modifier l'icône ou les informations de " "l'application." #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +msgid "Signtool failed to sign executable: %s." +msgstr "La signature de l’exécutable avec Signtool a échoué : %s." #: platform/windows/export/export.cpp -#, fuzzy msgid "Failed to remove temporary file \"%s\"." -msgstr "Impossible de supprimer le fichier temporaire :" +msgstr "Impossible de supprimer le fichier temporaire \"%s\"." #: platform/windows/export/export.cpp msgid "" @@ -20707,7 +20338,7 @@ msgstr "Version du produit invalide :" #: platform/windows/export/export.cpp msgid "Windows executables cannot be >= 4 GiB." -msgstr "" +msgstr "Les exécutables Windows ne peuvent pas peser >= 4Gio." #: platform/windows/export/export.cpp platform/x11/export/export.cpp #, fuzzy @@ -20716,38 +20347,37 @@ msgstr "Fichier exécutable invalide." #: platform/windows/export/export.cpp platform/x11/export/export.cpp msgid "Executable file header corrupted." -msgstr "" +msgstr "Entête du fichier exécutable corrompue." #: platform/windows/export/export.cpp platform/x11/export/export.cpp msgid "Executable \"pck\" section not found." -msgstr "" +msgstr "Section \"pck\" de l’exécutable non trouvée." #: platform/windows/export/export.cpp -#, fuzzy msgid "Windows" -msgstr "Nouvelle Fenêtre" +msgstr "Windows" #: platform/windows/export/export.cpp msgid "Rcedit" -msgstr "" +msgstr "Rcedit" #: platform/windows/export/export.cpp msgid "Osslsigncode" -msgstr "" +msgstr "Osslsigncode" #: platform/windows/export/export.cpp msgid "Wine" -msgstr "" +msgstr "Wine" #: platform/x11/export/export.cpp msgid "32-bit executables cannot have embedded data >= 4 GiB." msgstr "" +"les exécutables 32 bits ne peuvent pas contenir de données pesant >= 4Gio." #: scene/2d/animated_sprite.cpp scene/3d/sprite_3d.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Frames" -msgstr "Image %" +msgstr "Trames" #: scene/2d/animated_sprite.cpp msgid "" @@ -20759,71 +20389,61 @@ msgstr "" #: scene/2d/animated_sprite.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/particles_2d.cpp scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Speed Scale" -msgstr "Mode mise à l'échelle" +msgstr "Échelle de vitesse" #: scene/2d/animated_sprite.cpp scene/2d/audio_stream_player_2d.cpp #: scene/3d/audio_stream_player_3d.cpp scene/3d/sprite_3d.cpp #: scene/audio/audio_stream_player.cpp -#, fuzzy msgid "Playing" -msgstr "Jouer" +msgstr "En train de jouer" #: scene/2d/animated_sprite.cpp scene/2d/sprite.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Centered" -msgstr "Centre" +msgstr "Centré" #: scene/2d/animated_sprite.cpp scene/2d/sprite.cpp scene/3d/sprite_3d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_rect.cpp msgid "Flip H" -msgstr "" +msgstr "Miroir H" #: scene/2d/animated_sprite.cpp scene/2d/sprite.cpp scene/3d/sprite_3d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_rect.cpp msgid "Flip V" -msgstr "" +msgstr "Miroir V" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Monitoring" -msgstr "Moniteur" +msgstr "Observation" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Monitorable" -msgstr "Moniteur" +msgstr "Observable" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Physics Overrides" -msgstr "Redéfinition" +msgstr "Redéfinitions de physique" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Space Override" -msgstr "Redéfinition" +msgstr "Redéfinition d'espace" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Point" -msgstr "Générer des points" +msgstr "Gravité ponctuelle" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Distance Scale" -msgstr "WaitInstanceSignal" +msgstr "Échelle de distance de gravité" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Vec" -msgstr "Aperçu par défaut" +msgstr "Vecteur de gravité" #: scene/2d/area_2d.cpp scene/2d/cpu_particles_2d.cpp scene/3d/area.cpp #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp msgid "Gravity" -msgstr "" +msgstr "Gravité" #: scene/2d/area_2d.cpp scene/3d/area.cpp #, fuzzy @@ -20835,38 +20455,33 @@ msgid "Angular Damp" msgstr "" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Audio Bus" -msgstr "Ajouter un bus audio" +msgstr "Bus audio" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Override" msgstr "Redéfinition" #: scene/2d/audio_stream_player_2d.cpp scene/audio/audio_stream_player.cpp #: scene/gui/video_player.cpp servers/audio/effects/audio_effect_amplify.cpp -#, fuzzy msgid "Volume dB" -msgstr "Volume" +msgstr "Volume (dB)" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp #: servers/audio/effects/audio_effect_pitch_shift.cpp -#, fuzzy msgid "Pitch Scale" -msgstr "Mode mise à l'échelle" +msgstr "Échelle de pitch" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp -#, fuzzy msgid "Autoplay" -msgstr "Activer/désactiver la lecture automatique" +msgstr "Lecture automatique" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp msgid "Stream Paused" -msgstr "" +msgstr "Diffusion en pause" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/3d/light.cpp scene/3d/reflection_probe.cpp @@ -20876,34 +20491,29 @@ msgid "Max Distance" msgstr "Distance Maximale" #: scene/2d/audio_stream_player_2d.cpp scene/3d/light.cpp -#, fuzzy msgid "Attenuation" -msgstr "Animation" +msgstr "Atténuation" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp -#, fuzzy msgid "Bus" -msgstr "Ajouter un bus" +msgstr "Bus" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp msgid "Area Mask" -msgstr "" +msgstr "Masque de zone" #: scene/2d/back_buffer_copy.cpp -#, fuzzy msgid "Copy Mode" -msgstr "Copier les nœuds" +msgstr "Mode copie" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Anchor Mode" -msgstr "Mode Icône" +msgstr "Mode ancre" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Rotating" -msgstr "Pas de la rotation :" +msgstr "En rotation" #: scene/2d/camera_2d.cpp scene/2d/listener_2d.cpp scene/3d/camera.cpp #: scene/3d/listener.cpp scene/animation/animation_blend_tree.cpp @@ -20911,14 +20521,12 @@ msgid "Current" msgstr "Actuel" #: scene/2d/camera_2d.cpp scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom" msgstr "Zoomer" #: scene/2d/camera_2d.cpp scene/main/canvas_layer.cpp -#, fuzzy msgid "Custom Viewport" -msgstr "1 vue" +msgstr "Vue personnalisée" #: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp @@ -20929,26 +20537,23 @@ msgstr "Mode déplacement" #: scene/2d/camera_2d.cpp msgid "Limit" -msgstr "" +msgstr "Limite" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp -#, fuzzy msgid "Left" -msgstr "En haut à gauche" +msgstr "Gauche" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp -#, fuzzy msgid "Right" -msgstr "Lumière" +msgstr "Droite" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/dynamic_font.cpp scene/resources/style_box.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Bottom" -msgstr "En bas à gauche" +msgstr "Bas" #: scene/2d/camera_2d.cpp #, fuzzy @@ -20956,9 +20561,8 @@ msgid "Smoothed" msgstr "Progression douce" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Draw Margin" -msgstr "Définir la marge" +msgstr "Afficher les marges" #: scene/2d/camera_2d.cpp #, fuzzy @@ -20977,27 +20581,24 @@ msgstr "Progression douce" #: scene/2d/camera_2d.cpp msgid "H" -msgstr "" +msgstr "H" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "V" -msgstr "UV" +msgstr "V" #: scene/2d/camera_2d.cpp #, fuzzy msgid "Drag Margin" -msgstr "Définir la marge" +msgstr "Tirer la marge" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Draw Screen" -msgstr "Appels de dessin :" +msgstr "Afficher l'écran" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Draw Limits" -msgstr "Appels de dessin :" +msgstr "Afficher les limites" #: scene/2d/camera_2d.cpp #, fuzzy @@ -21006,43 +20607,37 @@ msgstr "Définir la marge" #: scene/2d/canvas_item.cpp scene/resources/environment.cpp #: scene/resources/material.cpp -#, fuzzy msgid "Blend Mode" -msgstr "Nœud Blend2" +msgstr "Mode mélange" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Light Mode" -msgstr "Étendu à Droite" +msgstr "Mode de lumière" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Particles Animation" -msgstr "Particules" +msgstr "Animation de particules" #: scene/2d/canvas_item.cpp msgid "Particles Anim H Frames" -msgstr "" +msgstr "Trames d'animation H de particules" #: scene/2d/canvas_item.cpp msgid "Particles Anim V Frames" -msgstr "" +msgstr "Trames d'animation V de particules" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Particles Anim Loop" -msgstr "Particules" +msgstr "Boucle d'animation de particules" #: scene/2d/canvas_item.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Visibility" -msgstr "Basculer la visibilité" +msgstr "Visibilité" #: scene/2d/canvas_item.cpp scene/3d/spatial.cpp scene/gui/progress_bar.cpp #: scene/gui/rich_text_effect.cpp scene/main/canvas_layer.cpp -#, fuzzy msgid "Visible" -msgstr "Basculer la visibilité" +msgstr "Visible" #: scene/2d/canvas_item.cpp #, fuzzy @@ -21051,22 +20646,20 @@ msgstr "Peupler" #: scene/2d/canvas_item.cpp msgid "Show Behind Parent" -msgstr "" +msgstr "Montrer derrière le parent" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Show On Top" -msgstr "Afficher l'origine" +msgstr "Montrer au dessus" #: scene/2d/canvas_item.cpp scene/2d/light_occluder_2d.cpp #: scene/2d/tile_map.cpp -#, fuzzy msgid "Light Mask" -msgstr "LightMap Bake" +msgstr "Masque de lumières" #: scene/2d/canvas_item.cpp msgid "Use Parent Material" -msgstr "" +msgstr "Utiliser le matériau du parent" #: scene/2d/canvas_modulate.cpp msgid "" @@ -21088,9 +20681,8 @@ msgstr "" "qu'enfant pour définir sa forme." #: scene/2d/collision_object_2d.cpp -#, fuzzy msgid "Pickable" -msgstr "Sélectionner une tuile" +msgstr "Déplaçable" #: scene/2d/collision_polygon_2d.cpp msgid "" @@ -21122,29 +20714,27 @@ msgstr "" msgid "" "The One Way Collision property will be ignored when the parent is an Area2D." msgstr "" +"La propriété Collision à sens unique est ignorée lorsque le parent est un " +"Area2D." #: scene/2d/collision_polygon_2d.cpp -#, fuzzy msgid "Build Mode" -msgstr "Mode Règle" +msgstr "Mode construction" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp #: scene/3d/collision_polygon.cpp scene/3d/collision_shape.cpp #: scene/animation/animation_node_state_machine.cpp scene/gui/base_button.cpp #: scene/gui/texture_button.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Disabled" -msgstr "Item désactivé" +msgstr "Désactivé" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp -#, fuzzy msgid "One Way Collision" -msgstr "Créer le polygone de collision" +msgstr "Collision à sens unique" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp -#, fuzzy msgid "One Way Collision Margin" -msgstr "Créer le polygone de collision" +msgstr "marge de collision à sens unique" #: scene/2d/collision_shape_2d.cpp msgid "" @@ -21183,31 +20773,28 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Emitting" -msgstr "Paramètres :" +msgstr "Émet" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp msgid "Lifetime" -msgstr "" +msgstr "Durée de vie" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp scene/main/timer.cpp -#, fuzzy msgid "One Shot" -msgstr "Nœud one-shot" +msgstr "Jouer une fois" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Preprocess" -msgstr "Post-traitement" +msgstr "Pré-traitement" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp msgid "Explosiveness" -msgstr "" +msgstr "Explovisité" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -21217,13 +20804,12 @@ msgstr "Aléatoire" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp msgid "Lifetime Randomness" -msgstr "" +msgstr "Aléatoire de durée de vie" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Fixed FPS" -msgstr "Voir Images par secondes" +msgstr "FPS fixes" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -21237,20 +20823,18 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Local Coords" -msgstr "Projets locaux" +msgstr "Coordonnées locales" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp msgid "Draw Order" -msgstr "" +msgstr "Ordre de rendu" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Emission Shape" -msgstr "Masque d'émission" +msgstr "Forme d'émission" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21263,63 +20847,55 @@ msgid "Rect Extents" msgstr "Gadgets" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp -#, fuzzy msgid "Normals" -msgstr "Format" +msgstr "Normales" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Align Y" -msgstr "Assigner" +msgstr "Aligner axe Y" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Direction" -msgstr "Directions" +msgstr "Direction" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp #: servers/audio/effects/audio_effect_reverb.cpp msgid "Spread" -msgstr "" +msgstr "Propagation" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Initial Velocity" -msgstr "Initialiser" +msgstr "Vélocité initiale" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Velocity Random" -msgstr "Vue de l'orbite vers la droite" +msgstr "Vélocité aléatoire" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp msgid "Angular Velocity" -msgstr "" +msgstr "Vélocité angulaire" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Velocity Curve" -msgstr "Vue de l'orbite vers la droite" +msgstr "Courbe de vélocité" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Orbit Velocity" -msgstr "Vue de l'orbite vers la droite" +msgstr "Vélocité d'orbite" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Linear Accel" -msgstr "Linéaire" +msgstr "Accélération linéaire" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21329,23 +20905,22 @@ msgstr "Accel" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp msgid "Accel Random" -msgstr "" +msgstr "Accélération aléatoire" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Accel Curve" -msgstr "Scinder la courbe" +msgstr "Courbe d’accélération" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp msgid "Radial Accel" -msgstr "" +msgstr "Accélération radiale" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp msgid "Tangential Accel" -msgstr "" +msgstr "Accélération tangentielle" #: scene/2d/cpu_particles_2d.cpp scene/2d/joints_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/physics_body.cpp @@ -21353,39 +20928,37 @@ msgstr "" #: scene/resources/particles_material.cpp #: servers/audio/effects/audio_effect_reverb.cpp msgid "Damping" -msgstr "" +msgstr "Amortissement" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp msgid "Damping Random" -msgstr "" +msgstr "Amortissement aléatoire" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Damping Curve" -msgstr "Scinder la courbe" +msgstr "Courbe d'amortissement" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp scene/3d/light.cpp #: scene/resources/particles_material.cpp msgid "Angle" -msgstr "" +msgstr "Angle" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp msgid "Angle Random" -msgstr "" +msgstr "Angle aléatoire" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Angle Curve" -msgstr "Fermer la courbe" +msgstr "Courbe d'angle" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #, fuzzy msgid "Scale Amount" -msgstr "Quantité :" +msgstr "Valeur d'échelle" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp msgid "Scale Amount Random" @@ -21398,14 +20971,13 @@ msgstr "Agrandir/Rétrécir à partir du curseur" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Color Ramp" -msgstr "Couleurs" +msgstr "Dégradé de couleurs" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp msgid "Color Initial Ramp" -msgstr "" +msgstr "Dégradé de couleurs initial" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21424,33 +20996,28 @@ msgstr "Variation aléatoire" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Variation Curve" -msgstr "Séparation :" +msgstr "Courbe de variation" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Speed Random" -msgstr "Mode mise à l'échelle" +msgstr "Vitesse aléatoire" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Speed Curve" -msgstr "Scinder la courbe" +msgstr "Courbe de vitesse" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Offset Random" -msgstr "Décalage :" +msgstr "Décalage de l'aléatoire" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Offset Curve" -msgstr "Fermer la courbe" +msgstr "Courbe de décalage" #: scene/2d/joints_2d.cpp msgid "Node A and Node B must be PhysicsBody2Ds" @@ -21473,25 +21040,22 @@ msgid "Node A and Node B must be different PhysicsBody2Ds" msgstr "Node A et Node B doivent être des PhysicsBody2D différents" #: scene/2d/joints_2d.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Node A" -msgstr "Nœud" +msgstr "Nœud A" #: scene/2d/joints_2d.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Node B" -msgstr "Nœud" +msgstr "Nœud B" #: scene/2d/joints_2d.cpp scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/light.cpp scene/3d/physics_body.cpp scene/3d/physics_joint.cpp #: scene/resources/environment.cpp msgid "Bias" -msgstr "" +msgstr "Biais" #: scene/2d/joints_2d.cpp -#, fuzzy msgid "Disable Collision" -msgstr "Bouton désactivé" +msgstr "Désactiver les collisions" #: scene/2d/joints_2d.cpp scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Softness" @@ -21503,9 +21067,8 @@ msgid "Length" msgstr "Longueur" #: scene/2d/joints_2d.cpp -#, fuzzy msgid "Initial Offset" -msgstr "Initialiser" +msgstr "Décalage initial" #: scene/2d/joints_2d.cpp scene/3d/vehicle_body.cpp msgid "Rest Length" @@ -21524,14 +21087,12 @@ msgstr "" "« Texture »." #: scene/2d/light_2d.cpp scene/3d/light.cpp scene/gui/reference_rect.cpp -#, fuzzy msgid "Editor Only" -msgstr "Éditeur" +msgstr "Éditeur seulement" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Texture Scale" -msgstr "RegionDeTexture" +msgstr "Échelle de texture" #: scene/2d/light_2d.cpp scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/light.cpp scene/resources/environment.cpp @@ -21548,33 +21109,28 @@ msgid "Z Max" msgstr "Maximum Z" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Layer Min" -msgstr "Changer la taille d'une caméra" +msgstr "Calque min" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Layer Max" -msgstr "Calque" +msgstr "Calque max" #: scene/2d/light_2d.cpp msgid "Item Cull Mask" msgstr "" #: scene/2d/light_2d.cpp scene/3d/light.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Shadow" -msgstr "Ombrage" +msgstr "Ombre" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Buffer Size" -msgstr "Vue de derrière" +msgstr "Taille de tampon" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Gradient Length" -msgstr "Dégradé édité" +msgstr "Longueur du dégradé" #: scene/2d/light_2d.cpp #, fuzzy @@ -21582,9 +21138,8 @@ msgid "Filter Smooth" msgstr "Filtrer les méthodes" #: scene/2d/light_occluder_2d.cpp -#, fuzzy msgid "Closed" -msgstr "Fermer" +msgstr "Fermé" #: scene/2d/light_occluder_2d.cpp scene/resources/material.cpp #, fuzzy @@ -21605,38 +21160,32 @@ msgstr "" "polygone." #: scene/2d/line_2d.cpp -#, fuzzy msgid "Width Curve" -msgstr "Scinder la courbe" +msgstr "Courbe de largeur" #: scene/2d/line_2d.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Default Color" -msgstr "Défaut" +msgstr "Couleur par défaut" #: scene/2d/line_2d.cpp scene/resources/texture.cpp msgid "Fill" msgstr "Remplissage" #: scene/2d/line_2d.cpp scene/resources/texture.cpp -#, fuzzy msgid "Gradient" -msgstr "Dégradé édité" +msgstr "Dégradé" #: scene/2d/line_2d.cpp -#, fuzzy msgid "Texture Mode" -msgstr "RegionDeTexture" +msgstr "Mode de texture" #: scene/2d/line_2d.cpp -#, fuzzy msgid "Capping" -msgstr "Recouvrement" +msgstr "Capuchonnement" #: scene/2d/line_2d.cpp -#, fuzzy msgid "Joint Mode" -msgstr "Mode Icône" +msgstr "Mode de jointure" #: scene/2d/line_2d.cpp #, fuzzy @@ -21644,14 +21193,12 @@ msgid "Begin Cap Mode" msgstr "Mode Région" #: scene/2d/line_2d.cpp -#, fuzzy msgid "End Cap Mode" -msgstr "Mode d'aimantation :" +msgstr "Mode du capuchon de fin" #: scene/2d/line_2d.cpp scene/2d/polygon_2d.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Border" -msgstr "dans l'ordre :" +msgstr "Bordure" #: scene/2d/line_2d.cpp msgid "Sharp Limit" @@ -21663,9 +21210,8 @@ msgstr "Précision de l’arrondissement" #: scene/2d/line_2d.cpp scene/2d/polygon_2d.cpp #: scene/resources/dynamic_font.cpp -#, fuzzy msgid "Antialiased" -msgstr "Initialiser" +msgstr "Anticrénelé" #: scene/2d/multimesh_instance_2d.cpp scene/3d/multimesh_instance.cpp #, fuzzy @@ -21679,9 +21225,8 @@ msgid "Cell Size" msgstr "Taille des Cellules" #: scene/2d/navigation_2d.cpp scene/3d/navigation.cpp -#, fuzzy msgid "Edge Connection Margin" -msgstr "Modifier la connexion :" +msgstr "Marge de connexion des bords" #: scene/2d/navigation_2d.cpp msgid "" @@ -21696,31 +21241,27 @@ msgstr "" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp #, fuzzy msgid "Pathfinding" -msgstr "Liaison" +msgstr "Pathfinding" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Path Desired Distance" -msgstr "Choisissez distance :" +msgstr "Distance souhaitée du chemin" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Target Desired Distance" msgstr "Distance Désirée de la Cible" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Path Max Distance" -msgstr "Choisissez distance :" +msgstr "Distance maximale du chemin" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Avoidance" -msgstr "Options avancées" +msgstr "Évitement" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Avoidance Enabled" -msgstr "Activer" +msgstr "Évitement activé" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Neighbor Dist" @@ -21740,10 +21281,11 @@ msgid "Max Speed" msgstr "Vitesse Max" #: scene/2d/navigation_agent_2d.cpp -#, fuzzy msgid "" "The NavigationAgent2D can be used only under a Node2D inheriting parent node." -msgstr "Le NavigationAgent2D ne peut être utilisé que sous un nœud Node2D." +msgstr "" +"Le NavigationAgent2D ne peut être utilisé que sous un nœud dont le parent " +"hérite de Node2D." #: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_obstacle.cpp msgid "Estimate Radius" @@ -21768,17 +21310,15 @@ msgstr "" #: scene/2d/navigation_polygon.cpp msgid "Navpoly" -msgstr "" +msgstr "Polygone de navigation" #: scene/2d/navigation_polygon.cpp scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Enter Cost" -msgstr "Centrée en bas" +msgstr "Coût d’entrée" #: scene/2d/navigation_polygon.cpp scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Travel Cost" -msgstr "Se déplacer" +msgstr "Coût de déplacement" #: scene/2d/node_2d.cpp scene/2d/polygon_2d.cpp scene/3d/spatial.cpp #: scene/main/canvas_layer.cpp @@ -21844,9 +21384,8 @@ msgid "Motion" msgstr "Déplacement" #: scene/2d/parallax_layer.cpp -#, fuzzy msgid "Mirroring" -msgstr "Miroir" +msgstr "Effet de miroir" #: scene/2d/particles_2d.cpp msgid "" @@ -21909,9 +21448,8 @@ msgstr "" "d'un nœud de type Path2D." #: scene/2d/path_2d.cpp scene/3d/path.cpp -#, fuzzy msgid "Unit Offset" -msgstr "Décalage de la grille :" +msgstr "Décalage d'unité" #: scene/2d/path_2d.cpp scene/3d/camera.cpp scene/3d/path.cpp msgid "H Offset" @@ -21927,7 +21465,7 @@ msgstr "Interpolation Cubique" #: scene/2d/path_2d.cpp msgid "Lookahead" -msgstr "" +msgstr "Anticipation" #: scene/2d/physics_body_2d.cpp scene/3d/visual_instance.cpp msgid "Layers" @@ -21987,14 +21525,12 @@ msgid "Gravity Scale" msgstr "Échelle de la Gravité" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Custom Integrator" -msgstr "Nœud Personnalisé" +msgstr "Intégrateur personnalisé" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Continuous CD" -msgstr "Continu" +msgstr "Détection de collision continue" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Contacts Reported" @@ -22027,7 +21563,7 @@ msgstr "Forces Appliquées" #: scene/2d/physics_body_2d.cpp msgid "Torque" -msgstr "" +msgstr "Torque" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Safe Margin" @@ -22038,9 +21574,8 @@ msgid "Sync To Physics" msgstr "Synchroniser Avec La Physique" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Moving Platform" -msgstr "Déplacement du résultat" +msgstr "Plateforme mobile" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Apply Velocity On Leave" @@ -22054,9 +21589,8 @@ msgid "Normal" msgstr "Normale" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Remainder" -msgstr "Moteur de rendu :" +msgstr "Reste" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Local Shape" @@ -22117,9 +21651,8 @@ msgid "Exclude Parent" msgstr "Exclure Le Parent" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp -#, fuzzy msgid "Cast To" -msgstr "Créer un nœud Shader" +msgstr "Lancer vers" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp msgid "Collide With" @@ -22127,7 +21660,7 @@ msgstr "Collisionne Avec" #: scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp scene/3d/ray_cast.cpp msgid "Areas" -msgstr "" +msgstr "Zones" #: scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp scene/3d/ray_cast.cpp msgid "Bodies" @@ -22140,24 +21673,20 @@ msgstr "" "fonctionner." #: scene/2d/remote_transform_2d.cpp scene/3d/remote_transform.cpp -#, fuzzy msgid "Remote Path" -msgstr "Supprimer un point" +msgstr "Chemin distant" #: scene/2d/remote_transform_2d.cpp scene/3d/remote_transform.cpp -#, fuzzy msgid "Use Global Coordinates" -msgstr "Coordonnée suivante" +msgstr "Utiliser les coordonnées globales" #: scene/2d/skeleton_2d.cpp scene/3d/skeleton.cpp -#, fuzzy msgid "Rest" -msgstr "Redémarrer" +msgstr "Repos" #: scene/2d/skeleton_2d.cpp -#, fuzzy msgid "Default Length" -msgstr "Thème par défaut" +msgstr "Longueur par défaut" #: scene/2d/skeleton_2d.cpp msgid "This Bone2D chain should end at a Skeleton2D node." @@ -22178,16 +21707,15 @@ msgstr "" #: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp msgid "Hframes" -msgstr "" +msgstr "Trames H" #: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp msgid "Vframes" -msgstr "" +msgstr "Trames V" #: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Frame Coords" -msgstr "Image %" +msgstr "Coordonnées de trame" #: scene/2d/sprite.cpp scene/resources/texture.cpp #, fuzzy @@ -22205,14 +21733,12 @@ msgstr "" "etc." #: scene/2d/tile_map.cpp -#, fuzzy msgid "Tile Set" -msgstr "TileSet" +msgstr "Palette de tuiles" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Quadrant Size" -msgstr "Changer la taille d'une caméra" +msgstr "Taille de quadrant" #: scene/2d/tile_map.cpp #, fuzzy @@ -22220,19 +21746,16 @@ msgid "Custom Transform" msgstr "Transformation" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Half Offset" -msgstr "Initialiser" +msgstr "Décalage de moitié" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Tile Origin" -msgstr "Afficher l'origine" +msgstr "Origine de la tuile" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Y Sort" -msgstr "Trier" +msgstr "Trier par Y" #: scene/2d/tile_map.cpp msgid "Show Collision" @@ -22283,23 +21806,20 @@ msgstr "" "nœud racine de la scène éditée." #: scene/2d/visibility_notifier_2d.cpp scene/3d/visibility_notifier.cpp -#, fuzzy msgid "Pause Animations" -msgstr "Coller l'animation" +msgstr "Mettre les animations en pause" #: scene/2d/visibility_notifier_2d.cpp scene/3d/visibility_notifier.cpp msgid "Freeze Bodies" msgstr "Geler les corps" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Pause Particles" -msgstr "Particules" +msgstr "Mettre les particules en pause" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Pause Animated Sprites" -msgstr "Coller l'animation" +msgstr "Mettre les Sprites animés en pause" #: scene/2d/visibility_notifier_2d.cpp msgid "Process Parent" @@ -22327,7 +21847,7 @@ msgstr "ID Du Contrôleur" #: scene/3d/arvr_nodes.cpp servers/arvr/arvr_positional_tracker.cpp msgid "Rumble" -msgstr "" +msgstr "Vibration" #: scene/3d/arvr_nodes.cpp msgid "ARVRController must have an ARVROrigin node as its parent." @@ -22367,43 +21887,40 @@ msgid "World Scale" msgstr "Échelle du Monde" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Attenuation Model" -msgstr "Nœud d'animation" +msgstr "Modèle d’atténuation" #: scene/3d/audio_stream_player_3d.cpp msgid "Unit dB" -msgstr "" +msgstr "Unité (dB)" #: scene/3d/audio_stream_player_3d.cpp msgid "Unit Size" -msgstr "" +msgstr "Taille d’unité" #: scene/3d/audio_stream_player_3d.cpp msgid "Max dB" -msgstr "" +msgstr "Max (dB)" #: scene/3d/audio_stream_player_3d.cpp msgid "Out Of Range Mode" msgstr "" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Emission Angle" -msgstr "Couleurs d'émission" +msgstr "Angle d’émission" #: scene/3d/audio_stream_player_3d.cpp msgid "Degrees" msgstr "Degrés" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Filter Attenuation dB" -msgstr "Animation" +msgstr "Filtre d’atténuation (dB)" #: scene/3d/audio_stream_player_3d.cpp msgid "Attenuation Filter" -msgstr "" +msgstr "Filtre d’atténuation" #: scene/3d/audio_stream_player_3d.cpp #: servers/audio/effects/audio_effect_chorus.cpp @@ -22413,14 +21930,12 @@ msgstr "" #: scene/3d/audio_stream_player_3d.cpp #: servers/audio/effects/audio_effect_filter.cpp -#, fuzzy msgid "dB" -msgstr "o" +msgstr "dB" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Doppler" -msgstr "Activer l'effet Doppler" +msgstr "Doppler" #: scene/3d/audio_stream_player_3d.cpp #, fuzzy @@ -22430,7 +21945,7 @@ msgstr "Empaquetage" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/reflection_probe.cpp msgid "Interior" -msgstr "" +msgstr "Intérieur" #: scene/3d/baked_lightmap.cpp msgid "Finding meshes and lights" @@ -22465,69 +21980,59 @@ msgstr "Gadgets" #: scene/3d/baked_lightmap.cpp msgid "Tweaks" -msgstr "" +msgstr "Ajustements" #: scene/3d/baked_lightmap.cpp msgid "Bounces" -msgstr "" +msgstr "Rebonds" #: scene/3d/baked_lightmap.cpp msgid "Bounce Indirect Energy" -msgstr "" +msgstr "Énergie indirecte de rebond" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Use Denoiser" -msgstr "Filtre :" +msgstr "Utiliser un filtre anti-bruit" #: scene/3d/baked_lightmap.cpp scene/resources/texture.cpp msgid "Use HDR" -msgstr "" +msgstr "Utiliser HDR" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Use Color" -msgstr "Couleurs" +msgstr "Utiliser la couleur" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Default Texels Per Unit" -msgstr "Thème par défaut" +msgstr "Texels par unité par défaut" #: scene/3d/baked_lightmap.cpp scene/resources/texture.cpp -#, fuzzy msgid "Atlas" -msgstr "Nouvel Atlas" +msgstr "Atlas" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Generate" -msgstr "Général" +msgstr "Générer" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Max Size" -msgstr "Taille :" +msgstr "Taille maximale" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Custom Sky" -msgstr "Nœud Personnalisé" +msgstr "Ciel personnalisé" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Custom Sky Rotation Degrees" -msgstr "Rotation de %s degrés." +msgstr "Degrés de rotation du ciel personnalisé" #: scene/3d/baked_lightmap.cpp scene/3d/ray_cast.cpp -#, fuzzy msgid "Custom Color" -msgstr "Nœud Personnalisé" +msgstr "Couleur personnalisée" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Custom Energy" -msgstr "Déplacer effet de transport" +msgstr "Énergie personnalisée" #: scene/3d/baked_lightmap.cpp #, fuzzy @@ -22535,27 +22040,24 @@ msgid "Min Light" msgstr "Indenter vers la droite" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -#, fuzzy msgid "Propagation" -msgstr "Navigation" +msgstr "Propagation" #: scene/3d/baked_lightmap.cpp msgid "Image Path" -msgstr "" +msgstr "Chemin de l'image" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Light Data" -msgstr "Avec données" +msgstr "Données de lumière" #: scene/3d/bone_attachment.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Bone Name" -msgstr "Nom de nœud :" +msgstr "Nom de l'os" #: scene/3d/camera.cpp msgid "Keep Aspect" -msgstr "" +msgstr "Garder l'aspect" #: scene/3d/camera.cpp scene/3d/light.cpp scene/3d/reflection_probe.cpp msgid "Cull Mask" @@ -22567,36 +22069,32 @@ msgid "Doppler Tracking" msgstr "Piste de propriété" #: scene/3d/camera.cpp -#, fuzzy msgid "Projection" -msgstr "Projet" +msgstr "Projection" #: scene/3d/camera.cpp msgid "FOV" -msgstr "" +msgstr "Champ de vision" #: scene/3d/camera.cpp -#, fuzzy msgid "Frustum Offset" -msgstr "Décalage de la grille :" +msgstr "Décalage du Tronc" #: scene/3d/camera.cpp -#, fuzzy msgid "Near" -msgstr "Au plus proche" +msgstr "Plan proche" #: scene/3d/camera.cpp msgid "Far" -msgstr "" +msgstr "Plan éloigné" #: scene/3d/camera.cpp scene/3d/collision_polygon.cpp scene/3d/spring_arm.cpp #: scene/gui/control.cpp scene/resources/default_theme/default_theme.cpp #: scene/resources/shape.cpp scene/resources/style_box.cpp #: scene/resources/texture.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp -#, fuzzy msgid "Margin" -msgstr "Définir la marge" +msgstr "Marge" #: scene/3d/camera.cpp #, fuzzy @@ -22686,48 +22184,40 @@ msgid "Box Extents" msgstr "Gadgets" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Radius" -msgstr "Masque d'émission" +msgstr "Rayon de l'anneau" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Inner Radius" -msgstr "Changer le rayon intérieur de la tour" +msgstr "Rayon intérieur de l'anneau" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Height" -msgstr "Rotation vers la droite" +msgstr "Hauteur de l'anneau" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Axis" -msgstr "Avertissements" +msgstr "Axe de l'anneau" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Rotate Y" -msgstr "Rotation" +msgstr "Rotation Y" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Disable Z" -msgstr "Item désactivé" +msgstr "Désactiver axe Z" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp msgid "Flatness" -msgstr "" +msgstr "Platitude" #: scene/3d/cull_instance.cpp servers/visual_server.cpp -#, fuzzy msgid "Portals" -msgstr "Retourner les Portals" +msgstr "Portails" #: scene/3d/cull_instance.cpp -#, fuzzy msgid "Portal Mode" -msgstr "Mode prioritaire" +msgstr "Mode portail" #: scene/3d/cull_instance.cpp msgid "Include In Bound" @@ -22738,9 +22228,8 @@ msgid "Allow Merging" msgstr "" #: scene/3d/cull_instance.cpp -#, fuzzy msgid "Autoplace Priority" -msgstr "Activer la priorité" +msgstr "Priorité d’auto-placement" #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" @@ -22771,114 +22260,98 @@ msgstr "" #: scene/3d/gi_probe.cpp msgid "Subdiv" -msgstr "" +msgstr "Subdivision" #: scene/3d/gi_probe.cpp -#, fuzzy msgid "Dynamic Range" -msgstr "Bibliothèque dynamique" +msgstr "Plage dynamique" #: scene/3d/gi_probe.cpp scene/3d/light.cpp msgid "Normal Bias" -msgstr "" +msgstr "Biais normal" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Pixel Size" -msgstr "Aimanter au pixel" +msgstr "Taille de pixel" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Billboard" -msgstr "Billboard" +msgstr "Panneau(Billboard)" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Shaded" -msgstr "Ombrage" +msgstr "Ombré" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Double Sided" -msgstr "" +msgstr "Double face" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/material.cpp msgid "No Depth Test" -msgstr "" +msgstr "Pas de test de profondeur" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/material.cpp -#, fuzzy msgid "Fixed Size" -msgstr "Vue de devant" +msgstr "Taille fixe" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Alpha Cut" -msgstr "" +msgstr "Coupe alpha" #: scene/3d/label_3d.cpp scene/resources/material.cpp msgid "Alpha Scissor Threshold" -msgstr "" +msgstr "Seuil des ciseaux d'alpha" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/material.cpp -#, fuzzy msgid "Render Priority" -msgstr "Activer la priorité" +msgstr "Priorité de rendu" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Outline Render Priority" -msgstr "Activer la priorité" +msgstr "Priorité de rendu du contour" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Outline Modulate" -msgstr "Forcer la modulation blanche" +msgstr "Moduler le contour" #: scene/3d/label_3d.cpp scene/resources/default_theme/default_theme.cpp #: scene/resources/dynamic_font.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Font" -msgstr "Polices" +msgstr "Police" #: scene/3d/label_3d.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Horizontal Alignment" -msgstr "Horizontal Activé" +msgstr "Alignement horizontal" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Vertical Alignment" -msgstr "Filtrer les signaux" +msgstr "Alignement vertical" #: scene/3d/label_3d.cpp scene/gui/dialogs.cpp scene/gui/label.cpp -#, fuzzy msgid "Autowrap" -msgstr "AutoLoad" +msgstr "Retour à la ligne automatique" #: scene/3d/light.cpp -#, fuzzy msgid "Indirect Energy" -msgstr "Couleurs d'émission" +msgstr "Énergie indirecte" #: scene/3d/light.cpp -#, fuzzy msgid "Negative" -msgstr "GDNative" +msgstr "Négative" #: scene/3d/light.cpp scene/resources/material.cpp #: scene/resources/visual_shader.cpp -#, fuzzy msgid "Specular" -msgstr "Mode Règle" +msgstr "Spéculaire" #: scene/3d/light.cpp -#, fuzzy msgid "Bake Mode" -msgstr "Mode Bitmask" +msgstr "Mode de pré-calcul" #: scene/3d/light.cpp -#, fuzzy msgid "Contact" -msgstr "Prélever une couleur" +msgstr "Contact" #: scene/3d/light.cpp #, fuzzy @@ -22886,9 +22359,8 @@ msgid "Reverse Cull Face" msgstr "Réinitialiser le volume de bus" #: scene/3d/light.cpp servers/visual_server.cpp -#, fuzzy msgid "Directional Shadow" -msgstr "Directions" +msgstr "Ombre directionnelle" #: scene/3d/light.cpp #, fuzzy @@ -22906,9 +22378,8 @@ msgid "Split 3" msgstr "Divisé" #: scene/3d/light.cpp -#, fuzzy msgid "Blend Splits" -msgstr "Temps de mélange :" +msgstr "Mélanger les écarts" #: scene/3d/light.cpp #, fuzzy @@ -22916,23 +22387,20 @@ msgid "Bias Split Scale" msgstr "Utiliser le magnétisme d'échelle" #: scene/3d/light.cpp -#, fuzzy msgid "Depth Range" -msgstr "Profondeur" +msgstr "Plage de profondeur" #: scene/3d/light.cpp msgid "Omni" -msgstr "" +msgstr "Omnidirectionnelle" #: scene/3d/light.cpp -#, fuzzy msgid "Shadow Mode" -msgstr "Ombrage" +msgstr "Mode ombre" #: scene/3d/light.cpp -#, fuzzy msgid "Shadow Detail" -msgstr "Afficher par défaut" +msgstr "Détails d'ombre" #: scene/3d/light.cpp msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." @@ -22942,21 +22410,19 @@ msgstr "" #: scene/3d/light.cpp msgid "Spot" -msgstr "" +msgstr "Spot" #: scene/3d/light.cpp -#, fuzzy msgid "Angle Attenuation" -msgstr "Animation" +msgstr "Atténuation d'angle" #: scene/3d/mesh_instance.cpp msgid "Software Skinning" msgstr "" #: scene/3d/mesh_instance.cpp -#, fuzzy msgid "Transform Normals" -msgstr "Transformation annulée." +msgstr "Transformer les normales" #: scene/3d/navigation.cpp msgid "" @@ -22964,45 +22430,44 @@ msgid "" "be removed in a future version. Use 'NavigationServer.map_get_path()' " "instead." msgstr "" +"Le nœud \"Navigation\" et \"Navigation.get_simple_path()\" sont obsolètes et " +"seront retires dans une version ultérieure. Utilisez plutôt " +"\"NavigationServer.map_get_path()\"." #: scene/3d/navigation.cpp scene/resources/curve.cpp -#, fuzzy msgid "Up Vector" -msgstr "Vecteur" +msgstr "Vecteur Haut" #: scene/3d/navigation.cpp -#, fuzzy msgid "Cell Height" -msgstr "En période de test" +msgstr "Hauteur de cellule" #: scene/3d/navigation_agent.cpp msgid "Agent Height Offset" -msgstr "" +msgstr "Décalage de hauteur de l'agent" #: scene/3d/navigation_agent.cpp -#, fuzzy msgid "Ignore Y" -msgstr "[Ignorer]" +msgstr "Ignorer Y" #: scene/3d/navigation_agent.cpp -#, fuzzy msgid "" "The NavigationAgent can be used only under a Spatial inheriting parent node." -msgstr "Le NavigationAgent ne peut être utilisé que sous un nœud spatial." +msgstr "" +"Le NavigationAgent ne peut être utilisé que sous un nœud parent héritant de " +"Spatial." #: scene/3d/navigation_mesh_instance.cpp scene/resources/mesh_library.cpp -#, fuzzy msgid "NavMesh" -msgstr "Calculer le NavMesh" +msgstr "NavMesh" #: scene/3d/navigation_obstacle.cpp -#, fuzzy msgid "" "The NavigationObstacle only serves to provide collision avoidance to a " "Spatial inheriting parent object." msgstr "" -"Un NavigationObstacle ne peut éviter les collisions qu'avec les nœuds " -"Spatial." +"Le NavigationObstacle ne sert qu'à fournir l’évitement de collision qu'aux " +"objets dont les parents héritent de Spatial." #: scene/3d/occluder.cpp msgid "No shape is set." @@ -23053,19 +22518,16 @@ msgstr "" "Particles » activé." #: scene/3d/particles.cpp -#, fuzzy msgid "Visibility AABB" -msgstr "Basculer la visibilité" +msgstr "Visibilité AABB" #: scene/3d/particles.cpp -#, fuzzy msgid "Draw Passes" -msgstr "Appels de dessin :" +msgstr "Afficher les passes" #: scene/3d/particles.cpp -#, fuzzy msgid "Passes" -msgstr "Appels de dessin :" +msgstr "Passes" #: scene/3d/path.cpp msgid "PathFollow only works when set as a child of a Path node." @@ -23082,7 +22544,6 @@ msgstr "" "Vector » dans la ressource Curve de son parent Path." #: scene/3d/path.cpp -#, fuzzy msgid "Rotation Mode" msgstr "Mode rotation" @@ -23097,223 +22558,189 @@ msgstr "" "Modifiez la taille dans les formes de collision enfant à la place." #: scene/3d/physics_body.cpp -#, fuzzy msgid "Axis Lock" -msgstr "Axe" +msgstr "Verrouiller l'axe" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear X" -msgstr "Linéaire" +msgstr "X linéaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Y" -msgstr "Linéaire" +msgstr "Y linéaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Z" -msgstr "Linéaire" +msgstr "Z linéaire" #: scene/3d/physics_body.cpp msgid "Angular X" -msgstr "" +msgstr "X angulaire" #: scene/3d/physics_body.cpp msgid "Angular Y" -msgstr "" +msgstr "Y angulaire" #: scene/3d/physics_body.cpp msgid "Angular Z" -msgstr "" +msgstr "Z angulaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion X" -msgstr "Action" +msgstr "X mouvement" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion Y" -msgstr "Action" +msgstr "Y mouvement" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion Z" -msgstr "Action" +msgstr "Z mouvement" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Joint Constraints" -msgstr "Constantes" +msgstr "Restrictions de jointure" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Impulse Clamp" -msgstr "" +msgstr "Borner l'impulsion" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Swing Span" -msgstr "Enregistrement de la scène" +msgstr "Ampleur de balancement" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Twist Span" -msgstr "" +msgstr "Ampleur de torsion" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Relaxation" -msgstr "Séparation :" +msgstr "Relaxation" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Enabled" -msgstr "Filtrer les signaux" +msgstr "Limite angulaire activée" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Upper" -msgstr "Linéaire" +msgstr "Limite angulaire haute" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Lower" -msgstr "Erreur angulaire max. :" +msgstr "Limite angulaire basse" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Bias" -msgstr "Linéaire" +msgstr "Biais de limite angulaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Softness" -msgstr "Animation" +msgstr "Douceur de limite angulaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Relaxation" -msgstr "Animation" +msgstr "Relaxation de limite angulaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Upper" -msgstr "Linéaire" +msgstr "Limite linéaire haute" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Lower" -msgstr "Linéaire" +msgstr "Limite linéaire basse" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Softness" -msgstr "Linéaire" +msgstr "Douceur de limite linéaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Restitution" -msgstr "Linéaire" +msgstr "Restitution de limite linéaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Damping" -msgstr "Linéaire" +msgstr "Amortissement de limite linéaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Restitution" -msgstr "Animation" +msgstr "Restitution de limite angulaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Damping" -msgstr "Animation" +msgstr "Amortissement de limite angulaire" #: scene/3d/physics_body.cpp msgid "X" -msgstr "" +msgstr "X" #: scene/3d/physics_body.cpp msgid "Y" -msgstr "" +msgstr "Y" #: scene/3d/physics_body.cpp msgid "Z" -msgstr "" +msgstr "Z" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Enabled" -msgstr "Linéaire" +msgstr "Limite linéaire active" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Spring Enabled" -msgstr "Linéaire" +msgstr "Ressort linéaire actif" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Spring Stiffness" -msgstr "Linéaire" +msgstr "Raideur du ressort linéaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Spring Damping" -msgstr "Linéaire" +msgstr "Amortissement de ressort linéaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Equilibrium Point" -msgstr "Linéaire" +msgstr "Point d’équilibre linéaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Restitution" -msgstr "Description" +msgstr "Restitution linéaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Damping" -msgstr "Linéaire" +msgstr "Amortissement linéaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Restitution" -msgstr "Description" +msgstr "Restitution angulaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Damping" -msgstr "Animation" +msgstr "Amortissement angulaire" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "ERP" msgstr "" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Spring Enabled" -msgstr "Filtrer les signaux" +msgstr "Ressort angulaire actif" #: scene/3d/physics_body.cpp msgid "Angular Spring Stiffness" -msgstr "" +msgstr "Raideur de ressort angulaire" #: scene/3d/physics_body.cpp msgid "Angular Spring Damping" -msgstr "" +msgstr "Amortissement de ressort angulaire" #: scene/3d/physics_body.cpp msgid "Angular Equilibrium Point" -msgstr "" +msgstr "Point d’équilibre angulaire" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Body Offset" -msgstr "Décalage :" +msgstr "Décalage du corps" #: scene/3d/physics_joint.cpp msgid "Node A and Node B must be PhysicsBodies" @@ -23337,183 +22764,159 @@ msgstr "Node A et Node B doivent être des PhysicsBody différents" #: scene/3d/physics_joint.cpp msgid "Solver" -msgstr "" +msgstr "Résolveur" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Exclude Nodes" -msgstr "Supprimer des nœuds" +msgstr "Exclure les nœuds" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Params" -msgstr "Paramètre modifié :" +msgstr "Paramètres" #: scene/3d/physics_joint.cpp msgid "Angular Limit" -msgstr "" +msgstr "Limite angulaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper" -msgstr "Tout en majuscule" +msgstr "Haute" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower" -msgstr "Tout en minuscule" +msgstr "Basse" #: scene/3d/physics_joint.cpp msgid "Motor" -msgstr "" +msgstr "Moteur" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Target Velocity" -msgstr "Vue de l'orbite vers la droite" +msgstr "Vélocité cible" #: scene/3d/physics_joint.cpp msgid "Max Impulse" msgstr "Impulsion Maximale" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit" -msgstr "Linéaire" +msgstr "Limite linéaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper Distance" -msgstr "Choisissez distance :" +msgstr "Distance haute" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower Distance" -msgstr "Choisissez distance :" +msgstr "Distance basse" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Restitution" -msgstr "Description" +msgstr "Restitution" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motion" -msgstr "Initialiser" +msgstr "Mouvement linéaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Ortho" -msgstr "Orthogonale arrière" +msgstr "Ortho linéaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper Angle" -msgstr "Tout en majuscule" +msgstr "Angle supérieur" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower Angle" -msgstr "Tout en minuscule" +msgstr "Angle inférieur" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Angular Motion" -msgstr "Animation" +msgstr "Mouvement angulaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Angular Ortho" -msgstr "Erreur angulaire max. :" +msgstr "Ortho angulaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit X" -msgstr "Linéaire" +msgstr "X de la limite linéaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor X" -msgstr "Initialiser" +msgstr "X du moteur linéaire" #: scene/3d/physics_joint.cpp msgid "Force Limit" msgstr "Limite de Force" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Spring X" -msgstr "Linéaire" +msgstr "X du ressort linéaire" #: scene/3d/physics_joint.cpp msgid "Equilibrium Point" -msgstr "" +msgstr "Point d’équilibre" #: scene/3d/physics_joint.cpp msgid "Angular Limit X" -msgstr "" +msgstr "X de la limite angulaire" #: scene/3d/physics_joint.cpp msgid "Angular Motor X" -msgstr "" +msgstr "X du moteur angulaire" #: scene/3d/physics_joint.cpp msgid "Angular Spring X" -msgstr "" +msgstr "X du ressort angulaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit Y" -msgstr "Linéaire" +msgstr "Y de la limite linéaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor Y" -msgstr "Initialiser" +msgstr "Y du moteur linéaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Spring Y" -msgstr "Linéaire" +msgstr "Y du ressort linéaire" #: scene/3d/physics_joint.cpp msgid "Angular Limit Y" -msgstr "" +msgstr "Y de la limite angulaire" #: scene/3d/physics_joint.cpp msgid "Angular Motor Y" -msgstr "" +msgstr "Y du moteur angulaire" #: scene/3d/physics_joint.cpp msgid "Angular Spring Y" -msgstr "" +msgstr "Y du ressort angulaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit Z" -msgstr "Linéaire" +msgstr "Z de la limite linéaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor Z" -msgstr "Initialiser" +msgstr "Z du moteur linéaire" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Spring Z" -msgstr "Linéaire" +msgstr "Z du ressort linéaire" #: scene/3d/physics_joint.cpp msgid "Angular Limit Z" -msgstr "" +msgstr "Z de la limite angulaire" #: scene/3d/physics_joint.cpp msgid "Angular Motor Z" -msgstr "" +msgstr "Z du moteur angulaire" #: scene/3d/physics_joint.cpp msgid "Angular Spring Z" -msgstr "" +msgstr "Z du ressort angulaire" #: scene/3d/portal.cpp msgid "The RoomManager should not be a child or grandchild of a Portal." @@ -23533,21 +22936,19 @@ msgstr "Portail actif" #: scene/3d/portal.cpp scene/resources/occluder_shape_polygon.cpp msgid "Two Way" -msgstr "" +msgstr "Double sens" #: scene/3d/portal.cpp msgid "Linked Room" msgstr "Salle liée" #: scene/3d/portal.cpp -#, fuzzy msgid "Use Default Margin" -msgstr "Défaut" +msgstr "Utiliser les marges par défaut" #: scene/3d/proximity_group.cpp -#, fuzzy msgid "Group Name" -msgstr "Groupé" +msgstr "Nom de groupe" #: scene/3d/proximity_group.cpp msgid "Dispatch Mode" @@ -23558,42 +22959,36 @@ msgid "Grid Radius" msgstr "Rayon de la Grille" #: scene/3d/ray_cast.cpp -#, fuzzy msgid "Debug Shape" -msgstr "Débogueur" +msgstr "Forme de débogage" #: scene/3d/ray_cast.cpp scene/resources/style_box.cpp msgid "Thickness" -msgstr "" +msgstr "Épaisseur" #: scene/3d/reflection_probe.cpp scene/main/viewport.cpp -#, fuzzy msgid "Update Mode" -msgstr "Mode rotation" +msgstr "Mode de mise à jour" #: scene/3d/reflection_probe.cpp msgid "Origin Offset" msgstr "Décalage de la Grille" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Box Projection" -msgstr "Projet" +msgstr "Projection boîte" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Enable Shadows" -msgstr "Activer l'alignement" +msgstr "Activer les ombres" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Ambient Color" -msgstr "Prélever une couleur" +msgstr "Couleur ambiante" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Ambient Energy" -msgstr "Couleurs d'émission" +msgstr "Énergie ambiante" #: scene/3d/reflection_probe.cpp #, fuzzy @@ -23974,9 +23369,8 @@ msgid "Use As Steering" msgstr "" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Wheel" -msgstr "Molette vers le haut." +msgstr "Molette" #: scene/3d/vehicle_body.cpp msgid "Roll Influence" @@ -24012,9 +23406,8 @@ msgid "Material Override" msgstr "Redéfinition" #: scene/3d/visual_instance.cpp -#, fuzzy msgid "Material Overlay" -msgstr "Changements de matériau :" +msgstr "Superposition de Matériau" #: scene/3d/visual_instance.cpp #, fuzzy @@ -24022,9 +23415,8 @@ msgid "Cast Shadow" msgstr "Créer un nœud Shader" #: scene/3d/visual_instance.cpp -#, fuzzy msgid "Extra Cull Margin" -msgstr "Arguments supplémentaires :" +msgstr "Marge supplémentaire de détermination des faces cachées" #: scene/3d/visual_instance.cpp #, fuzzy @@ -24096,14 +23488,12 @@ msgid "Mix Mode" msgstr "Mélanger le nœud" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Fadein Time" -msgstr "Durée du fondu (s) :" +msgstr "Durée du fondu entrant" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Fadeout Time" -msgstr "Durée du fondu (s) :" +msgstr "Durée du fondu sortant" #: scene/animation/animation_blend_tree.cpp msgid "Auto Restart" @@ -24118,9 +23508,8 @@ msgid "Delay" msgstr "" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Random Delay" -msgstr "Inclinaison aléatoire :" +msgstr "Retard aléatoire" #: scene/animation/animation_blend_tree.cpp #, fuzzy @@ -24128,9 +23517,8 @@ msgid "Add Amount" msgstr "Quantité" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Blend Amount" -msgstr "Quantité :" +msgstr "Quantité de mélange" #: scene/animation/animation_blend_tree.cpp #, fuzzy @@ -24144,9 +23532,8 @@ msgstr "Ajouter un port d'entrée" #: scene/animation/animation_blend_tree.cpp #: scene/animation/animation_node_state_machine.cpp -#, fuzzy msgid "Xfade Time" -msgstr "Durée du fondu (s) :" +msgstr "Durée du fondu croisé" #: scene/animation/animation_node_state_machine.cpp #, fuzzy @@ -24558,9 +23945,8 @@ msgid "Pass On Modal Close Click" msgstr "" #: scene/gui/control.cpp -#, fuzzy msgid "Size Flags" -msgstr "Taille :" +msgstr "Drapeaux de Taille" #: scene/gui/control.cpp #, fuzzy @@ -24612,9 +23998,8 @@ msgid "Scroll Offset" msgstr "Décalage du Défilement" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Snap Distance" -msgstr "Choisissez distance :" +msgstr "Distance d'arrondissage" #: scene/gui/graph_edit.cpp #, fuzzy @@ -24751,9 +24136,8 @@ msgid "Secret" msgstr "" #: scene/gui/line_edit.cpp -#, fuzzy msgid "Secret Character" -msgstr "Caractères valides :" +msgstr "Caractère secret" #: scene/gui/line_edit.cpp msgid "Expand To Text Length" @@ -24810,7 +24194,7 @@ msgstr "" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Caret" -msgstr "" +msgstr "Caret" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Blink" @@ -24987,9 +24371,8 @@ msgid "Meta Underlined" msgstr "" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Tab Size" -msgstr "Taille :" +msgstr "Taille de tabulation" #: scene/gui/rich_text_label.cpp #, fuzzy @@ -25010,9 +24393,8 @@ msgid "Selection Enabled" msgstr "Sélection uniquement" #: scene/gui/rich_text_label.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Override Selected Font Color" -msgstr "Configurer le profil sélectionné :" +msgstr "Remplacer la couleur de police sélectionnée" #: scene/gui/rich_text_label.cpp #, fuzzy @@ -25063,9 +24445,8 @@ msgid "Tick Count" msgstr "Prélever une couleur" #: scene/gui/slider.cpp -#, fuzzy msgid "Ticks On Borders" -msgstr "dans l'ordre :" +msgstr "Encoches aux bordures" #: scene/gui/spin_box.cpp msgid "Prefix" @@ -25076,9 +24457,8 @@ msgid "Suffix" msgstr "Suffixe" #: scene/gui/split_container.cpp -#, fuzzy msgid "Split Offset" -msgstr "Décalage de la grille :" +msgstr "Décalage des écarts" #: scene/gui/split_container.cpp scene/gui/tree.cpp #, fuzzy @@ -25095,9 +24475,8 @@ msgid "Tab Align" msgstr "" #: scene/gui/tab_container.cpp scene/gui/tabs.cpp -#, fuzzy msgid "Current Tab" -msgstr "Actuel :" +msgstr "Onglet actuel" #: scene/gui/tab_container.cpp #, fuzzy @@ -25139,9 +24518,8 @@ msgid "Breakpoint Gutter" msgstr "Passer les points d'arrêt" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Fold Gutter" -msgstr "Dossier :" +msgstr "Replier le bandeau" #: scene/gui/text_edit.cpp #, fuzzy @@ -25243,9 +24621,8 @@ msgid "Initial Angle" msgstr "Initialiser" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Fill Degrees" -msgstr "Rotation de %s degrés." +msgstr "Degrés remplis" #: scene/gui/texture_progress.cpp scene/resources/primitive_meshes.cpp #, fuzzy @@ -25351,9 +24728,8 @@ msgid "Max Redirects" msgstr "" #: scene/main/http_request.cpp -#, fuzzy msgid "Timeout" -msgstr "Délai dépassé." +msgstr "Délai dépassé" #: scene/main/node.cpp msgid "" @@ -25626,9 +25002,8 @@ msgid "Debug Draw" msgstr "Débogage" #: scene/main/viewport.cpp -#, fuzzy msgid "Render Target" -msgstr "Moteur de rendu :" +msgstr "Rendre la cible" #: scene/main/viewport.cpp msgid "V Flip" @@ -25801,9 +25176,8 @@ msgid "Font Color Disabled" msgstr "Âgrafe désactivée" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "H Separation" -msgstr "Séparation :" +msgstr "Séparation H" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25891,14 +25265,12 @@ msgid "Font Outline Modulate" msgstr "Forcer la modulation blanche" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Shadow Offset X" -msgstr "Décalage X de la grille :" +msgstr "Décalage X de l'ombre" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Shadow Offset Y" -msgstr "Décalage Y de la grille :" +msgstr "Décalage Y de l'ombre" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25956,14 +25328,12 @@ msgid "Space" msgstr "Scène principale" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Folded" -msgstr "Dossier :" +msgstr "Replié" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Fold" -msgstr "Dossier :" +msgstr "Replier" #: scene/resources/default_theme/default_theme.cpp msgid "Font Color Readonly" @@ -26082,14 +25452,12 @@ msgid "Close Highlight" msgstr "Éclairage direct" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Close H Offset" -msgstr "Décalage de la grille :" +msgstr "Fermer décalage H" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Close V Offset" -msgstr "Décalage de la grille :" +msgstr "Fermer décalage V" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26117,9 +25485,8 @@ msgid "Labeled Separator Right" msgstr "Séparateur nommé" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Separator" -msgstr "Opérateur de couleur." +msgstr "Séparateur de police" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26127,14 +25494,12 @@ msgid "Font Color Accel" msgstr "Renommer l'item de couleur" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Separator" -msgstr "Opérateur de couleur." +msgstr "Séparateur de couleur de police" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "V Separation" -msgstr "Séparation :" +msgstr "Séparation V" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26182,9 +25547,8 @@ msgid "Title Offset" msgstr "Décalage d’Octet" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Close Offset" -msgstr "Décalage de la grille :" +msgstr "Fermer de décalage" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26314,9 +25678,8 @@ msgid "Icon Margin" msgstr "Définir la marge" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Line Separation" -msgstr "Séparation :" +msgstr "Séparation de line" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26376,9 +25739,8 @@ msgid "Large" msgstr "Cible" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Folder" -msgstr "Dossier :" +msgstr "Dossier" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26416,9 +25778,8 @@ msgid "Label Width" msgstr "Étendu à Gauche" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Screen Picker" -msgstr "Opérateur d'écran." +msgstr "Sélecteur d'écran" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26479,14 +25840,12 @@ msgid "Mono Font" msgstr "Police Principale" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Table H Separation" -msgstr "Séparation :" +msgstr "Séparation H de table" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Table V Separation" -msgstr "Séparation :" +msgstr "Séparation V de table" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26651,7 +26010,7 @@ msgstr "Condition" #: scene/resources/environment.cpp msgid "Fog" -msgstr "" +msgstr "Brouillard" #: scene/resources/environment.cpp msgid "Sun Color" @@ -26747,14 +26106,12 @@ msgid "Max Steps" msgstr "Pas" #: scene/resources/environment.cpp -#, fuzzy msgid "Fade In" -msgstr "Fondu entrant (s) :" +msgstr "Fondu entrant" #: scene/resources/environment.cpp -#, fuzzy msgid "Fade Out" -msgstr "Fondu sortant (s) :" +msgstr "Fondu sortant" #: scene/resources/environment.cpp #, fuzzy @@ -26833,54 +26190,52 @@ msgstr "2" #: scene/resources/environment.cpp #: servers/audio/effects/audio_effect_chorus.cpp msgid "3" -msgstr "" +msgstr "3" #: scene/resources/environment.cpp #: servers/audio/effects/audio_effect_chorus.cpp msgid "4" -msgstr "" +msgstr "4" #: scene/resources/environment.cpp msgid "5" -msgstr "" +msgstr "5" #: scene/resources/environment.cpp msgid "6" -msgstr "" +msgstr "6" #: scene/resources/environment.cpp msgid "7" -msgstr "" +msgstr "7" #: scene/resources/environment.cpp msgid "Bloom" -msgstr "" +msgstr "Flou lumineux" #: scene/resources/environment.cpp msgid "HDR Threshold" -msgstr "" +msgstr "Seuil HDR" #: scene/resources/environment.cpp msgid "HDR Luminance Cap" -msgstr "" +msgstr "Limite de luminance HDR" #: scene/resources/environment.cpp -#, fuzzy msgid "HDR Scale" -msgstr "Mode mise à l'échelle" +msgstr "Échelle HDR" #: scene/resources/environment.cpp msgid "Bicubic Upscale" -msgstr "" +msgstr "Redimensionnement Bicubique" #: scene/resources/environment.cpp msgid "Adjustments" -msgstr "" +msgstr "Ajustements" #: scene/resources/environment.cpp -#, fuzzy msgid "Brightness" -msgstr "Lumière" +msgstr "Luminosité" #: scene/resources/environment.cpp msgid "Saturation" @@ -26888,22 +26243,19 @@ msgstr "Saturation" #: scene/resources/environment.cpp msgid "Color Correction" -msgstr "Correction de Couleur" +msgstr "Correction des couleurs" #: scene/resources/font.cpp -#, fuzzy msgid "Ascent" -msgstr "Récents :" +msgstr "Inclinaison" #: scene/resources/font.cpp -#, fuzzy msgid "Distance Field" -msgstr "Mode Sans Distraction" +msgstr "Champ de distance" #: scene/resources/gradient.cpp -#, fuzzy msgid "Raw Data" -msgstr "Profondeur" +msgstr "Données brutes" #: scene/resources/gradient.cpp msgid "Offsets" @@ -26911,62 +26263,55 @@ msgstr "Décalages" #: scene/resources/height_map_shape.cpp msgid "Map Width" -msgstr "" +msgstr "Largeur de la carte" #: scene/resources/height_map_shape.cpp -#, fuzzy msgid "Map Depth" -msgstr "Profondeur" +msgstr "Profondeur de la carte" #: scene/resources/height_map_shape.cpp -#, fuzzy msgid "Map Data" -msgstr "Profondeur" +msgstr "Données de la carte" #: scene/resources/line_shape_2d.cpp msgid "D" -msgstr "" +msgstr "D" #: scene/resources/material.cpp -#, fuzzy msgid "Next Pass" -msgstr "Plan suivant" +msgstr "Passe suivante" #: scene/resources/material.cpp msgid "Use Shadow To Opacity" msgstr "" #: scene/resources/material.cpp -#, fuzzy msgid "Unshaded" -msgstr "Afficher sans ombrage" +msgstr "Sans ombrage" #: scene/resources/material.cpp -#, fuzzy msgid "Vertex Lighting" -msgstr "Éclairage direct" +msgstr "Éclairage de sommet" #: scene/resources/material.cpp -#, fuzzy msgid "Use Point Size" -msgstr "Vue de devant" +msgstr "Utiliser la taille de point" #: scene/resources/material.cpp msgid "World Triplanar" -msgstr "" +msgstr "Monde Triplanaire" #: scene/resources/material.cpp msgid "Albedo Tex Force sRGB" -msgstr "" +msgstr "Forcer sRGB dans la texture d'albédo" #: scene/resources/material.cpp msgid "Do Not Receive Shadows" -msgstr "" +msgstr "Ne pas recevoir d'ombres" #: scene/resources/material.cpp -#, fuzzy msgid "Disable Ambient Light" -msgstr "Indenter vers la droite" +msgstr "Désactiver la lumière ambiante" #: scene/resources/material.cpp msgid "Ensure Correct Normals" @@ -26974,70 +26319,63 @@ msgstr "Assurer des Normales Correctes" #: scene/resources/material.cpp msgid "Albedo Tex MSDF" -msgstr "" +msgstr "Texture d'albédo MSDF" #: scene/resources/material.cpp -#, fuzzy msgid "Vertex Color" -msgstr "Vertex" +msgstr "Couleur de sommet" #: scene/resources/material.cpp msgid "Use As Albedo" -msgstr "" +msgstr "Utiliser comme albédo" #: scene/resources/material.cpp msgid "Is sRGB" -msgstr "" +msgstr "Est sRGB" #: scene/resources/material.cpp servers/visual_server.cpp msgid "Parameters" msgstr "Paramètres" #: scene/resources/material.cpp -#, fuzzy msgid "Diffuse Mode" -msgstr "Mode navigation" +msgstr "Mode diffus" #: scene/resources/material.cpp -#, fuzzy msgid "Specular Mode" -msgstr "Mode Règle" +msgstr "Mode spéculaire" #: scene/resources/material.cpp -#, fuzzy msgid "Depth Draw Mode" -msgstr "Mode d’interpolation" +msgstr "Mode de dessin en profondeur" #: scene/resources/material.cpp -#, fuzzy msgid "Line Width" -msgstr "Étendu à Gauche" +msgstr "Largeur de ligne" #: scene/resources/material.cpp -#, fuzzy msgid "Point Size" -msgstr "Vue de devant" +msgstr "Taille de point" #: scene/resources/material.cpp msgid "Billboard Mode" -msgstr "Mode billboard" +msgstr "Mode Billboard" #: scene/resources/material.cpp msgid "Billboard Keep Scale" -msgstr "Garder l'échelle du billboard" +msgstr "Garder l'échelle du Billboard" #: scene/resources/material.cpp msgid "Grow" -msgstr "" +msgstr "Croître" #: scene/resources/material.cpp -#, fuzzy msgid "Grow Amount" -msgstr "Quantité :" +msgstr "Quantité de croissance" #: scene/resources/material.cpp msgid "Use Alpha Scissor" -msgstr "" +msgstr "Utiliser la découpe alpha" #: scene/resources/material.cpp #, fuzzy @@ -27056,7 +26394,7 @@ msgstr "Image %" #: scene/resources/material.cpp msgid "Albedo" -msgstr "" +msgstr "Albédo" #: scene/resources/material.cpp msgid "Metallic" @@ -27082,7 +26420,7 @@ msgstr "" #: scene/resources/material.cpp msgid "Rim" -msgstr "Bordure" +msgstr "Bord" #: scene/resources/material.cpp #, fuzzy @@ -27206,9 +26544,8 @@ msgid "Color Format" msgstr "Format de Couleur" #: scene/resources/multimesh.cpp -#, fuzzy msgid "Transform Format" -msgstr "Transformation annulée." +msgstr "Format de transformation" #: scene/resources/multimesh.cpp msgid "Custom Data Format" @@ -27224,9 +26561,8 @@ msgid "Visible Instance Count" msgstr "" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Sampling" -msgstr "Mise à l'échelle :" +msgstr "Échantillonnage" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -27234,9 +26570,8 @@ msgid "Partition Type" msgstr "Définir type de variable" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Parsed Geometry Type" -msgstr "Analyse de la géométrie..." +msgstr "Type de la géométrie analysée" #: scene/resources/navigation_mesh.cpp msgid "Source Geometry Mode" @@ -27293,9 +26628,8 @@ msgid "Details" msgstr "Afficher par défaut" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Sample Distance" -msgstr "Choisissez distance :" +msgstr "Échantillonner la distance" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -27366,12 +26700,10 @@ msgid "Color Modifier" msgstr "Ralentissement de la vue libre" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Point Texture" -msgstr "Points d'Émission :" +msgstr "Texture ponctuelle" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Normal Texture" msgstr "Texture Normale" @@ -27403,9 +26735,8 @@ msgid "Absorbent" msgstr "" #: scene/resources/plane_shape.cpp -#, fuzzy msgid "Plane" -msgstr "Plan :" +msgstr "Plan" #: scene/resources/primitive_meshes.cpp #, fuzzy @@ -27479,9 +26810,8 @@ msgid "Bone" msgstr "Os" #: scene/resources/sky.cpp -#, fuzzy msgid "Radiance Size" -msgstr "Taille du contour :" +msgstr "Taille du rayonnement" #: scene/resources/sky.cpp msgid "Panorama" @@ -27773,9 +27103,8 @@ msgid "Default Cell Height" msgstr "En période de test" #: scene/resources/world.cpp scene/resources/world_2d.cpp -#, fuzzy msgid "Default Edge Connection Margin" -msgstr "Modifier la connexion :" +msgstr "Marge de connexion des bords par défaut" #: scene/resources/world_2d.cpp msgid "Canvas" @@ -27929,11 +27258,11 @@ msgstr "Ressource" #: servers/audio/effects/audio_effect_limiter.cpp msgid "Ceiling dB" -msgstr "" +msgstr "Plafond de dB" #: servers/audio/effects/audio_effect_limiter.cpp msgid "Threshold dB" -msgstr "" +msgstr "Seuil de dB" #: servers/audio/effects/audio_effect_limiter.cpp msgid "Soft Clip dB" @@ -27945,37 +27274,36 @@ msgstr "" #: servers/audio/effects/audio_effect_phaser.cpp msgid "Range Min Hz" -msgstr "" +msgstr "Borne inférieure de la plage (Hz)" #: servers/audio/effects/audio_effect_phaser.cpp msgid "Range Max Hz" -msgstr "" +msgstr "Borne supérieure de la plage (Hz)" #: servers/audio/effects/audio_effect_pitch_shift.cpp msgid "Oversampling" -msgstr "" +msgstr "Suréchantillonnage" #: servers/audio/effects/audio_effect_pitch_shift.cpp #: servers/audio/effects/audio_effect_spectrum_analyzer.cpp msgid "FFT Size" -msgstr "Taille FFT" +msgstr "Taille des FFTs" #: servers/audio/effects/audio_effect_reverb.cpp msgid "Predelay" -msgstr "" +msgstr "Pré-retarder" #: servers/audio/effects/audio_effect_reverb.cpp msgid "Msec" -msgstr "" +msgstr "Millisec" #: servers/audio/effects/audio_effect_reverb.cpp msgid "Room Size" -msgstr "" +msgstr "Taille de la salle" #: servers/audio/effects/audio_effect_reverb.cpp -#, fuzzy msgid "High-pass" -msgstr "Contourner" +msgstr "Passe-haut" #: servers/audio/effects/audio_effect_spectrum_analyzer.cpp msgid "Tap Back Pos" @@ -27986,27 +27314,24 @@ msgid "Pan Pullout" msgstr "" #: servers/audio/effects/audio_effect_stereo_enhance.cpp -#, fuzzy msgid "Time Pullout (ms)" -msgstr "Délai dépassé." +msgstr "Temps de retrait (ms)" #: servers/audio/effects/audio_effect_stereo_enhance.cpp msgid "Surround" -msgstr "" +msgstr "Surround" #: servers/audio_server.cpp -#, fuzzy msgid "Enable Audio Input" -msgstr "Renommer le bus audio" +msgstr "Activer l’entrée audio" #: servers/audio_server.cpp -#, fuzzy msgid "Output Latency" -msgstr "Sortie" +msgstr "Latence de sortie" #: servers/audio_server.cpp msgid "Channel Disable Threshold dB" -msgstr "" +msgstr "Désactiver le seuil de dB du canal" #: servers/audio_server.cpp #, fuzzy @@ -28015,43 +27340,39 @@ msgstr "Changer le temps de mélange" #: servers/audio_server.cpp msgid "Video Delay Compensation (ms)" -msgstr "" +msgstr "Compensation de retard vidéo (ms)" #: servers/audio_server.cpp -#, fuzzy msgid "Bus Count" -msgstr "Ajouter un port d'entrée" +msgstr "Nombre de ports" #: servers/audio_server.cpp -#, fuzzy msgid "Capture Device" -msgstr "Capturer depuis Pixel" +msgstr "Périphérique de capture" #: servers/audio_server.cpp -#, fuzzy msgid "Global Rate Scale" -msgstr "Variable globale" +msgstr "Echelle de débit global" #: servers/camera/camera_feed.cpp msgid "Feed" -msgstr "" +msgstr "Flux" #: servers/camera/camera_feed.cpp -#, fuzzy msgid "Is Active" -msgstr "Perspective" +msgstr "Est active" #: servers/physics/space_sw.cpp servers/physics_2d/space_2d_sw.cpp msgid "Sleep Threshold Linear" -msgstr "" +msgstr "Seuil linéaire de veille" #: servers/physics/space_sw.cpp servers/physics_2d/space_2d_sw.cpp msgid "Sleep Threshold Angular" -msgstr "" +msgstr "Seuil angulaire de veille" #: servers/physics/space_sw.cpp servers/physics_2d/space_2d_sw.cpp msgid "Time Before Sleep" -msgstr "" +msgstr "Temps avant veille" #: servers/physics_2d/physics_2d_server_sw.cpp msgid "BP Hash Table Size" @@ -28063,48 +27384,43 @@ msgstr "" #: servers/physics_2d_server.cpp servers/physics_server.cpp msgid "Inverse Mass" -msgstr "" +msgstr "Masse inverse" #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Inverse Inertia" -msgstr "Vue libre gauche" +msgstr "Inertie inverse" #: servers/physics_2d_server.cpp servers/physics_server.cpp msgid "Total Angular Damp" -msgstr "" +msgstr "Amortissage angulaire total" #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Total Linear Damp" -msgstr "Linéaire" +msgstr "Amortissage linéaire total" #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Total Gravity" -msgstr "Aperçu par défaut" +msgstr "Gravité totale" #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Linear Velocity" -msgstr "Initialiser" +msgstr "Vélocité linéaire" #: servers/physics_2d_server.cpp servers/physics_server.cpp msgid "Exclude" -msgstr "" +msgstr "Exclure" #: servers/physics_2d_server.cpp servers/physics_server.cpp msgid "Shape RID" -msgstr "" +msgstr "RID de forme" #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collide With Bodies" -msgstr "Mode collision" +msgstr "Collisions avec les corps" #: servers/physics_2d_server.cpp servers/physics_server.cpp msgid "Collide With Areas" -msgstr "" +msgstr "Collisions avec les zones" #: servers/physics_2d_server.cpp servers/physics_server.cpp msgid "Motion Remainder" @@ -28346,14 +27662,12 @@ msgid "Use Software Skinning" msgstr "" #: servers/visual_server.cpp -#, fuzzy msgid "Ninepatch Mode" -msgstr "Mode d’interpolation" +msgstr "Mode Ninepatch" #: servers/visual_server.cpp -#, fuzzy msgid "OpenGL" -msgstr "Ouvrir" +msgstr "OpenGL" #: servers/visual_server.cpp msgid "Batching Send Null" @@ -28378,12 +27692,11 @@ msgstr "Traitement en lot" #: servers/visual_server.cpp msgid "Use Batching" -msgstr "" +msgstr "Utiliser le traitement en lot" #: servers/visual_server.cpp -#, fuzzy msgid "Use Batching In Editor" -msgstr "Mise à jour de l'éditeur" +msgstr "Utiliser le traitement en lot dans l'éditeur" #: servers/visual_server.cpp msgid "Single Rect Fallback" @@ -28407,7 +27720,7 @@ msgstr "Nombre Maximal d'Éléments Joints" #: servers/visual_server.cpp msgid "Batch Buffer Size" -msgstr "" +msgstr "Taille de tampon des lots" #: servers/visual_server.cpp msgid "Item Reordering Lookahead" @@ -28418,21 +27731,20 @@ msgid "Flash Batching" msgstr "" #: servers/visual_server.cpp -#, fuzzy msgid "Diagnose Frame" -msgstr "Coller une image" +msgstr "Diagnostiquer la trame" #: servers/visual_server.cpp msgid "GLES2" -msgstr "" +msgstr "GLES2" #: servers/visual_server.cpp msgid "Compatibility" -msgstr "" +msgstr "Compatibilité" #: servers/visual_server.cpp msgid "Disable Half Float" -msgstr "" +msgstr "Désactiver les demi Float" #: servers/visual_server.cpp #, fuzzy @@ -28440,31 +27752,28 @@ msgid "Enable High Float" msgstr "Activer la priorité" #: servers/visual_server.cpp -#, fuzzy msgid "Precision" -msgstr "Expression" +msgstr "Précision" #: servers/visual_server.cpp msgid "UV Contract" -msgstr "" +msgstr "Contraction UV" #: servers/visual_server.cpp msgid "UV Contract Amount" -msgstr "" +msgstr "Quantité de contraction UV" #: servers/visual_server.cpp -#, fuzzy msgid "Use Simple PVS" -msgstr "Utiliser le magnétisme d'échelle" +msgstr "Utiliser PVS simple" #: servers/visual_server.cpp msgid "PVS Logging" -msgstr "" +msgstr "Journal PVS" #: servers/visual_server.cpp -#, fuzzy msgid "Use Signals" -msgstr "Signaux" +msgstr "Utiliser les signaux" #: servers/visual_server.cpp #, fuzzy @@ -28483,27 +27792,24 @@ msgstr "Voir la suppression de l'occlusion" #: servers/visual_server.cpp msgid "Max Active Spheres" -msgstr "" +msgstr "Nombre maximum de sphères actives" #: servers/visual_server.cpp -#, fuzzy msgid "Max Active Polygons" -msgstr "Déplacer le polygone" +msgstr "Nombre maximum de polygones actifs" #: servers/visual_server.cpp -#, fuzzy msgid "Shader Compilation Mode" -msgstr "Mode d’interpolation" +msgstr "Mode de compilation des shaders" #: servers/visual_server.cpp msgid "Max Simultaneous Compiles" -msgstr "" +msgstr "Nombre de compilations simultanées" #: servers/visual_server.cpp msgid "Log Active Async Compiles Count" msgstr "" #: servers/visual_server.cpp -#, fuzzy msgid "Shader Cache Size (MB)" -msgstr "Changer la taille d'une caméra" +msgstr "Taille du cache de shader (Mo)" diff --git a/editor/translations/ga.po b/editor/translations/ga.po index db42dda6ed..87e005f5f3 100644 --- a/editor/translations/ga.po +++ b/editor/translations/ga.po @@ -2095,14 +2095,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cuardach:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2158,8 +2159,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2719,8 +2720,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "CrannBeochan" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5304,6 +5306,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11293,6 +11299,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "CrannBeochan" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19442,14 +19453,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19470,14 +19480,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/gl.po b/editor/translations/gl.po index b42b50e5a7..29db0e8063 100644 --- a/editor/translations/gl.po +++ b/editor/translations/gl.po @@ -2196,14 +2196,15 @@ msgstr "Favoritos:" msgid "Recent:" msgstr "Recente:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Buscar:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Coincidencias:" @@ -2263,8 +2264,8 @@ msgstr "Buscar Recurso de Substitución:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2850,7 +2851,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Copiar Ruta do Nodo" #: editor/editor_export.cpp @@ -5656,6 +5657,10 @@ msgid "Drag And Drop Selection" msgstr "Encadrar Selección" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11904,6 +11909,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrar métodos" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocidade:" @@ -20540,15 +20550,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Extensión inválida." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20570,15 +20580,15 @@ msgstr "Nome inválido." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Extensión inválida." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/he.po b/editor/translations/he.po index a89d117ead..abaada7880 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -2167,14 +2167,15 @@ msgstr "מועדפים:" msgid "Recent:" msgstr "אחרונים:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "חיפוש:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "התאמות:" @@ -2234,8 +2235,8 @@ msgstr "חיפוש משאב חלופי:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2806,7 +2807,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "העתקת נתיב המפרק" #: editor/editor_export.cpp @@ -5571,6 +5572,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap מילוי הבחירה" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11959,6 +11964,11 @@ msgstr "שם הנפשה חדשה:" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy +msgid "Filter animations" +msgstr "מאפייני פריט." + +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Speed:" msgstr "מהירות (FPS):" @@ -20697,15 +20707,15 @@ msgstr "לא ניתן לפתוח תבנית לייצוא:" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "סיומת לא חוקית." #: platform/windows/export/export.cpp #, fuzzy @@ -20729,15 +20739,15 @@ msgstr "שם שגוי." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "סיומת לא חוקית." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/hi.po b/editor/translations/hi.po index a598e43071..e5a41404d0 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -2155,14 +2155,15 @@ msgstr "पसंदीदा:" msgid "Recent:" msgstr "हाल ही में किया:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "खोज:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "एक जैसा:" @@ -2222,8 +2223,8 @@ msgstr "खोज रिप्लेसमेंट संसाधन:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2803,8 +2804,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "खंड कौपी कीजिये" #: editor/editor_export.cpp #, fuzzy @@ -5576,6 +5578,10 @@ msgid "Drag And Drop Selection" msgstr "सभी खंड" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11760,6 +11766,11 @@ msgid "New Animation" msgstr "एनिमेशन लूप" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "एनिमेशन" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20299,15 +20310,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "गलत फॉण्ट का आकार |" #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20329,15 +20340,15 @@ msgstr "अमान्य नाम." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "गलत फॉण्ट का आकार |" #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/hr.po b/editor/translations/hr.po index 61aeaeeb10..e473c6556c 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -6,12 +6,13 @@ # Patik <patrikfs5@gmail.com>, 2019. # Nikola Bunjevac <nikola.bunjevac@gmail.com>, 2019, 2020. # LeoClose <leoclose575@gmail.com>, 2020, 2021. +# Filip <fhomolka@protonmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2021-08-13 19:05+0000\n" -"Last-Translator: LeoClose <leoclose575@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: Filip <fhomolka@protonmail.com>\n" "Language-Team: Croatian <https://hosted.weblate.org/projects/godot-engine/" "godot/hr/>\n" "Language: hr\n" @@ -19,11 +20,11 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.8-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" -msgstr "" +msgstr "Upravljački program za Tablet" #: core/bind/core_bind.cpp msgid "Clipboard" @@ -39,73 +40,77 @@ msgid "Exit Code" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "V-Sync Enabled" -msgstr "Omogući" +msgstr "V-Sync Omogućen" #: core/bind/core_bind.cpp main/main.cpp msgid "V-Sync Via Compositor" -msgstr "" +msgstr "V-Sync preko Kompozitora" #: core/bind/core_bind.cpp main/main.cpp msgid "Delta Smoothing" -msgstr "" +msgstr "Delta Ublažavanje" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode" -msgstr "" +msgstr "Način niske upotrebe procesora" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode Sleep (µsec)" -msgstr "" +msgstr "Stanje mirovanja u načinu korištenja niskog procesora (μsec)" #: core/bind/core_bind.cpp main/main.cpp platform/uwp/os_uwp.cpp msgid "Keep Screen On" -msgstr "" +msgstr "Zadrži zaslon uključenim" #: core/bind/core_bind.cpp -#, fuzzy msgid "Min Window Size" -msgstr "Glavna skripta:" +msgstr "Min. veličina prozora" #: core/bind/core_bind.cpp -#, fuzzy msgid "Max Window Size" -msgstr "Glavna skripta:" +msgstr "Maks. veličina prozora" #: core/bind/core_bind.cpp msgid "Screen Orientation" -msgstr "" +msgstr "Orijentacija zaslona" #: core/bind/core_bind.cpp core/project_settings.cpp main/main.cpp #: platform/uwp/os_uwp.cpp +#, fuzzy msgid "Window" -msgstr "" +msgstr "Prozor" #: core/bind/core_bind.cpp core/project_settings.cpp +#, fuzzy msgid "Borderless" -msgstr "" +msgstr "Bez obruba" #: core/bind/core_bind.cpp +#, fuzzy msgid "Per Pixel Transparency Enabled" -msgstr "" +msgstr "Omogućena prozirnost po pikselu" #: core/bind/core_bind.cpp core/project_settings.cpp +#, fuzzy msgid "Fullscreen" -msgstr "" +msgstr "Cijeli zaslon" #: core/bind/core_bind.cpp +#, fuzzy msgid "Maximized" -msgstr "" +msgstr "Maksimiziran" #: core/bind/core_bind.cpp +#, fuzzy msgid "Minimized" -msgstr "" +msgstr "Minimiziran" #: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp #: scene/gui/graph_node.cpp +#, fuzzy msgid "Resizable" -msgstr "" +msgstr "Mogućnost promjene veličine" #: core/bind/core_bind.cpp core/os/input_event.cpp scene/2d/node_2d.cpp #: scene/2d/physics_body_2d.cpp scene/2d/remote_transform_2d.cpp @@ -114,7 +119,7 @@ msgstr "" #: scene/resources/default_theme/default_theme.cpp #, fuzzy msgid "Position" -msgstr "Stvori" +msgstr "Pozicija" #: core/bind/core_bind.cpp core/project_settings.cpp editor/editor_settings.cpp #: main/main.cpp modules/gridmap/grid_map.cpp @@ -125,8 +130,9 @@ msgstr "Stvori" #: scene/resources/primitive_meshes.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp #: scene/resources/visual_shader.cpp servers/visual_server.cpp +#, fuzzy msgid "Size" -msgstr "" +msgstr "Veličina" #: core/bind/core_bind.cpp msgid "Endian Swap" @@ -135,25 +141,27 @@ msgstr "" #: core/bind/core_bind.cpp #, fuzzy msgid "Editor Hint" -msgstr "(Editor Onemogućen)" +msgstr "Savjet Urednika" #: core/bind/core_bind.cpp +#, fuzzy msgid "Print Error Messages" -msgstr "" +msgstr "Ispis poruka o pogreškama" #: core/bind/core_bind.cpp #, fuzzy msgid "Iterations Per Second" -msgstr "Način Interpolacije" +msgstr "Iteracije u sekundi" #: core/bind/core_bind.cpp +#, fuzzy msgid "Target FPS" -msgstr "" +msgstr "Ciljani FPS" #: core/bind/core_bind.cpp #, fuzzy msgid "Time Scale" -msgstr "Dubina" +msgstr "Vremenska skala" #: core/bind/core_bind.cpp main/main.cpp msgid "Physics Jitter Fix" @@ -2125,14 +2133,15 @@ msgstr "Favoriti:" msgid "Recent:" msgstr "Nedavno:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Pretraga:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Podudaranja:" @@ -2192,8 +2201,8 @@ msgstr "Traži zamjenu resursa:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2764,8 +2773,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Animacija" #: editor/editor_export.cpp #, fuzzy @@ -5395,6 +5405,10 @@ msgid "Drag And Drop Selection" msgstr "Izbriši Odabir" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11479,6 +11493,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Obrisati Animaciju?" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19799,15 +19818,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Nevažeće ime." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -19829,15 +19848,15 @@ msgstr "Nevažeće ime." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Nevažeće ime." #: platform/windows/export/export.cpp msgid "Failed to remove temporary file \"%s\"." diff --git a/editor/translations/hu.po b/editor/translations/hu.po index 9f0d894b2a..b35be76368 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -2226,14 +2226,15 @@ msgstr "Kedvencek:" msgid "Recent:" msgstr "Legutóbbi:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Keresés:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Egyezések:" @@ -2293,8 +2294,8 @@ msgstr "Csere Forrás Keresése:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2871,7 +2872,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Node Útvonal Másolása" #: editor/editor_export.cpp @@ -5684,6 +5685,10 @@ msgid "Drag And Drop Selection" msgstr "Kijelölés Keretezése" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11933,6 +11938,11 @@ msgid "New Animation" msgstr "Új animáció" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Metódusok szűrése" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20500,15 +20510,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Érvénytelen kiterjesztés." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20530,15 +20540,15 @@ msgstr "Érvénytelen név." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Érvénytelen kiterjesztés." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/id.po b/editor/translations/id.po index 24547a7464..7d839357cd 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -39,13 +39,14 @@ # ProgrammerIndonesia 44 <elo.jhy@gmail.com>, 2022. # Rizky Ramadhan <rizkyterm@gmail.com>, 2022. # Primananda Kurnia <primakurnia71@gmail.com>, 2022. +# FellowMustard <rachmawanng33@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-09 21:12+0000\n" -"Last-Translator: yusuf afandi <afandi.yusuf.04@gmail.com>\n" +"PO-Revision-Date: 2022-07-31 18:34+0000\n" +"Last-Translator: ProgrammerIndonesia 44 <elo.jhy@gmail.com>\n" "Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/" "godot/id/>\n" "Language: id\n" @@ -53,7 +54,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -426,9 +427,8 @@ msgid "Command" msgstr "Perintah" #: core/os/input_event.cpp -#, fuzzy msgid "Physical" -msgstr " (Secara fisik)" +msgstr "(Secara fisik)" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp @@ -1206,7 +1206,7 @@ msgstr "Atur Pegangan" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp msgid "Stream" -msgstr "" +msgstr "Arus" #: editor/animation_track_editor.cpp #, fuzzy @@ -2158,14 +2158,15 @@ msgstr "Favorit:" msgid "Recent:" msgstr "Saat ini:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cari:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Kecocokan:" @@ -2225,8 +2226,8 @@ msgstr "Cari Resource Pengganti:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2803,13 +2804,12 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Salin Lokasi Node" #: editor/editor_export.cpp -#, fuzzy msgid "Completed successfully." -msgstr "Paket Sukses Terpasang!" +msgstr "Sukses." #: editor/editor_export.cpp #, fuzzy @@ -3288,9 +3288,8 @@ msgid "Save a File" msgstr "Simpan sebuah File" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Access" -msgstr "Sukses!" +msgstr "Akses" #: editor/editor_file_dialog.cpp editor/editor_settings.cpp #, fuzzy @@ -5616,6 +5615,10 @@ msgid "Drag And Drop Selection" msgstr "Isi Seleksi GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Penampilan" @@ -11849,6 +11852,11 @@ msgid "New Animation" msgstr "Animasi Baru" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filter method" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Kecepatan:" @@ -12371,9 +12379,8 @@ msgid "Available Node-based types:" msgstr "Profil yang Tersedia:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Type name is empty!" -msgstr "Nama berkas kosong." +msgstr "Nama tipe kosong!" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -19278,9 +19285,8 @@ msgid "Could not find keystore, unable to export." msgstr "Tidak dapat menemukan keystore, tidak bisa ekspor." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not start apksigner executable." -msgstr "Tidak dapat memulai subproses!" +msgstr "Tidak dapat memulai apksigner." #: platform/android/export/export_plugin.cpp msgid "'apksigner' returned with error #%d" @@ -19313,9 +19319,8 @@ msgid "Invalid filename! Android APK requires the *.apk extension." msgstr "Nama berkas tidak valid! APK Android memerlukan ekstensi *.apk ." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Unsupported export format!" -msgstr "Format ekspor tidak didukung!\n" +msgstr "Format ekspor tidak didukung!" #: platform/android/export/export_plugin.cpp msgid "" @@ -19326,15 +19331,12 @@ msgstr "" "versinya. Silakan pasang ulang dari menu 'Proyek'." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Android build version mismatch: Template installed: %s, Godot version: %s. " "Please reinstall Android build template from 'Project' menu." msgstr "" -"Versi build Android tidak cocok:\n" -" Templat terpasang: %s\n" -" Versi Godot: %s\n" -"Silakan pasang ulang templat build Android dari menu 'Project'." +"Versi build Android tidak cocok: Templat terpasang: %s, Versi Godot: %s. " +"Silakan pasang ulang templat build Android dari menu 'Proyek'." #: platform/android/export/export_plugin.cpp msgid "" @@ -19342,9 +19344,8 @@ msgid "" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files to gradle project." -msgstr "Tidak dapat menyunting proyek gradle dalam lokasi proyek\n" +msgstr "Tidak dapat mengekspor file proyek ke dalam lokasi proyek gradle." #: platform/android/export/export_plugin.cpp msgid "Could not write expansion package file!" @@ -19355,13 +19356,12 @@ msgid "Building Android Project (gradle)" msgstr "Membangun Proyek Android (gradle)" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Building of Android project failed, check output for the error. " "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" -"Pembangunan proyek Android gagal, periksa output untuk galatnya.\n" -"Atau kunjungi docs.godotengine.org untuk dokumentasi build Android." +"Pembangunan proyek Android gagal, periksa output untuk galatnya. Atau " +"kunjungi docs.godotengine.org untuk dokumentasi build Android." #: platform/android/export/export_plugin.cpp msgid "Moving output" @@ -19386,11 +19386,8 @@ msgid "Creating APK..." msgstr "Membuat kontur..." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not find template APK to export: \"%s\"." -msgstr "" -"Tidak dapat menemukan contoh APK untuk ekspor:\n" -"%s" +msgstr "Tidak dapat menemukan contoh APK untuk ekspor: \"%s\"" #: platform/android/export/export_plugin.cpp msgid "" @@ -19549,9 +19546,8 @@ msgid "Capabilities" msgstr "Kapabilitas" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Access Wi-Fi" -msgstr "Sukses!" +msgstr "Akses Wi-Fi" #: platform/iphone/export/export.cpp #, fuzzy @@ -20099,9 +20095,8 @@ msgid "Could not open icon file \"%s\"." msgstr "Tidak dapat ekspor berkas proyek" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not start xcrun executable." -msgstr "Tidak dapat memulai subproses!" +msgstr "Tidak dapat memulai subproses xcrun." #: platform/osx/export/export.cpp #, fuzzy @@ -20179,9 +20174,8 @@ msgid "DMG Creation" msgstr "Arah" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not start hdiutil executable." -msgstr "Tidak dapat memulai subproses!" +msgstr "Tidak dapat memulai subproses hdiutil." #: platform/osx/export/export.cpp msgid "`hdiutil create` failed - file exists." @@ -20263,7 +20257,7 @@ msgstr "Proyeksi" #: platform/osx/export/export.cpp #, fuzzy msgid "Could not open file to read from path \"%s\"." -msgstr "Tidak dapat menyunting proyek gradle dalam lokasi proyek\n" +msgstr "Tidak dapat membuka file untuk membaca dari jalur \"%s\"." #: platform/osx/export/export.cpp msgid "Invalid bundle identifier:" @@ -20648,15 +20642,15 @@ msgstr "Tidak dapat menemukan keystore, tidak bisa ekspor." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Ekstensi tidak valid." #: platform/windows/export/export.cpp #, fuzzy @@ -20680,15 +20674,15 @@ msgstr "Nama tidak sah." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Ekstensi tidak valid." #: platform/windows/export/export.cpp #, fuzzy @@ -25434,9 +25428,8 @@ msgid "Draw 2D Outlines" msgstr "Buat Garis Tepi" #: scene/main/scene_tree.cpp servers/visual_server.cpp -#, fuzzy msgid "Reflections" -msgstr "Arah" +msgstr "Refleksi" #: scene/main/scene_tree.cpp #, fuzzy @@ -26792,9 +26785,8 @@ msgstr "" #: scene/resources/environment.cpp #: servers/audio/effects/audio_effect_chorus.cpp -#, fuzzy msgid "2" -msgstr "2D" +msgstr "2" #: scene/resources/environment.cpp #: servers/audio/effects/audio_effect_chorus.cpp diff --git a/editor/translations/is.po b/editor/translations/is.po index b7eb0e4b88..512c660eef 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -2140,14 +2140,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2203,8 +2204,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2766,8 +2767,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Fjarlægja val" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5381,6 +5383,10 @@ msgid "Drag And Drop Selection" msgstr "Allt úrvalið" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11444,6 +11450,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Stillið breyting á:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19714,14 +19725,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19742,14 +19752,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/it.po b/editor/translations/it.po index 36757b891d..2c9f7eb6fe 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -69,13 +69,15 @@ # Federico Caprini <caprinifede@gmail.com>, 2022. # Alessandro Casalino <alessandro.casalino93@gmail.com>, 2022. # conecat <ilgrandemax190@gmail.com>, 2022. +# Gico2006 <gradaellig@protonmail.com>, 2022. +# ale piccia <picciatialessio2@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-04 05:16+0000\n" -"Last-Translator: conecat <ilgrandemax190@gmail.com>\n" +"PO-Revision-Date: 2022-07-31 18:34+0000\n" +"Last-Translator: Mirko <miknsop@gmail.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" "Language: it\n" @@ -83,7 +85,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -374,7 +376,6 @@ msgid "Not enough bytes for decoding bytes, or invalid format." msgstr "Byte insufficienti per decodificarli o formato non valido." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %d (not passed) in expression" msgstr "Input %d non valido (assente) nell'espressione" @@ -425,7 +426,7 @@ msgstr "Modalità Mouse" #: core/os/input.cpp msgid "Use Accumulated Input" -msgstr "Usa Input Accumulato" +msgstr "Usa Input Accumulati" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: servers/audio_server.cpp @@ -472,6 +473,7 @@ msgid "Physical Scancode" msgstr "Scancode Fisico" #: core/os/input_event.cpp +#, fuzzy msgid "Unicode" msgstr "Unicode" @@ -671,14 +673,12 @@ msgid "Always On Top" msgstr "Sempre In Primo Piano" #: core/project_settings.cpp -#, fuzzy msgid "Test Width" -msgstr "Larghezza Test" +msgstr "Test Larghezza" #: core/project_settings.cpp -#, fuzzy msgid "Test Height" -msgstr "Altezza Test" +msgstr "Test Altezza" #: core/project_settings.cpp editor/animation_track_editor.cpp #: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp @@ -713,14 +713,12 @@ msgid "Script Templates Search Path" msgstr "Percorso di Ricerca dei Template di Script" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Autoload On Startup" -msgstr "Autocaricamento all'Avvio" +msgstr "Caricamento automatico del controllo di versione all'avvio" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Plugin Name" -msgstr "Controllo della versione" +msgstr "Nome del plugin di controllo della versione" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp @@ -903,6 +901,7 @@ msgid "Modules" msgstr "Moduli" #: core/register_core_types.cpp +#, fuzzy msgid "TCP" msgstr "TCP" @@ -1210,14 +1209,12 @@ msgid "Type" msgstr "Tipo" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "Imposta Maniglia" +msgstr "In gestione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out Handle" -msgstr "Imposta Maniglia" +msgstr "Non gestire" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp @@ -1406,19 +1403,16 @@ msgid "Stream:" msgstr "Stream" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Start (s):" -msgstr "Riavvia (s):" +msgstr "inizia:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "End (s):" -msgstr "Fade In (s):" +msgstr "finisci:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation Clip:" -msgstr "Animazioni:" +msgstr "clip delle animazioni:" #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" @@ -2121,6 +2115,7 @@ msgid "Are you sure you want to remove all connections from the \"%s\" signal?" msgstr "Sei sicuro di voler rimuovere tutte le connessioni dal segnale \"%s\"?" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp +#, fuzzy msgid "Signals" msgstr "Segnali" @@ -2173,14 +2168,15 @@ msgstr "Preferiti:" msgid "Recent:" msgstr "Recenti:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cerca:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Corrispondenze:" @@ -2240,8 +2236,8 @@ msgstr "Cerca risorsa di rimpiazzo:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2250,7 +2246,7 @@ msgstr "Apri" #: editor/dependency_editor.cpp msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "proprietario di: %s (Totale: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2607,9 +2603,8 @@ msgid "There is no '%s' file." msgstr "File \"%s\" assente." #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Layout:" -msgstr "Disposizione" +msgstr "" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -2819,7 +2814,7 @@ msgstr "Esportazione del progetto per la piattaforma:" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Completato con errori." #: editor/editor_export.cpp @@ -2850,9 +2845,8 @@ msgid "Save PCK" msgstr "Salva PCK" #: editor/editor_export.cpp -#, fuzzy msgid "Cannot create file \"%s\"." -msgstr "Impossibile creare la cartella." +msgstr "impossibile creare il file \"%s\"." #: editor/editor_export.cpp #, fuzzy @@ -2860,9 +2854,8 @@ msgid "Failed to export project files." msgstr "Impossibile esportare i file del progetto" #: editor/editor_export.cpp -#, fuzzy msgid "Can't open file to read from path \"%s\"." -msgstr "Impossibile aprire il file in scrittura:" +msgstr "impossibile aprire file da leggere dalla path \"%s\"." #: editor/editor_export.cpp #, fuzzy @@ -5582,6 +5575,10 @@ msgid "Drag And Drop Selection" msgstr "Selezione GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Aspetto" @@ -7001,6 +6998,7 @@ msgstr "Anisotropico" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp +#, fuzzy msgid "sRGB" msgstr "sRGB" @@ -11739,6 +11737,11 @@ msgid "New Animation" msgstr "Nuova Animazione" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Modalità di filtraggio" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocità:" @@ -18021,7 +18024,6 @@ msgid "Expression" msgstr "Espressione" #: modules/visual_script/visual_script_flow_control.cpp -#, fuzzy msgid "Return" msgstr "Ritorno" @@ -18681,7 +18683,6 @@ msgid "Hand Tracking Frequency" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Passthrough" msgstr "Passthrough" @@ -20337,15 +20338,15 @@ msgstr "Non è stato possibile trovare keystore, impossible esportare." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Estensione non valida." #: platform/windows/export/export.cpp #, fuzzy @@ -20369,15 +20370,15 @@ msgstr "Nome non valido." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Estensione non valida." #: platform/windows/export/export.cpp #, fuzzy @@ -20925,9 +20926,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Fixed FPS" -msgstr "Vedi FPS" +msgstr "FPS fisso" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -26412,7 +26412,6 @@ msgid "Sky Contribution" msgstr "Condizione" #: scene/resources/environment.cpp -#, fuzzy msgid "Fog" msgstr "Nebbia" @@ -26759,7 +26758,7 @@ msgstr "" #: scene/resources/material.cpp msgid "Is sRGB" -msgstr "" +msgstr "È sRGB" #: scene/resources/material.cpp servers/visual_server.cpp #, fuzzy @@ -26877,9 +26876,8 @@ msgid "Flowmap" msgstr "" #: scene/resources/material.cpp -#, fuzzy msgid "Ambient Occlusion" -msgstr "Occlusione" +msgstr "Occlusione ambientale" #: scene/resources/material.cpp msgid "Deep Parallax" diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 5c6358a4c4..60458e89df 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -2180,14 +2180,15 @@ msgstr "お気に入り:" msgid "Recent:" msgstr "最近:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "検索:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "一致:" @@ -2247,8 +2248,8 @@ msgstr "置換するリソースを検索:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2821,7 +2822,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "ノードのパスをコピー" #: editor/editor_export.cpp @@ -5582,6 +5583,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap の選択" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "外観" @@ -11777,6 +11782,11 @@ msgid "New Animation" msgstr "新規アニメーション" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "メソッドを絞り込む" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "速度:" @@ -20452,15 +20462,15 @@ msgstr "キーストアが見つからないため、エクスポートできま #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "無効な実行可能ファイルです。" #: platform/windows/export/export.cpp #, fuzzy @@ -20484,15 +20494,15 @@ msgstr "無効な名前です。" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "無効な実行可能ファイルです。" #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/ka.po b/editor/translations/ka.po index f67e7c0bdd..2e6e0e70e7 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -2195,14 +2195,15 @@ msgstr "საყვარლები:" msgid "Recent:" msgstr "ბოლო:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "ძებნა:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "დამთხვევები:" @@ -2264,8 +2265,8 @@ msgstr "ჩამნაცვლებელი რესურსის ძი #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2846,8 +2847,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "მონიშვნის მოშორება" #: editor/editor_export.cpp #, fuzzy @@ -5510,6 +5512,10 @@ msgid "Drag And Drop Selection" msgstr "ყველა მონიშნვა" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11727,6 +11733,11 @@ msgid "New Animation" msgstr "ანიმაციის ოპტიმიზაცია" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ფუნქციები:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20184,15 +20195,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "არასწორი ფონტის ზომა." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20214,15 +20225,15 @@ msgstr "არასწორი ფონტის ზომა." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "არასწორი ფონტის ზომა." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/km.po b/editor/translations/km.po index 2da1ccac99..522cb30363 100644 --- a/editor/translations/km.po +++ b/editor/translations/km.po @@ -2071,14 +2071,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2134,8 +2135,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2694,8 +2695,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Anim ផ្លាស់ប្តូរ Transform" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5269,6 +5271,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11240,6 +11246,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Key(s) ដែលបានជ្រើសស្ទួន" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19308,14 +19319,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19337,14 +19347,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/ko.po b/editor/translations/ko.po index ff2f4ecb80..a91450dd41 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -2123,14 +2123,15 @@ msgstr "즐겨찾기:" msgid "Recent:" msgstr "최근 기록:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "검색:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "일치함:" @@ -2190,8 +2191,8 @@ msgstr "대체 리소스 검색:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2760,7 +2761,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "파일 경로 완성" #: editor/editor_export.cpp @@ -5482,6 +5483,10 @@ msgid "Drag And Drop Selection" msgstr "그리드맵 선택" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "모습" @@ -11681,6 +11686,11 @@ msgid "New Animation" msgstr "새 애니메이션" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "메서드 필터" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "속도:" @@ -20410,15 +20420,15 @@ msgstr "keystore를 찾을 수 없어, 내보낼 수 없었습니다." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "잘못된 확장자." #: platform/windows/export/export.cpp #, fuzzy @@ -20442,15 +20452,15 @@ msgstr "올바르지 않은 이름입니다." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "잘못된 확장자." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/lt.po b/editor/translations/lt.po index 8daa544db9..66891e3f0e 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -2178,14 +2178,15 @@ msgstr "Mėgstamiausi:" msgid "Recent:" msgstr "Naujausi:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Ieškoti:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2241,8 +2242,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2805,8 +2806,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Panaikinti pasirinkimą" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5487,6 +5489,10 @@ msgid "Drag And Drop Selection" msgstr "Visas Pasirinkimas" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11716,6 +11722,11 @@ msgid "New Animation" msgstr "Animacija" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrai..." + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20205,15 +20216,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Netinkamas šrifto dydis." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20235,15 +20246,15 @@ msgstr "Netinkamas šrifto dydis." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Netinkamas šrifto dydis." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/lv.po b/editor/translations/lv.po index 2dabcb40bf..c00e8d1a44 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -2173,14 +2173,15 @@ msgstr "Favorīti:" msgid "Recent:" msgstr "Nesenie:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Meklēt:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Sakritības:" @@ -2240,8 +2241,8 @@ msgstr "Meklēt aizstājēja resursu:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2818,7 +2819,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Kopēt mezgla ceļu" #: editor/editor_export.cpp @@ -5558,6 +5559,10 @@ msgid "Drag And Drop Selection" msgstr "Režģkartes izvēle" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11644,6 +11649,11 @@ msgid "New Animation" msgstr "Jauna animācija" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "animācija" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20012,15 +20022,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Nederīgs paplašinājums." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20042,15 +20052,15 @@ msgstr "Nederīgs nosaukums." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Nederīgs paplašinājums." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/mk.po b/editor/translations/mk.po index ef9a504af6..2d183ec609 100644 --- a/editor/translations/mk.po +++ b/editor/translations/mk.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-06-29 10:04+0000\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" "Last-Translator: Kristijan Fremen Velkovski <me@krisfremen.com>\n" "Language-Team: Macedonian <https://hosted.weblate.org/projects/godot-engine/" "godot/mk/>\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n==1 || n%10==1 ? 0 : 1;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -1255,7 +1255,7 @@ msgstr "" #: editor/animation_track_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Functions:" -msgstr "" +msgstr "Фукнции:" #: editor/animation_track_editor.cpp msgid "Audio Clips:" @@ -1358,33 +1358,33 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Continuous" -msgstr "" +msgstr "Континуирана" #: editor/animation_track_editor.cpp msgid "Discrete" -msgstr "" +msgstr "Дискретна" #: editor/animation_track_editor.cpp msgid "Trigger" -msgstr "" +msgstr "Чкрапало" #: editor/animation_track_editor.cpp scene/3d/baked_lightmap.cpp msgid "Capture" -msgstr "" +msgstr "Снимање" #: editor/animation_track_editor.cpp msgid "Nearest" -msgstr "" +msgstr "Најблиску" #: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp #: editor/property_editor.cpp scene/2d/physics_body_2d.cpp #: scene/3d/physics_body.cpp msgid "Linear" -msgstr "" +msgstr "Линеарна" #: editor/animation_track_editor.cpp msgid "Cubic" -msgstr "" +msgstr "Кубни" #: editor/animation_track_editor.cpp msgid "Clamp Loop Interp" @@ -1462,7 +1462,7 @@ msgstr "" #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Create" -msgstr "" +msgstr "Создади" #: editor/animation_track_editor.cpp msgid "Anim Insert" @@ -1763,7 +1763,7 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Clean-Up" -msgstr "" +msgstr "Очисти" #: editor/animation_track_editor.cpp msgid "Scale Ratio:" @@ -1840,7 +1840,7 @@ msgstr "" #: editor/code_editor.cpp msgid "Replace" -msgstr "" +msgstr "Замени" #: editor/code_editor.cpp msgid "Replace All" @@ -1853,7 +1853,7 @@ msgstr "" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Стандардно" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" @@ -1879,7 +1879,7 @@ msgstr "" #: editor/code_editor.cpp modules/gdscript/gdscript.cpp msgid "Warnings" -msgstr "" +msgstr "Предупредувања" #: editor/code_editor.cpp msgid "Line and column numbers." @@ -1921,7 +1921,7 @@ msgstr "" #: editor/plugins/item_list_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp msgid "Add" -msgstr "" +msgstr "Додади" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp @@ -1931,7 +1931,7 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" -msgstr "" +msgstr "Избриши" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" @@ -1948,11 +1948,11 @@ msgstr "" #: editor/connections_dialog.cpp scene/3d/room_manager.cpp #: servers/visual_server.cpp msgid "Advanced" -msgstr "" +msgstr "Напредно" #: editor/connections_dialog.cpp msgid "Deferred" -msgstr "" +msgstr "Одложено" #: editor/connections_dialog.cpp msgid "" @@ -2080,14 +2080,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2143,8 +2144,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2703,7 +2704,7 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "" #: editor/editor_export.cpp @@ -5286,6 +5287,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11268,6 +11273,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Својства на анимацијата." + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19353,14 +19363,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19382,14 +19391,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/ml.po b/editor/translations/ml.po index 1b5bc9e68f..7568bc881e 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -2090,14 +2090,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2153,8 +2154,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2714,8 +2715,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "ചലനം ചുറ്റൽ" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5302,6 +5304,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11290,6 +11296,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ചലനം ചുറ്റൽ" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19392,14 +19403,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19421,14 +19431,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/mr.po b/editor/translations/mr.po index 8dffed5d4e..4bdf5ba4fb 100644 --- a/editor/translations/mr.po +++ b/editor/translations/mr.po @@ -2091,14 +2091,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2154,8 +2155,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2714,8 +2715,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "अॅनिमेशन ट्री" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5292,6 +5294,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11278,6 +11284,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "अॅनिमेशन ट्री" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19393,14 +19404,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19422,14 +19432,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/ms.po b/editor/translations/ms.po index caef354c6c..61a60ad8fe 100644 --- a/editor/translations/ms.po +++ b/editor/translations/ms.po @@ -2101,14 +2101,15 @@ msgstr "Kegemaran:" msgid "Recent:" msgstr "Terkini:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cari:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Padanan:" @@ -2168,8 +2169,8 @@ msgstr "Cari Penggantian Sumber:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2744,8 +2745,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Salin Pilihan" #: editor/editor_export.cpp #, fuzzy @@ -5551,6 +5553,10 @@ msgid "Drag And Drop Selection" msgstr "Semua Pilihan" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11733,6 +11739,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Padam Animasi?" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20216,15 +20227,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Nama kumpulan tidak sah." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20246,15 +20257,15 @@ msgstr "Nama tidak sah." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Nama kumpulan tidak sah." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 68de0259c2..542d5987ca 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -2205,14 +2205,15 @@ msgstr "Favoritter:" msgid "Recent:" msgstr "Nylige:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Søk:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Treff:" @@ -2274,8 +2275,8 @@ msgstr "Søk Erstatningsressurs:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2875,7 +2876,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Kopier Node-bane" #: editor/editor_export.cpp @@ -5735,6 +5736,10 @@ msgid "Drag And Drop Selection" msgstr "Slett Valgte" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12215,6 +12220,11 @@ msgstr "Animasjon" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy +msgid "Filter animations" +msgstr "Lim inn Noder" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Speed:" msgstr "Hastighet (FPS):" @@ -21039,15 +21049,15 @@ msgstr "Kunne ikke opprette mappe." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Må ha en gyldig filutvidelse." #: platform/windows/export/export.cpp #, fuzzy @@ -21071,15 +21081,15 @@ msgstr "Ugyldig navn." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Må ha en gyldig filutvidelse." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/nl.po b/editor/translations/nl.po index 756bf78add..aaa0f38a1d 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -2270,14 +2270,15 @@ msgstr "Favorieten:" msgid "Recent:" msgstr "Onlangs:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Zoeken:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Overeenkomsten:" @@ -2337,8 +2338,8 @@ msgstr "Bronvervanging zoeken:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2915,7 +2916,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Knooppad kopiëren" #: editor/editor_export.cpp @@ -5728,6 +5729,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap-selectie vullen" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12068,6 +12073,11 @@ msgid "New Animation" msgstr "Nieuwe animatie" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filter methoden" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Snelheid:" @@ -20926,15 +20936,15 @@ msgstr "Kon template niet openen voor export:" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Ongeldige extentie." #: platform/windows/export/export.cpp #, fuzzy @@ -20958,15 +20968,15 @@ msgstr "Ongeldige naam." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Ongeldige extentie." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/pl.po b/editor/translations/pl.po index 264d623676..3e4664c317 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -62,13 +62,14 @@ # Pixel Zone - Godot Engine Tutorials <karoltomaszewskimusic@gmail.com>, 2022. # DK0492 <doriankaczmarek28@gmail.com>, 2022. # Dawid Skubij <davidsd@tlen.pl>, 2022. +# kingofsponges <q.patex.q@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-10 14:38+0000\n" -"Last-Translator: Dawid Skubij <davidsd@tlen.pl>\n" +"PO-Revision-Date: 2022-08-04 06:38+0000\n" +"Last-Translator: kingofsponges <q.patex.q@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" "Language: pl\n" @@ -77,7 +78,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -338,7 +339,7 @@ msgstr "Członek transmisji" #: core/io/stream_peer.cpp msgid "Big Endian" -msgstr "" +msgstr "Big endian" #: core/io/stream_peer.cpp msgid "Data Array" @@ -368,9 +369,8 @@ msgid "Not enough bytes for decoding bytes, or invalid format." msgstr "Niewystarczająca ilość bajtów dla bajtów dekodujących lub zły format." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %d (not passed) in expression" -msgstr "Niewłaściwe dane %i (nie przekazane) w wyrażeniu" +msgstr "Niewłaściwe dane %d (nie przekazane) w wyrażeniu" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -415,14 +415,12 @@ msgid "Max Size (KB)" msgstr "Maks. rozmiar (KB)" #: core/os/input.cpp -#, fuzzy msgid "Mouse Mode" -msgstr "Tryb przesuwania" +msgstr "Tryb myszki" #: core/os/input.cpp -#, fuzzy msgid "Use Accumulated Input" -msgstr "Usuń Wejście" +msgstr "Użyj skumulowanego wejścia" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: servers/audio_server.cpp @@ -501,15 +499,15 @@ msgstr "Pochylenie" #: core/os/input_event.cpp msgid "Pressure" -msgstr "Ciśnienie" +msgstr "Nacisk" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Odwrócone pióro" #: core/os/input_event.cpp msgid "Relative" -msgstr "Relatywny" +msgstr "Względny" #: core/os/input_event.cpp scene/2d/camera_2d.cpp scene/2d/cpu_particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/interpolated_camera.cpp @@ -644,9 +642,8 @@ msgstr "Własna nazwa katalogu użytkownika" #: core/project_settings.cpp main/main.cpp #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #: platform/uwp/os_uwp.cpp -#, fuzzy msgid "Display" -msgstr "Pokaż wszystko" +msgstr "Wyświetlanie" #: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp #: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp @@ -660,23 +657,20 @@ msgstr "Szerokość" #: scene/resources/capsule_shape_2d.cpp scene/resources/cylinder_shape.cpp #: scene/resources/font.cpp scene/resources/navigation_mesh.cpp #: scene/resources/primitive_meshes.cpp scene/resources/texture.cpp -#, fuzzy msgid "Height" -msgstr "Światło" +msgstr "Wysokość" #: core/project_settings.cpp msgid "Always On Top" msgstr "Zawsze na wierzchu" #: core/project_settings.cpp -#, fuzzy msgid "Test Width" -msgstr "Rozciągnij po lewej" +msgstr "Szerokość testowa" #: core/project_settings.cpp -#, fuzzy msgid "Test Height" -msgstr "Testowanie" +msgstr "Wysokość testowa" #: core/project_settings.cpp editor/animation_track_editor.cpp #: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp @@ -699,9 +693,8 @@ msgid "Main Run Args" msgstr "Główne argumenty włączania" #: core/project_settings.cpp -#, fuzzy msgid "Scene Naming" -msgstr "Ścieżka sceny:" +msgstr "Nazywanie scen" #: core/project_settings.cpp msgid "Search In File Extensions" @@ -712,14 +705,12 @@ msgid "Script Templates Search Path" msgstr "Ścieżka wyszukiwania szablonów skryptów" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Autoload On Startup" -msgstr "Automatyczne ładowanie podczas uruchamiania" +msgstr "Automatyczne ładowanie kontroli wersji podczas uruchamiania" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Plugin Name" -msgstr "Kontrola wersji" +msgstr "Nazwa wtyczki kontroli wersji" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp @@ -1204,7 +1195,7 @@ msgstr "Ilośc:" #: editor/animation_track_editor.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp msgid "Args" -msgstr "" +msgstr "Argumenty" #: editor/animation_track_editor.cpp editor/editor_settings.cpp #: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp @@ -1228,7 +1219,7 @@ msgstr "Ustaw uchwyt" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp msgid "Stream" -msgstr "" +msgstr "Strumień" #: editor/animation_track_editor.cpp #, fuzzy @@ -2176,14 +2167,15 @@ msgstr "Ulubione:" msgid "Recent:" msgstr "Ostatnie:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Szukaj:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Pasujące:" @@ -2243,8 +2235,8 @@ msgstr "Szukaj zastępczego zasobu:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2253,7 +2245,7 @@ msgstr "Otwórz" #: editor/dependency_editor.cpp msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "Właściciele: %s (Suma: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2813,11 +2805,11 @@ msgstr "Wybierz" #: editor/editor_export.cpp msgid "Project export for platform:" -msgstr "" +msgstr "Eksportowanie projektu dla platformy:" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Skopiuj ścieżkę węzła" #: editor/editor_export.cpp @@ -2843,14 +2835,12 @@ msgid "Packing" msgstr "Pakowanie" #: editor/editor_export.cpp -#, fuzzy msgid "Save PCK" -msgstr "Zapisz jako" +msgstr "Zapisz plik PCK" #: editor/editor_export.cpp -#, fuzzy msgid "Cannot create file \"%s\"." -msgstr "Nie można utworzyć katalogu." +msgstr "Nie można utworzyć pliku \"%s\"." #: editor/editor_export.cpp #, fuzzy @@ -5629,6 +5619,10 @@ msgid "Drag And Drop Selection" msgstr "Wybór GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Wygląd" @@ -11902,6 +11896,11 @@ msgid "New Animation" msgstr "Nowa animacja" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtruj metody" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Szybkość:" @@ -20688,17 +20687,17 @@ msgstr "Nie udało się znaleźć keystore, nie można eksportować." #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" "Narzędzie rcedit musi być skonfigurowane w Ustawieniach edytora (Eksport > " "Windows > Rcedit), aby zmienić ikonę lub dane informacji o aplikacji." #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Niepoprawny plik wykonywalny." #: platform/windows/export/export.cpp #, fuzzy @@ -20723,17 +20722,17 @@ msgstr "Niewłaściwa nazwa." #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" "Narzędzie rcedit musi być skonfigurowane w Ustawieniach edytora (Eksport > " "Windows > Rcedit), aby zmienić ikonę lub dane informacji o aplikacji." #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Niepoprawny plik wykonywalny." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/pr.po b/editor/translations/pr.po index 5c33524652..4c073f8542 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -2165,14 +2165,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2228,8 +2229,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2798,7 +2799,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Forge yer Node!" #: editor/editor_export.cpp @@ -5474,6 +5475,10 @@ msgid "Drag And Drop Selection" msgstr "Yar, Blow th' Selected Down!" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11705,6 +11710,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Paste yer Node" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20253,15 +20263,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Yer Calligraphy be wrongly sized." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20283,15 +20293,15 @@ msgstr "Yer Calligraphy be wrongly sized." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Yer Calligraphy be wrongly sized." #: platform/windows/export/export.cpp msgid "Failed to remove temporary file \"%s\"." diff --git a/editor/translations/pt.po b/editor/translations/pt.po index 0b2fa35ae5..f284e0ece8 100644 --- a/editor/translations/pt.po +++ b/editor/translations/pt.po @@ -25,13 +25,14 @@ # El_ExpertPlayer <xpertnathan37@gmail.com>, 2022. # Esdras Caleb Oliveira Silva <acheicaleb@gmail.com>, 2022. # Ednaldo Pereira Confia <filat51823@storypo.com>, 2022. +# Zé Beato Página Oficial <zebeato@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-11 21:32+0000\n" -"Last-Translator: Ednaldo Pereira Confia <filat51823@storypo.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: Zé Beato Página Oficial <zebeato@gmail.com>\n" "Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/" "godot/pt/>\n" "Language: pt\n" @@ -2109,14 +2110,15 @@ msgstr "Favoritos:" msgid "Recent:" msgstr "Recente:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Procurar:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Correspondências:" @@ -2176,8 +2178,8 @@ msgstr "Procurar Recurso de substituição:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2752,7 +2754,8 @@ msgid "Project export for platform:" msgstr "Exportação do projeto para plataforma:" #: editor/editor_export.cpp -msgid "Completed with errors." +#, fuzzy +msgid "Completed with warnings." msgstr "Concluído com erros." #: editor/editor_export.cpp @@ -2931,9 +2934,8 @@ msgid "The given export path doesn't exist." msgstr "O caminho de exportação não existe:" #: editor/editor_export.cpp platform/javascript/export/export.cpp -#, fuzzy msgid "Template file not found: \"%s\"." -msgstr "Ficheiro Modelo não encontrado:" +msgstr "Ficheiro Modelo não encontrado" #: editor/editor_export.cpp #, fuzzy @@ -5538,6 +5540,10 @@ msgid "Drag And Drop Selection" msgstr "Seleção de GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Aparência" @@ -11721,6 +11727,11 @@ msgid "New Animation" msgstr "Nova Animação" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Métodos de filtro" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocidade:" @@ -20398,15 +20409,15 @@ msgstr "Incapaz de encontrar keystore e exportar." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Extensão inválida." #: platform/windows/export/export.cpp #, fuzzy @@ -20430,15 +20441,15 @@ msgstr "Nome inválido." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Extensão inválida." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index a812335e4b..84a5ac45c3 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -142,13 +142,15 @@ # lucas rossy brasil coelho <lucasrossy270@gmail.com>, 2022. # Kaycke <kaycke@ymail.com>, 2022. # Ednaldo Pereira Confia <filat51823@storypo.com>, 2022. +# Mauricio <mauricio.fidalgo1@gmail.com>, 2022. +# Felipe Kinoshita <kinofhek@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2022-07-16 06:20+0000\n" -"Last-Translator: Cearaj <pmoraisleal@gmail.com>\n" +"PO-Revision-Date: 2022-08-04 06:38+0000\n" +"Last-Translator: Felipe Kinoshita <kinofhek@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_BR/>\n" "Language: pt_BR\n" @@ -361,7 +363,7 @@ msgstr "Página lida adiante" #: core/io/http_client.cpp msgid "Blocking Mode Enabled" -msgstr "Modo de bloqueio ativado" +msgstr "Modo de Bloqueio Ativado" #: core/io/http_client.cpp msgid "Connection" @@ -579,9 +581,8 @@ msgid "Pressure" msgstr "Pressão" #: core/os/input_event.cpp -#, fuzzy msgid "Pen Inverted" -msgstr "Inverter" +msgstr "Caneta Invertida (\"Borracha\")" #: core/os/input_event.cpp msgid "Relative" @@ -1120,7 +1121,7 @@ msgstr "Máximo de luzes renderizáveis" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Reflections" -msgstr "Reflexões máximas renderizáveis" +msgstr "Máximo de Reflexões Renderizáveis" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Lights Per Object" @@ -1278,14 +1279,12 @@ msgid "Type" msgstr "Tipo" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "Definir Manipulador" +msgstr "Manipulador de Entrada" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out Handle" -msgstr "Definir Manipulador" +msgstr "Manipulador de Saída" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp @@ -1296,11 +1295,11 @@ msgstr "Fluxo" #: editor/animation_track_editor.cpp msgid "Start Offset" -msgstr "Iniciar deslocamento" +msgstr "Deslocamento Inicial" #: editor/animation_track_editor.cpp msgid "End Offset" -msgstr "Terminar deslocamento" +msgstr "Deslocamento Final" #: editor/animation_track_editor.cpp editor/editor_settings.cpp #: editor/import/resource_importer_scene.cpp @@ -1314,7 +1313,7 @@ msgstr "Animação" #: editor/animation_track_editor.cpp msgid "Easing" -msgstr "Facilitar Entrada-Saída" +msgstr "Suavização" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -1453,18 +1452,16 @@ msgid "(Invalid, expected type: %s)" msgstr "(Inválido, tipo esperado: %s)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Easing:" -msgstr "Facilitar Entrada-Saída:" +msgstr "Suavizar:" #: editor/animation_track_editor.cpp msgid "In-Handle:" -msgstr "Definir Manipulador:" +msgstr "Manipulador de Entrada:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out-Handle:" -msgstr "Definir Manipulador:" +msgstr "Manipulador de Saída:" #: editor/animation_track_editor.cpp msgid "Stream:" @@ -2110,7 +2107,7 @@ msgstr "" #: editor/connections_dialog.cpp scene/resources/texture.cpp msgid "Oneshot" -msgstr "Oneshot" +msgstr "Só Uma Vez" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." @@ -2229,14 +2226,15 @@ msgstr "Favoritos:" msgid "Recent:" msgstr "Recente:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Pesquisar:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Correspondências:" @@ -2296,8 +2294,8 @@ msgstr "Buscar Recurso para Substituição:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2420,7 +2418,7 @@ msgstr "Desenvolvedor-chefe" #: editor/editor_about.cpp msgctxt "Job Title" msgid "Project Manager" -msgstr "Gerenciador de Projeto" +msgstr "Gestor de Projeto" #: editor/editor_about.cpp msgid "Developers" @@ -2870,7 +2868,8 @@ msgid "Project export for platform:" msgstr "Exportação do projeto para plataforma:" #: editor/editor_export.cpp -msgid "Completed with errors." +#, fuzzy +msgid "Completed with warnings." msgstr "Concluído com erros." #: editor/editor_export.cpp @@ -2993,7 +2992,7 @@ msgstr "64 Bits" #: editor/editor_export.cpp msgid "Embed PCK" -msgstr "Incorporar PCK" +msgstr "PCK Incorporado" #: editor/editor_export.cpp platform/osx/export/export.cpp msgid "Texture Format" @@ -3016,9 +3015,8 @@ msgid "ETC2" msgstr "ETC2" #: editor/editor_export.cpp -#, fuzzy msgid "No BPTC Fallbacks" -msgstr "Sem Fallbacks do BPTC" +msgstr "Sem Fallbacks para imagens BPTC" #: editor/editor_export.cpp platform/android/export/export_plugin.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -3673,9 +3671,8 @@ msgid "Property:" msgstr "Propriedade:" #: editor/editor_inspector.cpp editor/editor_spin_slider.cpp -#, fuzzy msgid "Label" -msgstr "Etiqueta" +msgstr "Rótulo" #: editor/editor_inspector.cpp editor/editor_spin_slider.cpp #: scene/resources/default_theme/default_theme.cpp @@ -4391,11 +4388,11 @@ msgstr "Abas de Cena" #: editor/editor_node.cpp msgid "Always Show Close Button" -msgstr "Sempre mostrar o botão de fechar." +msgstr "Sempre Exibir o Botão de Fechar" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Resize If Many Tabs" -msgstr "Redimensionar se houver muitas guias" +msgstr "Redimensionar se Houver Muitas Guias" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Minimum Width" @@ -5102,7 +5099,7 @@ msgstr "Tempo Médio (ms)" #: editor/editor_profiler.cpp msgid "Frame %" -msgstr "Frame %" +msgstr "Quadro %" #: editor/editor_profiler.cpp msgid "Physics Frame %" @@ -5147,12 +5144,11 @@ msgstr "Depurador" #: editor/editor_profiler.cpp msgid "Profiler Frame History Size" -msgstr "" +msgstr "Tamanho de histórico disponível no \"Profiler\"" #: editor/editor_profiler.cpp -#, fuzzy msgid "Profiler Frame Max Functions" -msgstr "Renomear Função" +msgstr "Máximo de funções por quadro no \"Profiler\"" #: editor/editor_properties.cpp msgid "Edit Text:" @@ -5285,20 +5281,17 @@ msgstr "Novo %s" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_yield_nodes.cpp -#, fuzzy msgid "Base Type" -msgstr "Mudar Tipo Base" +msgstr "Tipo Base" #: editor/editor_resource_picker.cpp -#, fuzzy msgid "Edited Resource" -msgstr "Adicionar Recurso" +msgstr "Recurso Editado" #: editor/editor_resource_picker.cpp scene/gui/line_edit.cpp #: scene/gui/slider.cpp scene/gui/spin_box.cpp -#, fuzzy msgid "Editable" -msgstr "Item Editável" +msgstr "Editável" #: editor/editor_resource_picker.cpp editor/property_editor.cpp msgid "New Script" @@ -5324,9 +5317,8 @@ msgstr "" "predefinição existente como executável." #: editor/editor_run_native.cpp -#, fuzzy msgid "Project Run" -msgstr "Projeto" +msgstr "Executar Projeto" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." @@ -5353,73 +5345,68 @@ msgid "Did you forget the '_run' method?" msgstr "Você esqueceu o método '_run'?" #: editor/editor_settings.cpp -#, fuzzy msgid "Editor Language" -msgstr "Layout do Editor" +msgstr "Linguagem do Editor" #: editor/editor_settings.cpp -#, fuzzy msgid "Display Scale" -msgstr "Exibir Tudo" +msgstr "Escala de Exibição" #: editor/editor_settings.cpp msgid "Custom Display Scale" -msgstr "" +msgstr "Escala de Exibição Customizada" #: editor/editor_settings.cpp msgid "Main Font Size" -msgstr "" +msgstr "Tamanho de Fonte Principal" #: editor/editor_settings.cpp msgid "Code Font Size" -msgstr "" +msgstr "Tamanho de Fonte (Tipo) no Código" #: editor/editor_settings.cpp msgid "Font Antialiased" -msgstr "" +msgstr "Fonte Com Serrilhado Suavizado" #: editor/editor_settings.cpp msgid "Font Hinting" -msgstr "" +msgstr "Suavização de Fonte" #: editor/editor_settings.cpp -#, fuzzy msgid "Main Font" -msgstr "Cena Principal" +msgstr "Fonte Principal" #: editor/editor_settings.cpp msgid "Main Font Bold" -msgstr "" +msgstr "Fonte Principal (Negrito)" #: editor/editor_settings.cpp -#, fuzzy msgid "Code Font" -msgstr "Adicionar Ponto de Nó" +msgstr "Fonte para Código" #: editor/editor_settings.cpp msgid "Dim Editor On Dialog Popup" -msgstr "" +msgstr "Escurecer o Editor ao Abir Janela Popup" #: editor/editor_settings.cpp main/main.cpp msgid "Low Processor Mode Sleep (µsec)" -msgstr "" +msgstr "Tempo de Espera em Modo de Hibernação (µseg)" #: editor/editor_settings.cpp msgid "Unfocused Low Processor Mode Sleep (µsec)" -msgstr "" +msgstr "Tempo de Espera em Modo de Hibernação Quando Fora de Foco (µseg)" #: editor/editor_settings.cpp -#, fuzzy msgid "Separate Distraction Mode" -msgstr "Modo Sem Distrações" +msgstr "Modo \"Sem Distrações\" Desacoplado" #: editor/editor_settings.cpp msgid "Automatically Open Screenshots" -msgstr "" +msgstr "Abrir Capturas de Tela Automaticamente" #: editor/editor_settings.cpp msgid "Max Array Dictionary Items Per Page" -msgstr "" +msgstr "Máximo de Itens em Arrays Dicionários Por Página" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp scene/gui/control.cpp @@ -5433,59 +5420,51 @@ msgstr "Predefinição" #: editor/editor_settings.cpp msgid "Icon And Font Color" -msgstr "" +msgstr "Cor da Fonte e do Ícone" #: editor/editor_settings.cpp -#, fuzzy msgid "Base Color" -msgstr "Cores" +msgstr "Cor Base" #: editor/editor_settings.cpp -#, fuzzy msgid "Accent Color" -msgstr "Escolher Cor" +msgstr "Cor de Destaque" #: editor/editor_settings.cpp scene/resources/environment.cpp msgid "Contrast" -msgstr "" +msgstr "Contraste" #: editor/editor_settings.cpp msgid "Relationship Line Opacity" -msgstr "" +msgstr "Opacidade da Linha de Relacionamento" #: editor/editor_settings.cpp -#, fuzzy msgid "Highlight Tabs" -msgstr "Salvando mapas de luz" +msgstr "Abas de Destaque" #: editor/editor_settings.cpp -#, fuzzy msgid "Border Size" -msgstr "Pixels de Borda" +msgstr "Tamanho da Borda" #: editor/editor_settings.cpp msgid "Use Graph Node Headers" -msgstr "" +msgstr "Utilizar Cabeçalhos de Nós para Gráficos" #: editor/editor_settings.cpp -#, fuzzy msgid "Additional Spacing" -msgstr "Loop da Animação" +msgstr "Espaçamento Adicional" #: editor/editor_settings.cpp -#, fuzzy msgid "Custom Theme" -msgstr "Tema do Editor" +msgstr "Tema Personalizado" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Script Button" -msgstr "Botão direito da roda" +msgstr "Botão de Exibir Script" #: editor/editor_settings.cpp -#, fuzzy msgid "Directories" -msgstr "Direções" +msgstr "Diretórios" #: editor/editor_settings.cpp msgid "Autoscan Project Path" @@ -5496,23 +5475,20 @@ msgid "Default Project Path" msgstr "Caminho Padrão do Projeto" #: editor/editor_settings.cpp -#, fuzzy msgid "On Save" -msgstr "Salvar" +msgstr "Ao Salvar" #: editor/editor_settings.cpp -#, fuzzy msgid "Compress Binary Resources" -msgstr "Copiar Recurso" +msgstr "Comprimir Recursos Binários" #: editor/editor_settings.cpp msgid "Safe Save On Backup Then Rename" -msgstr "" +msgstr "Salvar de Forma Segura Como Backup e Então Renomear" #: editor/editor_settings.cpp -#, fuzzy msgid "File Dialog" -msgstr "Diálogo XForm" +msgstr "Janela de Arquivo" #: editor/editor_settings.cpp msgid "Thumbnail Size" @@ -5520,82 +5496,73 @@ msgstr "Tamanho da Miniatura" #: editor/editor_settings.cpp msgid "Docks" -msgstr "" +msgstr "Docks" #: editor/editor_settings.cpp -#, fuzzy msgid "Scene Tree" -msgstr "Edição da Árvore de Cena" +msgstr "Árvore de Cena" #: editor/editor_settings.cpp msgid "Start Create Dialog Fully Expanded" -msgstr "" +msgstr "Iniciar Dialogo de Criação Expandido por Completo" #: editor/editor_settings.cpp -#, fuzzy msgid "Always Show Folders" -msgstr "Sempre Mostrar Grade" +msgstr "Sempre Exibir Pastas" #: editor/editor_settings.cpp -#, fuzzy msgid "Property Editor" -msgstr "Editor de Grupos" +msgstr "Editor de Propriedades" #: editor/editor_settings.cpp msgid "Auto Refresh Interval" -msgstr "" +msgstr "Intervalo de Atualização Automática" #: editor/editor_settings.cpp -#, fuzzy msgid "Subresource Hue Tint" -msgstr "Sub-Recursos" +msgstr "Tom de Coloração para Sub-Recursos" #: editor/editor_settings.cpp -#, fuzzy msgid "Color Theme" -msgstr "Tema do Editor" +msgstr "Tema de Cores" #: editor/editor_settings.cpp scene/3d/label_3d.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Line Spacing" -msgstr "" +msgstr "Espaçamento de Linha" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp #: modules/gdscript/editor/gdscript_highlighter.cpp -#, fuzzy msgid "Highlighting" -msgstr "Iluminação direta" +msgstr "Destacando" #: editor/editor_settings.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Syntax Highlighting" -msgstr "Realce de sintaxe" +msgstr "Destaque de Sintaxe" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Highlight All Occurrences" -msgstr "" +msgstr "Destaque de Todas as Ocorrências" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Highlight Current Line" -msgstr "" +msgstr "Destaque da Linha Atual" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp msgid "Highlight Type Safe Lines" -msgstr "" +msgstr "Destaque de Linhas de Tipo Seguro" #: editor/editor_settings.cpp -#, fuzzy msgid "Indent" -msgstr "Recuar Esquerda" +msgstr "Indentar" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp msgid "Auto Indent" msgstr "Auto Recuar" #: editor/editor_settings.cpp -#, fuzzy msgid "Convert Indent On Save" -msgstr "Converter recuo para espaços" +msgstr "Converter Indentação Ao Salvar" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Draw Tabs" @@ -5614,144 +5581,139 @@ msgstr "Navegação" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Smooth Scrolling" -msgstr "" +msgstr "Rolagem Suave" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "V Scroll Speed" -msgstr "" +msgstr "Velocidade de Rolagem Vertical" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Minimap" -msgstr "Mostrar Origem" +msgstr "Exibir Mini-Mapa" #: editor/editor_settings.cpp msgid "Minimap Width" -msgstr "" +msgstr "Largura do Mini-Mapa" #: editor/editor_settings.cpp msgid "Mouse Extra Buttons Navigate History" -msgstr "" +msgstr "Botões Extra do Mouse Navegam o Histórico" #: editor/editor_settings.cpp -#, fuzzy msgid "Drag And Drop Selection" -msgstr "Seleção Do GridMap" +msgstr "Seleção Arrasta e Solta" #: editor/editor_settings.cpp -msgid "Appearance" +msgid "Stay In Script Editor On Node Selected" msgstr "" +#: editor/editor_settings.cpp +msgid "Appearance" +msgstr "Aparência" + #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Show Line Numbers" msgstr "Mostrar Números de Linha" #: editor/editor_settings.cpp -#, fuzzy msgid "Line Numbers Zero Padded" -msgstr "Número da Linha:" +msgstr "Número das Linha Tem Espaçamento Com Zeros" #: editor/editor_settings.cpp msgid "Show Bookmark Gutter" -msgstr "" +msgstr "Exibir Espaçamento de Bookmark" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Breakpoint Gutter" -msgstr "Pular Breakpoints" +msgstr "Exibir Espaçamento de Pontos de Quebra" #: editor/editor_settings.cpp msgid "Show Info Gutter" -msgstr "" +msgstr "Exibir Espaçamento de Informações" #: editor/editor_settings.cpp msgid "Code Folding" -msgstr "" +msgstr "Dobramento de Código (Folding)" #: editor/editor_settings.cpp msgid "Word Wrap" -msgstr "" +msgstr "Quebra de Linhas" #: editor/editor_settings.cpp msgid "Show Line Length Guidelines" -msgstr "" +msgstr "Exibir Guia de Tamanho de Linhas" #: editor/editor_settings.cpp msgid "Line Length Guideline Soft Column" -msgstr "" +msgstr "Tamanho de Linha Guia em Coluna Suave" #: editor/editor_settings.cpp msgid "Line Length Guideline Hard Column" -msgstr "" +msgstr "Tamanho de Linha Guia em Coluna Rígida" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Script List" -msgstr "Editor de Script" +msgstr "Lista de Scripts" #: editor/editor_settings.cpp msgid "Show Members Overview" -msgstr "" +msgstr "Exibir Visão Geral de Membros" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Files" -msgstr "Arquivo" +msgstr "Arquivos" #: editor/editor_settings.cpp -#, fuzzy msgid "Trim Trailing Whitespace On Save" -msgstr "Apagar Espaços em Branco" +msgstr "Aparar Espaços em Branco de Fim de Linha ao Salvar" #: editor/editor_settings.cpp msgid "Autosave Interval Secs" -msgstr "" +msgstr "Intervalo de Salvamento Automático em Segundos" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp msgid "Restore Scripts On Load" -msgstr "" +msgstr "Restaurar Scripts ao Carregar" #: editor/editor_settings.cpp msgid "Auto Reload And Parse Scripts On Save" -msgstr "" +msgstr "Ao Salvar Recarregar e Reinterpretar Scripts Automaticamente" #: editor/editor_settings.cpp msgid "Auto Reload Scripts On External Change" -msgstr "" +msgstr "Recarregar Scripts Automaticamente em Alterações Externas" #: editor/editor_settings.cpp -#, fuzzy msgid "Create Signal Callbacks" -msgstr "Forçar Fallbacks do Shader" +msgstr "Criar Sinal de Callback" #: editor/editor_settings.cpp msgid "Sort Members Outline Alphabetically" -msgstr "" +msgstr "Ordenar Prévia de Membros Automaticamente" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Cursor" -msgstr "" +msgstr "Cursor" #: editor/editor_settings.cpp msgid "Scroll Past End Of File" -msgstr "" +msgstr "Rolar Além do Fim do Arquivo" #: editor/editor_settings.cpp msgid "Block Caret" -msgstr "" +msgstr "Bloco Cursor" #: editor/editor_settings.cpp msgid "Caret Blink" -msgstr "" +msgstr "Piscar Cursor" #: editor/editor_settings.cpp msgid "Caret Blink Speed" -msgstr "" +msgstr "Velocidade de Piscar do Cursor" #: editor/editor_settings.cpp -#, fuzzy msgid "Right Click Moves Caret" -msgstr "Clique com o botão direito para adicionar o ponto" +msgstr "Botão Direito Move o Cursor" #: editor/editor_settings.cpp modules/gdscript/gdscript.cpp #: modules/gdscript/gdscript_editor.cpp @@ -5761,54 +5723,51 @@ msgstr "Conclusão" #: editor/editor_settings.cpp msgid "Idle Parse Delay" -msgstr "" +msgstr "Atraso Ocioso Para Interpretação" #: editor/editor_settings.cpp msgid "Auto Brace Complete" -msgstr "" +msgstr "Fechar Chaves Automaticamente" #: editor/editor_settings.cpp msgid "Code Complete Delay" -msgstr "" +msgstr "Atraso de Sugestão de Código" #: editor/editor_settings.cpp msgid "Put Callhint Tooltip Below Current Line" -msgstr "" +msgstr "Pôr Dica de Sugestão de Chamada na Linha Abaixo da Atual" #: editor/editor_settings.cpp msgid "Callhint Tooltip Offset" -msgstr "" +msgstr "Espaçamento de Dica de Sugestão de Chamada" #: editor/editor_settings.cpp -#, fuzzy msgid "Complete File Paths" -msgstr "Copiar Caminho do Nó" +msgstr "Concluir Caminhos de Arquivo" #: editor/editor_settings.cpp modules/gdscript/gdscript_editor.cpp -#, fuzzy msgid "Add Type Hints" -msgstr "Adicionar Modelo" +msgstr "Adicionar Dicas de Tipo" #: editor/editor_settings.cpp msgid "Use Single Quotes" msgstr "Usar Aspas Simples" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Help Index" -msgstr "Mostrar auxiliadores" +msgstr "Exibir Índice de Ajuda" #: editor/editor_settings.cpp msgid "Help Font Size" -msgstr "" +msgstr "Tamanho da Fonte de Ajuda" #: editor/editor_settings.cpp msgid "Help Source Font Size" -msgstr "" +msgstr "Tamanho da Fonte de Ajuda Principal" #: editor/editor_settings.cpp msgid "Help Title Font Size" -msgstr "" +msgstr "Tamanho da Fonte de Ajuda para Títulos" #: editor/editor_settings.cpp modules/gridmap/grid_map_editor_plugin.cpp msgid "Grid Map" @@ -5819,45 +5778,39 @@ msgid "Pick Distance" msgstr "Escolha a Distância" #: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Preview Size" -msgstr "Visualização" +msgstr "Tamanho da Prévia" #: editor/editor_settings.cpp msgid "Primary Grid Color" -msgstr "" +msgstr "Cor Primária da Grade" #: editor/editor_settings.cpp msgid "Secondary Grid Color" -msgstr "" +msgstr "Cor Secundária da Grade" #: editor/editor_settings.cpp -#, fuzzy msgid "Selection Box Color" -msgstr "Selecionar Apenas" +msgstr "Cor da Caixa de Seleção" #: editor/editor_settings.cpp editor/plugins/path_editor_plugin.cpp #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp -#, fuzzy msgid "3D Gizmos" -msgstr "Gizmos" +msgstr "Gizmos 3D" #: editor/editor_settings.cpp editor/plugins/path_editor_plugin.cpp #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp -#, fuzzy msgid "Gizmo Colors" -msgstr "Cores de Emissão" +msgstr "Cores do Gismo" #: editor/editor_settings.cpp -#, fuzzy msgid "Instanced" -msgstr "Instância" +msgstr "Instanciado" #: editor/editor_settings.cpp modules/gltf/gltf_node.cpp #: scene/3d/physics_body.cpp -#, fuzzy msgid "Joint" -msgstr "Ponto" +msgstr "Junção" #: editor/editor_settings.cpp scene/2d/collision_shape_2d.cpp #: scene/2d/cpu_particles_2d.cpp scene/2d/touch_screen_button.cpp @@ -5866,12 +5819,11 @@ msgstr "Ponto" #: scene/resources/particles_material.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp msgid "Shape" -msgstr "" +msgstr "Form" #: editor/editor_settings.cpp -#, fuzzy msgid "Primary Grid Steps" -msgstr "Passo de grade:" +msgstr "Passadas para Grade Primária" #: editor/editor_settings.cpp msgid "Grid Size" @@ -5879,183 +5831,155 @@ msgstr "Tamanho da Grade" #: editor/editor_settings.cpp msgid "Grid Division Level Max" -msgstr "" +msgstr "Nível Máximo de Divisão de Grade" #: editor/editor_settings.cpp msgid "Grid Division Level Min" -msgstr "" +msgstr "Nível Mínimo de Divisão da Grade" #: editor/editor_settings.cpp msgid "Grid Division Level Bias" -msgstr "" +msgstr "Tendência do Nível de Divisão da Grade" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid XZ Plane" -msgstr "Pintura GridMap" +msgstr "Grade do Plano XZ" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid XY Plane" -msgstr "Pintura GridMap" +msgstr "Grade do Plano XY" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid YZ Plane" -msgstr "Pintura GridMap" +msgstr "Grade do Plano YZ" #: editor/editor_settings.cpp -#, fuzzy msgid "Default FOV" -msgstr "Padrão" +msgstr "Campo de Visão (FOV) Padrão" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Z Near" -msgstr "Tema Padrão" +msgstr "Z Padrão Próximo" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Z Far" -msgstr "Padrão" +msgstr "Z Padrão Longe" #: editor/editor_settings.cpp msgid "Lightmap Baking Number Of CPU Threads" -msgstr "" +msgstr "Número de Threads de CPU para o Bake do Mapa de Luz" #: editor/editor_settings.cpp -#, fuzzy msgid "Navigation Scheme" -msgstr "Modo Navegação" +msgstr "Esquema de Navegação" #: editor/editor_settings.cpp -#, fuzzy msgid "Invert Y Axis" -msgstr "Eduitar Eixo Y" +msgstr "Inverter Eixo Y" #: editor/editor_settings.cpp -#, fuzzy msgid "Invert X Axis" -msgstr "Editar Eixo X" +msgstr "Inverter Eixo X" #: editor/editor_settings.cpp -#, fuzzy msgid "Zoom Style" -msgstr "Reduzir" +msgstr "Estilo de Zoom" #: editor/editor_settings.cpp msgid "Emulate Numpad" -msgstr "" +msgstr "Simular o Numpad" #: editor/editor_settings.cpp msgid "Emulate 3 Button Mouse" -msgstr "" +msgstr "Simular o Botão 3 Do Mouse" #: editor/editor_settings.cpp -#, fuzzy msgid "Orbit Modifier" -msgstr "Ordenar por Primeiro Modificado" +msgstr "Modificador de Órbita" #: editor/editor_settings.cpp -#, fuzzy msgid "Pan Modifier" -msgstr "Modo Panorâmico" +msgstr "Modificador de Panorâmica" #: editor/editor_settings.cpp -#, fuzzy msgid "Zoom Modifier" -msgstr "Modificado" +msgstr "Modificador de Zoom" #: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp msgid "Warped Mouse Panning" -msgstr "" +msgstr "Panorização Distorcida pelo Mouse" #: editor/editor_settings.cpp -#, fuzzy msgid "Navigation Feel" -msgstr "Modo Navegação" +msgstr "Sensação de Navegação" #: editor/editor_settings.cpp msgid "Orbit Sensitivity" -msgstr "" +msgstr "Sensitividade de Órbita" #: editor/editor_settings.cpp msgid "Orbit Inertia" -msgstr "" +msgstr "Inercia de Órbita" #: editor/editor_settings.cpp -#, fuzzy msgid "Translation Inertia" -msgstr "Traduções" +msgstr "Inércia de Translação" #: editor/editor_settings.cpp -#, fuzzy msgid "Zoom Inertia" -msgstr "Ampliar" +msgstr "Inércia de Zoom" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook" -msgstr "Visão Livre em Cima" +msgstr "Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Navigation Scheme" -msgstr "Criar Malha de Navegação" +msgstr "Esquema de Navegação de Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Sensitivity" -msgstr "Visão Livre na Esquerda" +msgstr "Sensibilidade de Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Inertia" -msgstr "Visão Livre na Esquerda" +msgstr "Inercia de Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Base Speed" -msgstr "Modificador de velocidade da Visão Livre" +msgstr "Velocidade Base de Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Activation Modifier" -msgstr "Modificador de velocidade lenta da Visão Livre" +msgstr "Modificador de Ativação de Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Speed Zoom Link" -msgstr "Modificador de velocidade da Visão Livre" +msgstr "Velocidade de Ligação do Visão Livre" #: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Grid Color" -msgstr "Escolher Cor" +msgstr "Cor da Grade" #: editor/editor_settings.cpp -#, fuzzy msgid "Guides Color" -msgstr "Escolher Cor" +msgstr "Cor Guia" #: editor/editor_settings.cpp -#, fuzzy msgid "Smart Snapping Line Color" -msgstr "Encaixe inteligente" +msgstr "Cor da Linha de Encaixe Inteligente" #: editor/editor_settings.cpp msgid "Bone Width" -msgstr "" +msgstr "Largura do Osso" #: editor/editor_settings.cpp -#, fuzzy msgid "Bone Color 1" -msgstr "Renomear Item de Cor" +msgstr "Cor de Osso 1" #: editor/editor_settings.cpp -#, fuzzy msgid "Bone Color 2" -msgstr "Renomear Item de Cor" +msgstr "Cor de Osso 2" #: editor/editor_settings.cpp msgid "Bone Selected Color" @@ -6063,11 +5987,11 @@ msgstr "Cor Selecionada do Osso" #: editor/editor_settings.cpp msgid "Bone IK Color" -msgstr "" +msgstr "Cor de Osso IK (cinemática inversa)" #: editor/editor_settings.cpp msgid "Bone Outline Color" -msgstr "" +msgstr "Cor de Contorno do Osso" #: editor/editor_settings.cpp msgid "Bone Outline Size" @@ -6075,103 +5999,93 @@ msgstr "Tamanho do Contorno do Osso" #: editor/editor_settings.cpp msgid "Viewport Border Color" -msgstr "" +msgstr "Cor da Borda de Viewport" #: editor/editor_settings.cpp msgid "Constrain Editor View" -msgstr "" +msgstr "Restringir Visão do Editor" #: editor/editor_settings.cpp msgid "Simple Panning" -msgstr "" +msgstr "Panoramização Simples" #: editor/editor_settings.cpp msgid "Scroll To Pan" -msgstr "" +msgstr "Rolar para Panoramizar" #: editor/editor_settings.cpp -#, fuzzy msgid "Pan Speed" -msgstr "Velocidade:" +msgstr "Velocidade da Panoramização" #: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Poly Editor" -msgstr "Editor UV de Polígonos 2D" +msgstr "Editor de Polígonos" #: editor/editor_settings.cpp msgid "Point Grab Radius" -msgstr "" +msgstr "Raio de Agarro ao Ponto" #: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Show Previous Outline" -msgstr "Plano Anterior" +msgstr "Exibir Prévia Anterior" #: editor/editor_settings.cpp editor/scene_tree_dock.cpp -#, fuzzy msgid "Autorename Animation Tracks" -msgstr "Renomear Animação" +msgstr "Renomear Automaticamente Faixa de Animação" #: editor/editor_settings.cpp msgid "Default Create Bezier Tracks" -msgstr "" +msgstr "Criar Faixa de Bezier por Padrão" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Create Reset Tracks" -msgstr "Criar RESET Track(s)" +msgstr "Criar Faixa RESET Por Padrão" #: editor/editor_settings.cpp msgid "Onion Layers Past Color" -msgstr "" +msgstr "Cor da Camada de Cebola Anterior" #: editor/editor_settings.cpp msgid "Onion Layers Future Color" -msgstr "" +msgstr "Cor da Camada de Cebola Posterior" #: editor/editor_settings.cpp -#, fuzzy msgid "Visual Editors" -msgstr "Editor de Grupos" +msgstr "Editores Visuais" #: editor/editor_settings.cpp msgid "Minimap Opacity" -msgstr "" +msgstr "Opacidade do Mini-Mapa" #: editor/editor_settings.cpp msgid "Window Placement" -msgstr "" +msgstr "Colocação da Janela" #: editor/editor_settings.cpp scene/2d/back_buffer_copy.cpp scene/2d/sprite.cpp #: scene/2d/visibility_notifier_2d.cpp scene/3d/sprite_3d.cpp #: scene/gui/control.cpp -#, fuzzy msgid "Rect" -msgstr "Rect Completo" +msgstr "Retângulo" #: editor/editor_settings.cpp -#, fuzzy msgid "Rect Custom Position" -msgstr "Definir Posição de Saída da Curva" +msgstr "Posição Personalizada Do Retângulo" #: editor/editor_settings.cpp platform/android/export/export_plugin.cpp msgid "Screen" -msgstr "" +msgstr "Tela" #: editor/editor_settings.cpp -#, fuzzy msgid "Auto Save" -msgstr "Auto Fatiar" +msgstr "Salvar Automaticamente" #: editor/editor_settings.cpp msgid "Save Before Running" msgstr "Salvar Antes de Executar" #: editor/editor_settings.cpp -#, fuzzy msgid "Font Size" -msgstr "Visão Frontal" +msgstr "Tamanho da Fonte" #: editor/editor_settings.cpp #: modules/gdscript/language_server/gdscript_language_server.cpp @@ -6180,28 +6094,26 @@ msgstr "Hospedeiro Remoto" #: editor/editor_settings.cpp #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Remote Port" -msgstr "Remover Ponto" +msgstr "Porta Remota" #: editor/editor_settings.cpp -#, fuzzy msgid "Editor SSL Certificates" -msgstr "Configurações do Editor" +msgstr "Certificados SSL do Editor" #: editor/editor_settings.cpp msgid "HTTP Proxy" -msgstr "" +msgstr "Proxy HTTP" #: editor/editor_settings.cpp msgid "Host" -msgstr "" +msgstr "Hospedeiro" #: editor/editor_settings.cpp editor/fileserver/editor_file_server.cpp #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Port" -msgstr "" +msgstr "Porta" #. TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects. #: editor/editor_settings.cpp @@ -6215,32 +6127,31 @@ msgstr "Ordem de Classificação" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Symbol Color" -msgstr "" +msgstr "Cor do Simbolo" #: editor/editor_settings.cpp msgid "Keyword Color" -msgstr "" +msgstr "Cor de Palavra Chave" #: editor/editor_settings.cpp msgid "Control Flow Keyword Color" -msgstr "" +msgstr "Core de Palavra Chave de Controle de Fluxo" #: editor/editor_settings.cpp -#, fuzzy msgid "Base Type Color" -msgstr "Mudar Tipo Base" +msgstr "Cor de Tipo Base" #: editor/editor_settings.cpp msgid "Engine Type Color" -msgstr "" +msgstr "Cor de Tipo da Engine" #: editor/editor_settings.cpp msgid "User Type Color" -msgstr "" +msgstr "Cor de Tipo Do Usuário" #: editor/editor_settings.cpp msgid "Comment Color" -msgstr "" +msgstr "Cor de Comentário" #: editor/editor_settings.cpp msgid "String Color" @@ -6257,26 +6168,24 @@ msgid "Completion Background Color" msgstr "Cor de Fundo de Acabamento" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Completion Selected Color" -msgstr "Importar Selecionado" +msgstr "Cor de Sugestão Selecionada" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Existing Color" -msgstr "" +msgstr "Cor de Sugestão Existente" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Scroll Color" -msgstr "" +msgstr "Cor da Barra de Rolagem de Sugestão" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Font Color" -msgstr "" +msgstr "Cor da Fonte de Sugestão" #: editor/editor_settings.cpp -#, fuzzy msgid "Text Color" -msgstr "Próximo Chão" +msgstr "Cor do Texto" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Line Number Color" @@ -6288,86 +6197,75 @@ msgstr "Cor do Número da Linha Segura" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Caret Color" -msgstr "" +msgstr "Cor do Cursor" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Caret Background Color" msgstr "Cor de Fundo de Acentuação" #: editor/editor_settings.cpp -#, fuzzy msgid "Text Selected Color" -msgstr "Excluir Selecionados" +msgstr "Cor do Texto Selecionado" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Selection Color" -msgstr "Selecionar Apenas" +msgstr "Cor da Seleção" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Brace Mismatch Color" -msgstr "" +msgstr "Cor de Chave Incompatível" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Current Line Color" -msgstr "Cena Atual" +msgstr "Cor da Linha Atual" #: editor/editor_settings.cpp msgid "Line Length Guideline Color" -msgstr "" +msgstr "Cor do Tamanho de Linha Guia" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Word Highlighted Color" -msgstr "Realce de sintaxe" +msgstr "Cor da Palavra em Destaque" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Number Color" -msgstr "" +msgstr "Cor de Número" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Function Color" -msgstr "Funções" +msgstr "Cor de Função" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Member Variable Color" -msgstr "Renomear Variável" +msgstr "Cor de Variável Membro" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Mark Color" -msgstr "Escolher Cor" +msgstr "Cor de Marcação" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Bookmark Color" -msgstr "Marcadores" +msgstr "Cor de Bookmark" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Breakpoint Color" -msgstr "Breakpoints" +msgstr "Cor de Ponto de Quebra" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Executing Line Color" -msgstr "" +msgstr "Cor da Linha em Execução" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Code Folding Color" -msgstr "" +msgstr "Cor da Dobradiça de Código" #: editor/editor_settings.cpp -#, fuzzy msgid "Search Result Color" -msgstr "Pesquisar resultados" +msgstr "Cor do Resultado de Pesquisa" #: editor/editor_settings.cpp -#, fuzzy msgid "Search Result Border Color" -msgstr "Pesquisar resultados" +msgstr "Cor da Borda do Resultado de Pesquisa" #: editor/editor_spin_slider.cpp msgid "Hold %s to round to integers. Hold Shift for more precise changes." @@ -6376,14 +6274,12 @@ msgstr "" "mais precisas." #: editor/editor_spin_slider.cpp scene/gui/button.cpp -#, fuzzy msgid "Flat" -msgstr "Plano 0" +msgstr "Raso" #: editor/editor_spin_slider.cpp -#, fuzzy msgid "Hide Slider" -msgstr "Modo Colisão" +msgstr "Esconder Rolagem" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" @@ -6683,7 +6579,7 @@ msgstr "" #: editor/fileserver/editor_file_server.cpp msgid "File Server" -msgstr "" +msgstr "Servidor de Arquivos" #: editor/fileserver/editor_file_server.cpp #: editor/plugins/version_control_editor_plugin.cpp @@ -6751,6 +6647,11 @@ msgid "" "After renaming to an unknown extension, the file won't be shown in the " "editor anymore." msgstr "" +"Esta extensão de arquivo não é reconhecida pelo editor.\n" +"Se ainda assim você deseja renomear, utilize o explorador de arquivos do seu " +"sistema operacional.\n" +"Após renomear para uma extensão desconhecida, este arquivo não será mais " +"exibida pelo editor." #: editor/filesystem_dock.cpp msgid "" @@ -7051,43 +6952,40 @@ msgstr "Gerenciar Grupos" #: editor/import/editor_import_collada.cpp msgid "Collada" -msgstr "" +msgstr "Collada" #: editor/import/editor_import_collada.cpp msgid "Use Ambient" -msgstr "" +msgstr "Utilizar Ambient" #: editor/import/resource_importer_bitmask.cpp -#, fuzzy msgid "Create From" -msgstr "Criar Pasta" +msgstr "Criar à Partir de" #: editor/import/resource_importer_bitmask.cpp #: servers/audio/effects/audio_effect_compressor.cpp msgid "Threshold" -msgstr "" +msgstr "Limite" #: editor/import/resource_importer_csv_translation.cpp #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_scene.cpp #: editor/import/resource_importer_texture.cpp #: editor/import/resource_importer_wav.cpp scene/3d/gi_probe.cpp -#, fuzzy msgid "Compress" -msgstr "Componentes" +msgstr "Comprimir" #: editor/import/resource_importer_csv_translation.cpp msgid "Delimiter" -msgstr "" +msgstr "Delimitador" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "ColorCorrect" -msgstr "Correção de Cor" +msgstr "Corrigir as Cores" #: editor/import/resource_importer_layered_texture.cpp msgid "No BPTC If RGB" -msgstr "" +msgstr "Não utilizar BPTC se for RGB" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/2d/cpu_particles_2d.cpp @@ -7095,13 +6993,13 @@ msgstr "" #: scene/resources/material.cpp scene/resources/particles_material.cpp #: scene/resources/texture.cpp scene/resources/visual_shader.cpp msgid "Flags" -msgstr "" +msgstr "Sinalizadores" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/animation/tween.cpp #: scene/resources/texture.cpp msgid "Repeat" -msgstr "" +msgstr "Repetir" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/2d/light_2d.cpp @@ -7111,24 +7009,22 @@ msgstr "Filtro" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Mipmaps" -msgstr "Sinais" +msgstr "Mipmaps" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp msgid "Anisotropic" -msgstr "" +msgstr "Anisotrópico" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp msgid "sRGB" -msgstr "" +msgstr "sRGB" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "Slices" -msgstr "Auto Fatiar" +msgstr "Fatias" #: editor/import/resource_importer_layered_texture.cpp #: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp @@ -7145,14 +7041,12 @@ msgid "Vertical" msgstr "Vertical" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Generate Tangents" -msgstr "Gerar Pontos" +msgstr "Gerar Tangentes" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Scale Mesh" -msgstr "Modo de Escalonamento" +msgstr "Redimensionar Malha" #: editor/import/resource_importer_obj.cpp msgid "Offset Mesh" @@ -7160,14 +7054,12 @@ msgstr "Malha de Deslocamento" #: editor/import/resource_importer_obj.cpp #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Octahedral Compression" -msgstr "Expressão" +msgstr "Compressão Octaedral" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Optimize Mesh Flags" -msgstr "Sinalizadores de Tamanho" +msgstr "Otimizar Sinalizadores da Malha" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" @@ -7215,24 +7107,20 @@ msgid "Nodes" msgstr "Nós" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Type" -msgstr "Retornar" +msgstr "Tipo da Raiz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Name" -msgstr "Nome Remoto" +msgstr "Nome da Raiz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Scale" -msgstr "Escala" +msgstr "Escala da Raiz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Custom Script" -msgstr "Recortar Nós" +msgstr "Script Personalizado" #: editor/import/resource_importer_scene.cpp scene/resources/texture.cpp msgid "Storage" @@ -7240,69 +7128,59 @@ msgstr "Armazenamento" #: editor/import/resource_importer_scene.cpp msgid "Use Legacy Names" -msgstr "" +msgstr "Utilizar Nomes Legados" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp msgid "Materials" msgstr "Materiais" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Keep On Reimport" -msgstr "Reimportar" +msgstr "Manter ao Reimportar" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp -#, fuzzy msgid "Meshes" -msgstr "Malha" +msgstr "Malhas" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Ensure Tangents" -msgstr "Modificar Tangente da Curva" +msgstr "Garantir Tangentes" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Light Baking" -msgstr "Faça mapas de luz" +msgstr "Bake de Mapa de Luz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Lightmap Texel Size" -msgstr "Faça mapas de luz" +msgstr "Tamanho do Texel no Mapa de Luz" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp msgid "Skins" -msgstr "" +msgstr "Peles" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Use Named Skins" -msgstr "Usar Encaixe Escalar" +msgstr "Utilizar Peles com Nome" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "External Files" -msgstr "Abrir um Arquivo" +msgstr "Arquivos Externos" #: editor/import/resource_importer_scene.cpp msgid "Store In Subdir" -msgstr "" +msgstr "Salvar em Sub Diretório" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Filter Script" -msgstr "Filtrar scripts" +msgstr "Filtrar Script" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Keep Custom Tracks" -msgstr "Transformação" +msgstr "Manter Faixas Personalizadas" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Optimizer" -msgstr "Otimizar" +msgstr "Otimizador" #: editor/import/resource_importer_scene.cpp #: editor/plugins/item_list_editor_plugin.cpp main/main.cpp @@ -7316,9 +7194,8 @@ msgstr "Otimizar" #: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp #: scene/gui/rich_text_label.cpp scene/resources/curve.cpp #: scene/resources/environment.cpp scene/resources/material.cpp -#, fuzzy msgid "Enabled" -msgstr "Habilitar" +msgstr "Habilitado" #: editor/import/resource_importer_scene.cpp msgid "Max Linear Error" @@ -7329,19 +7206,16 @@ msgid "Max Angular Error" msgstr "Erro Angular Máximo" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Max Angle" -msgstr "Valor" +msgstr "Ângulo Máximo" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Remove Unused Tracks" -msgstr "Remover Trilha da Anim" +msgstr "Remover Faixas não Utilizadas" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Clips" -msgstr "Clipes de Animação" +msgstr "Clipes" #: editor/import/resource_importer_scene.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/particles_2d.cpp scene/3d/area.cpp scene/3d/cpu_particles.cpp @@ -7395,30 +7269,33 @@ msgid "" "%s: Texture detected as used as a normal map in 3D. Enabling red-green " "texture compression to reduce memory usage (blue channel is discarded)." msgstr "" +"%s: Foi detectado que a textura está sendo utilizada como mapa normal em 3D. " +"Habilitando a compressão vermelho/verde para reduzir o uso de memória (o " +"canal azul é descartado)." #: editor/import/resource_importer_texture.cpp msgid "" "%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap " "generation and VRAM texture compression." msgstr "" +"%s: Foi detectado que a textura está sendo utilizada em 3D. Habilitando a " +"filtro, repetir, geração de mipmap e compressão de textura VRAM." #: editor/import/resource_importer_texture.cpp msgid "2D, Detect 3D" -msgstr "" +msgstr "2D, Detecte 3D" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "2D Pixel" -msgstr "Pixels Sólidos" +msgstr "Pixel 2D" #: editor/import/resource_importer_texture.cpp scene/resources/texture.cpp msgid "Lossy Quality" -msgstr "" +msgstr "Com Perda de Qualidade" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "HDR Mode" -msgstr "Modo de Seleção" +msgstr "Modo HDR" #: editor/import/resource_importer_texture.cpp msgid "BPTC LDR" @@ -7429,54 +7306,52 @@ msgstr "" #: scene/2d/mesh_instance_2d.cpp scene/2d/multimesh_instance_2d.cpp #: scene/2d/particles_2d.cpp scene/2d/sprite.cpp scene/resources/style_box.cpp msgid "Normal Map" -msgstr "" +msgstr "Mapa Normal" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Process" -msgstr "Pós-processamento" +msgstr "Processar" #: editor/import/resource_importer_texture.cpp msgid "Fix Alpha Border" -msgstr "" +msgstr "Corrigir Alpha da Borda" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Premult Alpha" -msgstr "Editar Polígono" +msgstr "" #: editor/import/resource_importer_texture.cpp msgid "Hdr As Srgb" -msgstr "" +msgstr "HDR como SRGB" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Invert Color" -msgstr "Vértice" +msgstr "Inverter Cor" #: editor/import/resource_importer_texture.cpp msgid "Normal Map Invert Y" msgstr "Inverter Y do Mapa Normal" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Size Limit" -msgstr "Limites" +msgstr "Limite de Tamanho" #: editor/import/resource_importer_texture.cpp msgid "Detect 3D" -msgstr "" +msgstr "Detectar 3D" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "SVG" -msgstr "HSV" +msgstr "SVG" #: editor/import/resource_importer_texture.cpp msgid "" "Warning, no suitable PC VRAM compression enabled in Project Settings. This " "texture will not display correctly on PC." msgstr "" +"Atenção, nenhuma forma adequada de Compressão VRAM para PC foi habilitada " +"nas Configurações do Projeto. Esta textura não será exibida corretamente em " +"PCs." #: editor/import/resource_importer_texture_atlas.cpp msgid "Atlas File" @@ -7487,64 +7362,56 @@ msgid "Import Mode" msgstr "Modo de Importação" #: editor/import/resource_importer_texture_atlas.cpp -#, fuzzy msgid "Crop To Region" -msgstr "Definir a região do Mosaico" +msgstr "Recortar para Região" #: editor/import/resource_importer_texture_atlas.cpp msgid "Trim Alpha Border From Region" -msgstr "" +msgstr "Aparar Borda Alfa da Região" #: editor/import/resource_importer_wav.cpp scene/2d/physics_body_2d.cpp -#, fuzzy msgid "Force" -msgstr "Forçar Push" +msgstr "Forçar" #: editor/import/resource_importer_wav.cpp msgid "8 Bit" -msgstr "" +msgstr "8 Bits" #: editor/import/resource_importer_wav.cpp main/main.cpp #: modules/mono/editor/csharp_project.cpp modules/mono/mono_gd/gd_mono.cpp msgid "Mono" -msgstr "" +msgstr "Mono" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Max Rate" -msgstr "Nó Mix" +msgstr "Frequência Máxima" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Max Rate Hz" -msgstr "Nó Mix" +msgstr "Frequência Máxima Hz" #: editor/import/resource_importer_wav.cpp msgid "Trim" -msgstr "" +msgstr "Aparar" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Normalize" -msgstr "Formato" +msgstr "Normalizar" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop Mode" -msgstr "Modo de Movimentação" +msgstr "Modo de Loop" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop Begin" -msgstr "Modo de Movimentação" +msgstr "Inicio do Loop" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop End" -msgstr "Modo de Movimentação" +msgstr "Fim do Loop" #: editor/import_defaults_editor.cpp msgid "Select Importer" @@ -7632,18 +7499,16 @@ msgid "Raw" msgstr "Bruto" #: editor/inspector_dock.cpp -#, fuzzy msgid "Capitalized" -msgstr "Capitalizar" +msgstr "Capitalizado" #: editor/inspector_dock.cpp -#, fuzzy msgid "Localized" -msgstr "Localizar" +msgstr "Localizado" #: editor/inspector_dock.cpp msgid "Localization not available for current language." -msgstr "" +msgstr "Localização não disponível para linguagem atual." #: editor/inspector_dock.cpp msgid "Copy Properties" @@ -8192,9 +8057,8 @@ msgid "New" msgstr "Novo" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Paste As Reference" -msgstr "%s Referência de Classes" +msgstr "Colar como Referência" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Transitions..." @@ -8523,7 +8387,7 @@ msgstr "Filtros..." #: editor/plugins/asset_library_editor_plugin.cpp scene/main/http_request.cpp msgid "Use Threads" -msgstr "" +msgstr "Usar Threads" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Contents:" @@ -8686,25 +8550,21 @@ msgid "Loading..." msgstr "Carregando..." #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "First" msgstr "Primeiro" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Previous" msgstr "Anterior" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Next" msgstr "Próximo" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Last" msgstr "Último" @@ -8755,7 +8615,7 @@ msgstr "Testando" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed to get repository configuration." -msgstr "" +msgstr "Falhou em obter o repositório de configuração." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" @@ -8815,7 +8675,7 @@ msgstr "Faça mapas de luz" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "LightMap Bake" -msgstr "" +msgstr "Bake de Mapa de Luz" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Select lightmap bake file:" @@ -9322,23 +9182,20 @@ msgid "View" msgstr "Visualizar" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Show" -msgstr "Mostrar Grade" +msgstr "Exibir" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Show When Snapping" -msgstr "Encaixe inteligente" +msgstr "Exibir ao Encaixar" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Hide" -msgstr "" +msgstr "Esconder" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Toggle Grid" -msgstr "Alternar Modo" +msgstr "Alternar Grade" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -9622,11 +9479,11 @@ msgstr "Plano 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" -msgstr "Ease In" +msgstr "Esmaecer de Entrada" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease Out" -msgstr "Ease Out" +msgstr "Esmaecer de Saída" #: editor/plugins/curve_editor_plugin.cpp msgid "Smoothstep" @@ -9690,16 +9547,15 @@ msgstr "Gradiente Editado" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp msgid "Swap GradientTexture2D Fill Points" -msgstr "" +msgstr "Trocar Pontos de Preenchimento do GradientTexture2D" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp msgid "Swap Gradient Fill Points" -msgstr "" +msgstr "Trocar Pontos de Preenchimento do Degradê" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp -#, fuzzy msgid "Toggle Grid Snap" -msgstr "Alternar Modo" +msgstr "Alternar Encaixe da Grade" #: editor/plugins/item_list_editor_plugin.cpp editor/project_export.cpp #: scene/3d/label_3d.cpp scene/gui/button.cpp scene/gui/dialogs.cpp @@ -9718,13 +9574,12 @@ msgstr "Ícone" #: editor/plugins/item_list_editor_plugin.cpp msgid "ID" -msgstr "" +msgstr "ID" #: editor/plugins/item_list_editor_plugin.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Separator" -msgstr "Separação:" +msgstr "Separador" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" @@ -9958,7 +9813,6 @@ msgstr "" "%s" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "MeshLibrary" msgstr "Biblioteca de Malhas" @@ -9983,14 +9837,12 @@ msgid "Update from Scene" msgstr "Atualizar a partir de Cena" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Apply without Transforms" -msgstr "Aplicar transformações da MeshInstance" +msgstr "Aplicar sem Transformações" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Apply with Transforms" -msgstr "Aplicar transformações da MeshInstance" +msgstr "Aplicar com Transformações" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." @@ -10482,7 +10334,7 @@ msgstr "Configurações da grade" #: editor/plugins/polygon_2d_editor_plugin.cpp modules/csg/csg_shape.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Snap" -msgstr "Snap" +msgstr "Encaixe" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" @@ -10518,7 +10370,7 @@ msgstr "Sincronizar Ossos ao Polígono" #: editor/plugins/ray_cast_2d_editor_plugin.cpp msgid "Set cast_to" -msgstr "" +msgstr "Definir cast_to" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ERROR: Couldn't load resource!" @@ -10849,48 +10701,43 @@ msgstr "Resultados de Pesquisa" #: editor/plugins/script_editor_plugin.cpp msgid "Open Dominant Script On Scene Change" -msgstr "" +msgstr "Abrir Script Dominante ao Mudar de Cena" #: editor/plugins/script_editor_plugin.cpp msgid "External" -msgstr "" +msgstr "Externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Use External Editor" -msgstr "Depurar com o Editor Externo" +msgstr "Utilizar Editor Externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Exec Path" -msgstr "Caminho de Exportação" +msgstr "Caminho de Execução" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Script Temperature Enabled" -msgstr "Selecionar o Arquivo de Modelo" +msgstr "Temperatura de Script Habilitado" #: editor/plugins/script_editor_plugin.cpp msgid "Highlight Current Script" -msgstr "" +msgstr "Destacar Script Atual" #: editor/plugins/script_editor_plugin.cpp msgid "Script Temperature History Size" -msgstr "" +msgstr "Tamanho de Histórico de Temperatura de Script" #: editor/plugins/script_editor_plugin.cpp msgid "Current Script Background Color" msgstr "Cor de Fundo do Script Atual" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Group Help Pages" -msgstr "Agrupar Selecionados" +msgstr "Agrupar Páginas de Ajuda" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Sort Scripts By" -msgstr "Criar Script" +msgstr "Ordenar Scripts Por" #: editor/plugins/script_editor_plugin.cpp msgid "List Script Names As" @@ -10898,7 +10745,7 @@ msgstr "Listar Nomes de Script Como" #: editor/plugins/script_editor_plugin.cpp msgid "Exec Flags" -msgstr "" +msgstr "Sinalizadores de Execução" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Scripts" @@ -10982,7 +10829,7 @@ msgstr "Marcadores" #: editor/plugins/script_text_editor.cpp msgid "Breakpoints" -msgstr "Breakpoints" +msgstr "Pontos de Quebra" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp @@ -11411,13 +11258,14 @@ msgstr "Pré-visualização Cinemática" #: editor/plugins/spatial_editor_plugin.cpp msgid "(Not in GLES2)" -msgstr "" +msgstr "(Não disponível em GLES2)" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "" "Debug draw modes are only available when using the GLES3 renderer, not GLES2." -msgstr "Não disponível ao usar o renderizador GLES2." +msgstr "" +"Modos de Debug draw só estão disponíveis para uso com o renderizador GLES3. " +"GLES2 não suporta esta funcionalidade." #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Left" @@ -11712,16 +11560,15 @@ msgstr "Pós" #: editor/plugins/spatial_editor_plugin.cpp msgid "Manipulator Gizmo Size" -msgstr "" +msgstr "Tamanho do Gizmo Manipulador" #: editor/plugins/spatial_editor_plugin.cpp msgid "Manipulator Gizmo Opacity" -msgstr "" +msgstr "Opacidade do Gizmo Manipulador" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Show Viewport Rotation Gizmo" -msgstr "Bloquear Rotação da Visão" +msgstr "Exibir Gizmo de Rotação do Viewport" #: editor/plugins/spatial_editor_plugin.cpp msgid "Unnamed Gizmo" @@ -11773,9 +11620,8 @@ msgid "Invalid geometry, can't replace by mesh." msgstr "Geometria inválida, não é possível substituir por malha." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to MeshInstance2D" -msgstr "Converter para Malha2D" +msgstr "Converter para MeshInstance2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." @@ -11878,6 +11724,11 @@ msgid "New Animation" msgstr "Nova animação" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrar métodos" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocidade:" @@ -12175,9 +12026,8 @@ msgstr "" "Fechar mesmo assim?" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove Type" -msgstr "Remover Telha" +msgstr "Remover Tipo" #: editor/plugins/theme_editor_plugin.cpp msgid "" @@ -12221,14 +12071,12 @@ msgstr "" "Adicione mais itens manualmente ou importe de outro tema." #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Add Theme Type" -msgstr "Adicionar Tipo de Item" +msgstr "Adicionar Tipo de Tema" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove Theme Type" -msgstr "Remover remoto" +msgstr "Remover Tipo de Tema" #: editor/plugins/theme_editor_plugin.cpp msgid "Add Color Item" @@ -12343,9 +12191,8 @@ msgid "Select Another Theme Resource:" msgstr "Selecionar Outro Recurso de Tema:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Theme Resource" -msgstr "Renomear Recurso" +msgstr "Recurso de Tema" #: editor/plugins/theme_editor_plugin.cpp msgid "Another Theme" @@ -12400,14 +12247,12 @@ msgid "Add Item Type" msgstr "Adicionar Tipo de Item" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Set Variation Base Type" -msgstr "Definir o Tipo da Variável" +msgstr "Definir Tipo de Variação Base" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Set Base Type" -msgstr "Mudar Tipo Base" +msgstr "Definir Tipo Base" #: editor/plugins/theme_editor_plugin.cpp msgid "Show Default" @@ -12429,12 +12274,15 @@ msgstr "Substituir todos os itens do modelo padrão." #: editor/plugins/theme_editor_plugin.cpp msgid "Select the variation base type from a list of available types." msgstr "" +"Selecione a variação do tipo base à partir da lista de tipos disponíveis." #: editor/plugins/theme_editor_plugin.cpp msgid "" "A type associated with a built-in class cannot be marked as a variation of " "another type." msgstr "" +"Um tipo associado à uma classe padrão não pode ser marcada como variação de " +"outro tipo." #: editor/plugins/theme_editor_plugin.cpp msgid "Theme:" @@ -12672,14 +12520,13 @@ msgid "Clear Transform" msgstr "Limpar Transformação" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Tile Map" -msgstr "Pintar TileMap" +msgstr "Tile Map" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Palette Min Width" -msgstr "" +msgstr "Largura Mínima de Paleta" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -12687,24 +12534,20 @@ msgid "Palette Item H Separation" msgstr "Separador Nomeado" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Show Tile Names" -msgstr "Mostrar todos os Locales" +msgstr "Mostrar Nomes dos Tiles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Show Tile Ids" -msgstr "Mostrar Réguas" +msgstr "Mostrar Ids dos Tiles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Sort Tiles By Name" -msgstr "Ordenar arquivos" +msgstr "Ordenar Tiles por Nome" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Bucket Fill Preview" -msgstr "Preenchimento de Balde" +msgstr "Pré-visualização do Preenchimento de Balde" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp @@ -12713,9 +12556,8 @@ msgid "Editor Side" msgstr "Editor" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Display Grid" -msgstr "Exibição Overdraw" +msgstr "Mostrar Grid" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -13081,14 +12923,12 @@ msgstr "Passo" #: editor/plugins/tile_set_editor_plugin.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Separation" -msgstr "Separação:" +msgstr "Separação" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Tile" -msgstr "Selecionar" +msgstr "Selecionar Tile" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/light_2d.cpp scene/2d/line_2d.cpp scene/2d/mesh_instance_2d.cpp @@ -13097,9 +12937,8 @@ msgstr "Selecionar" #: scene/gui/nine_patch_rect.cpp scene/gui/texture_rect.cpp #: scene/resources/material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Texture" -msgstr "Texto" +msgstr "Textura" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13119,9 +12958,8 @@ msgid "Modulate" msgstr "Popular" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tile Mode" -msgstr "Alternar Modo" +msgstr "Modo de Tiles" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13129,14 +12967,12 @@ msgid "Autotile Bitmask Mode" msgstr "Modo Bitmask" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Size" -msgstr "Tamanho do Contorno:" +msgstr "Tamanho do Sub Título" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Spacing" -msgstr "Loop da Animação" +msgstr "Espaçamento dos Subtiles" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13144,24 +12980,20 @@ msgid "Occluder Offset" msgstr "Criar Polígono de Oclusão" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Offset" -msgstr "Modo Navegação" +msgstr "Deslocamento da Navegação" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Shape Offset" -msgstr "Deslocamento Base" +msgstr "Deslocamento da Forma" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Shape Transform" -msgstr "Transformação" +msgstr "Transformação da Forma" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision" -msgstr "Colisão" +msgstr "Colisão Selecionada" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13174,19 +13006,16 @@ msgid "Selected Collision One Way Margin" msgstr "Modo Colisão" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Navigation" -msgstr "Navegação Visível" +msgstr "Navegação Selecionada" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Occlusion" -msgstr "Selecionar" +msgstr "Oclusão Selecionada" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tileset Script" -msgstr "Filtrar scripts" +msgstr "Scripts do Tileset" #: editor/plugins/tile_set_editor_plugin.cpp msgid "TileSet" @@ -13265,7 +13094,7 @@ msgstr "Selecione o caminho da chave privada SSH" #: editor/plugins/version_control_editor_plugin.cpp msgid "SSH Passphrase" -msgstr "SSH Passphrase" +msgstr "Senha SSH" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" @@ -14274,11 +14103,13 @@ msgstr "Executável" #: editor/project_export.cpp msgid "Export the project for all the presets defined." -msgstr "" +msgstr "Exportar o projeto para todos os presets definidos." #: editor/project_export.cpp msgid "All presets must have an export path defined for Export All to work." msgstr "" +"Todos os presets devem ter um caminho de exportação para que a " +"funcionalidade de Exportar Todos funcione." #: editor/project_export.cpp msgid "Delete preset '%s'?" @@ -14391,11 +14222,12 @@ msgid "" "Note: Encryption key needs to be stored in the binary,\n" "you need to build the export templates from source." msgstr "" +"Nota: Chaves de encriptação têm que ser salvas com o binário,\n" +"você precisa compilar os modelos de exportação à partir do código fonte." #: editor/project_export.cpp -#, fuzzy msgid "More Info..." -msgstr "Mover Para..." +msgstr "Mais Informações..." #: editor/project_export.cpp msgid "Export PCK/Zip..." @@ -14422,18 +14254,16 @@ msgid "ZIP File" msgstr "Arquivo ZIP" #: editor/project_export.cpp -#, fuzzy msgid "Godot Project Pack" -msgstr "Pacote de Jogos Godot" +msgstr "Pacote do Projeto Godot" #: editor/project_export.cpp msgid "Export templates for this platform are missing:" msgstr "Modelos de exportação para esta plataforma não foram encontrados:" #: editor/project_export.cpp -#, fuzzy msgid "Project Export" -msgstr "Fundadores do Projeto" +msgstr "Exportar Projeto" #: editor/project_export.cpp msgid "Manage Export Templates" @@ -14746,7 +14576,6 @@ msgstr "" #. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp -#, fuzzy msgctxt "Application" msgid "Project Manager" msgstr "Gerenciador de Projetos" @@ -15546,7 +15375,7 @@ msgstr "Tornar Local" #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp msgid "Another node already uses this unique name in the scene." -msgstr "" +msgstr "Outro nó já está usando este nome único na cena atual." #: editor/scene_tree_dock.cpp #, fuzzy @@ -15632,7 +15461,7 @@ msgstr "Sub-Recursos" #: editor/scene_tree_dock.cpp msgid "Access as Scene Unique Name" -msgstr "" +msgstr "Acessar como Nome Único de Cena" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance" @@ -15737,7 +15566,7 @@ msgstr "Seleção Central" #: editor/scene_tree_dock.cpp msgid "Derive Script Globals By Name" -msgstr "" +msgstr "Obter Globais de Script por Nome" #: editor/scene_tree_dock.cpp #, fuzzy @@ -15770,6 +15599,9 @@ msgid "" "with the '%s' prefix in a node path.\n" "Click to disable this." msgstr "" +"Este nó pode ser acessado em qualquer lugar na cena adicionando o prefixo " +"'%s' em um node path.\n" +"Clique para desabilitar esta funcionalidade." #: editor/scene_tree_editor.cpp msgid "" @@ -16062,15 +15894,15 @@ msgstr "Filtros do tile" #: editor/script_editor_debugger.cpp msgid "Auto Switch To Remote Scene Tree" -msgstr "" +msgstr "Mudar Automaticamente Para a Árvore de Cena Remota" #: editor/script_editor_debugger.cpp msgid "Remote Scene Tree Refresh Interval" -msgstr "" +msgstr "Intervalo de Atualização da Árvore Remota" #: editor/script_editor_debugger.cpp msgid "Remote Inspect Refresh Interval" -msgstr "" +msgstr "Intervalo de Atualização da Inspeção Remota" #: editor/script_editor_debugger.cpp msgid "Network Profiler" @@ -16168,7 +16000,7 @@ msgstr "Alterar Raio da Luz" #: editor/spatial_editor_gizmos.cpp msgid "Stream Player 3D" -msgstr "" +msgstr "Player de Stream 3D" #: editor/spatial_editor_gizmos.cpp msgid "Change AudioStreamPlayer3D Emission Angle" @@ -16178,7 +16010,7 @@ msgstr "Alterar o Ângulo de Emissão do AudioStreamPlayer3D" #: platform/osx/export/export.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Camera" -msgstr "" +msgstr "Câmera" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" @@ -16190,7 +16022,7 @@ msgstr "Alterar Tamanho da Câmera" #: editor/spatial_editor_gizmos.cpp msgid "Visibility Notifier" -msgstr "" +msgstr "Notificador de Visibilidade" #: editor/spatial_editor_gizmos.cpp msgid "Change Notifier AABB" @@ -16248,9 +16080,8 @@ msgid "Change Ray Shape Length" msgstr "Alterar o Comprimento da Forma do Raio" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Edge" -msgstr "Modo Navegação" +msgstr "Bordas de Navegação" #: editor/spatial_editor_gizmos.cpp #, fuzzy @@ -16258,30 +16089,28 @@ msgid "Navigation Edge Disabled" msgstr "Modo Navegação" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Solid" -msgstr "Modo Navegação" +msgstr "Navegação Sólida" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Solid Disabled" -msgstr "Modo Navegação" +msgstr "Navegação Sólida Desabilitada" #: editor/spatial_editor_gizmos.cpp msgid "Joint Body A" -msgstr "" +msgstr "Corpo de Encaixe A" #: editor/spatial_editor_gizmos.cpp msgid "Joint Body B" -msgstr "" +msgstr "Corpo de Encaixe B" #: editor/spatial_editor_gizmos.cpp msgid "Room Edge" -msgstr "" +msgstr "Canto da Sala" #: editor/spatial_editor_gizmos.cpp msgid "Room Overlap" -msgstr "" +msgstr "Intercessão de Quarto" #: editor/spatial_editor_gizmos.cpp msgid "Set Room Point Position" @@ -16294,11 +16123,11 @@ msgstr "Definir Margem" #: editor/spatial_editor_gizmos.cpp msgid "Portal Edge" -msgstr "" +msgstr "Canto do Portal" #: editor/spatial_editor_gizmos.cpp msgid "Portal Arrow" -msgstr "" +msgstr "Seta do Portal" #: editor/spatial_editor_gizmos.cpp msgid "Set Portal Point Position" @@ -16306,7 +16135,7 @@ msgstr "Definir Posição Do Ponto Do Portal" #: editor/spatial_editor_gizmos.cpp msgid "Portal Front" -msgstr "" +msgstr "Frente do Portal" #: editor/spatial_editor_gizmos.cpp #, fuzzy @@ -16354,12 +16183,12 @@ msgstr "Criar Polígono de Oclusão" #: main/main.cpp msgid "Godot Physics" -msgstr "" +msgstr "Godot Physics" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp msgid "Use BVH" -msgstr "" +msgstr "Usar BVH" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp @@ -16382,37 +16211,36 @@ msgid "RID Pool Prealloc" msgstr "" #: main/main.cpp -#, fuzzy msgid "Debugger stdout" -msgstr "Depurador" +msgstr "Depurador stdout" #: main/main.cpp msgid "Max Chars Per Second" -msgstr "" +msgstr "Máximo de Caracteres por Segundo" #: main/main.cpp msgid "Max Messages Per Frame" -msgstr "" +msgstr "Máximo de Mensagens por Quadro" #: main/main.cpp msgid "Max Errors Per Second" -msgstr "" +msgstr "Máximo de Erros por Segundo" #: main/main.cpp msgid "Max Warnings Per Second" -msgstr "" +msgstr "Máximo de Alertas Por Segundo" #: main/main.cpp msgid "Flush stdout On Print" -msgstr "" +msgstr "Limpar stdout ao Fazer Print" #: main/main.cpp servers/visual_server.cpp msgid "Logging" -msgstr "" +msgstr "Registrando Log" #: main/main.cpp msgid "File Logging" -msgstr "" +msgstr "Registrando Log de Arquivos" #: main/main.cpp #, fuzzy @@ -16426,11 +16254,11 @@ msgstr "Copiar Caminho" #: main/main.cpp msgid "Max Log Files" -msgstr "" +msgstr "Máximo Log de Arquivos" #: main/main.cpp msgid "Driver" -msgstr "" +msgstr "Driver" #: main/main.cpp msgid "Driver Name" @@ -16438,41 +16266,39 @@ msgstr "Nome do Driver" #: main/main.cpp msgid "Fallback To GLES2" -msgstr "" +msgstr "Utilizar GLES2 Como Fallback" #: main/main.cpp msgid "Use Nvidia Rect Flicker Workaround" -msgstr "" +msgstr "Utilizar a Gambiarra \"Nvidia Rect Flicker\"" #: main/main.cpp msgid "DPI" -msgstr "" +msgstr "DPI" #: main/main.cpp msgid "Allow hiDPI" -msgstr "" +msgstr "Permitir hiDPI" #: main/main.cpp -#, fuzzy msgid "V-Sync" -msgstr "Sincronizar" +msgstr "Sincronização Vertical (V-Sync)" #: main/main.cpp -#, fuzzy msgid "Use V-Sync" -msgstr "Use Encaixar" +msgstr "Usar Sincronização Vertical (V-Sync)" #: main/main.cpp msgid "Per Pixel Transparency" -msgstr "" +msgstr "Transparência por Pixel" #: main/main.cpp msgid "Allowed" -msgstr "" +msgstr "Permitido" #: main/main.cpp msgid "Intended Usage" -msgstr "" +msgstr "Intenção de Uso" #: main/main.cpp #, fuzzy @@ -16480,13 +16306,12 @@ msgid "Framebuffer Allocation" msgstr "Seleção de Frame" #: main/main.cpp platform/uwp/os_uwp.cpp -#, fuzzy msgid "Energy Saving" -msgstr "Erro ao salvar" +msgstr "Economia de Energia" #: main/main.cpp msgid "Threads" -msgstr "" +msgstr "Threads" #: main/main.cpp servers/physics_2d/physics_2d_server_wrap_mt.h #, fuzzy @@ -16499,19 +16324,17 @@ msgstr "" #: main/main.cpp msgid "Handheld" -msgstr "" +msgstr "Portátil (Handheld)" #: main/main.cpp platform/javascript/export/export.cpp #: platform/uwp/export/export.cpp -#, fuzzy msgid "Orientation" -msgstr "Documentação Online" +msgstr "Orientação" #: main/main.cpp scene/gui/scroll_container.cpp scene/gui/text_edit.cpp #: scene/main/scene_tree.cpp scene/register_scene_types.cpp -#, fuzzy msgid "Common" -msgstr "Comunidade" +msgstr "Comum" #: main/main.cpp #, fuzzy @@ -16519,35 +16342,34 @@ msgid "Physics FPS" msgstr "Frame de Física %" #: main/main.cpp -#, fuzzy msgid "Force FPS" -msgstr "Forçar Push" +msgstr "Forçar FPS" #: main/main.cpp msgid "Enable Pause Aware Picking" -msgstr "" +msgstr "Habilitar Escolha que é Ciente à Pausas" #: main/main.cpp scene/gui/item_list.cpp scene/gui/popup_menu.cpp #: scene/gui/scroll_container.cpp scene/gui/text_edit.cpp scene/gui/tree.cpp #: scene/main/viewport.cpp scene/register_scene_types.cpp msgid "GUI" -msgstr "" +msgstr "GUI (Interface Gráfica de Usuário)" #: main/main.cpp msgid "Drop Mouse On GUI Input Disabled" -msgstr "" +msgstr "Desabilitar Mouse quando GUI Input estiver Desabilitad" #: main/main.cpp msgid "stdout" -msgstr "" +msgstr "stdout" #: main/main.cpp msgid "Print FPS" -msgstr "" +msgstr "Mostrar FPS" #: main/main.cpp msgid "Verbose stdout" -msgstr "" +msgstr "stdout Verboso" #: main/main.cpp scene/main/scene_tree.cpp scene/resources/multimesh.cpp #, fuzzy @@ -16555,9 +16377,8 @@ msgid "Physics Interpolation" msgstr "Modo de Interpolação" #: main/main.cpp -#, fuzzy msgid "Enable Warnings" -msgstr "Habilitar Filtragem" +msgstr "Habilitar Avisos" #: main/main.cpp #, fuzzy @@ -16566,19 +16387,19 @@ msgstr "Seleção de Frame" #: main/main.cpp msgid "Low Processor Mode" -msgstr "" +msgstr "Modo Processamento Baixo" #: main/main.cpp msgid "Delta Sync After Draw" -msgstr "" +msgstr "Sincronizar Delta Após o Draw" #: main/main.cpp msgid "iOS" -msgstr "" +msgstr "iOS" #: main/main.cpp msgid "Hide Home Indicator" -msgstr "" +msgstr "Esconder Indicador de Home" #: main/main.cpp #, fuzzy @@ -16592,16 +16413,15 @@ msgstr "Ponto" #: main/main.cpp msgid "Touch Delay" -msgstr "" +msgstr "Atraso de Touch" #: main/main.cpp servers/visual_server.cpp msgid "GLES3" -msgstr "" +msgstr "GLES3" #: main/main.cpp servers/visual_server.cpp -#, fuzzy msgid "Shaders" -msgstr "Shader" +msgstr "Shaders" #: main/main.cpp #, fuzzy @@ -16611,30 +16431,28 @@ msgstr "Forçar Fallbacks do Shader" #: main/main.cpp scene/3d/baked_lightmap.cpp scene/3d/camera.cpp #: scene/3d/world_environment.cpp scene/main/scene_tree.cpp #: scene/resources/world.cpp -#, fuzzy msgid "Environment" -msgstr "Visualizar Ambiente" +msgstr "Ambiente" #: main/main.cpp msgid "Default Clear Color" -msgstr "" +msgstr "Cor de Limpeza Padrão" #: main/main.cpp msgid "Boot Splash" -msgstr "" +msgstr "Imagem de Exibição ao Iniciar" #: main/main.cpp -#, fuzzy msgid "Show Image" -msgstr "Mostrar Ossos" +msgstr "Mostrar Imagem" #: main/main.cpp msgid "Image" -msgstr "" +msgstr "Imagem" #: main/main.cpp msgid "Fullsize" -msgstr "" +msgstr "Tamanho Inteiro" #: main/main.cpp scene/resources/dynamic_font.cpp msgid "Use Filter" @@ -16646,13 +16464,12 @@ msgid "BG Color" msgstr "Cores" #: main/main.cpp -#, fuzzy msgid "macOS Native Icon" -msgstr "Definir ícone de telha" +msgstr "Ícone Nativo macOS" #: main/main.cpp msgid "Windows Native Icon" -msgstr "" +msgstr "Ícone Windows Nativo" #: main/main.cpp msgid "Buffering" @@ -16660,29 +16477,27 @@ msgstr "" #: main/main.cpp msgid "Agile Event Flushing" -msgstr "" +msgstr "Limpeza de Eventos Agil" #: main/main.cpp msgid "Emulate Touch From Mouse" -msgstr "" +msgstr "Simular Toque à Partir do Mouse" #: main/main.cpp msgid "Emulate Mouse From Touch" -msgstr "" +msgstr "Simular Mouse à Partir do Touch" #: main/main.cpp -#, fuzzy msgid "Mouse Cursor" -msgstr "Botão do Mouse" +msgstr "Cursor do Mouse" #: main/main.cpp -#, fuzzy msgid "Custom Image" -msgstr "Recortar Nós" +msgstr "Imagem Personalizada" #: main/main.cpp msgid "Custom Image Hotspot" -msgstr "" +msgstr "Imagem Personalizada de Hotspot" #: main/main.cpp msgid "Tooltip Position Offset" @@ -16694,9 +16509,8 @@ msgid "Debugger Agent" msgstr "Depurador" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp -#, fuzzy msgid "Wait For Debugger" -msgstr "Depurador" +msgstr "Esperar pelo Depurador" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp msgid "Wait Timeout" @@ -16704,11 +16518,11 @@ msgstr "Tempo Limite de Espera" #: main/main.cpp msgid "Runtime" -msgstr "" +msgstr "Tempo de Execução" #: main/main.cpp msgid "Unhandled Exception Policy" -msgstr "" +msgstr "Politica de Tratamento Exceções" #: main/main.cpp #, fuzzy @@ -16717,22 +16531,20 @@ msgstr "Localizar Tipo de Nó" #: main/main.cpp scene/gui/texture_progress.cpp #: scene/gui/viewport_container.cpp -#, fuzzy msgid "Stretch" -msgstr "Buscar" +msgstr "Esticar" #: main/main.cpp -#, fuzzy msgid "Aspect" -msgstr "Inspetor" +msgstr "Aspecto" #: main/main.cpp msgid "Shrink" -msgstr "" +msgstr "Encolher" #: main/main.cpp scene/main/scene_tree.cpp msgid "Auto Accept Quit" -msgstr "" +msgstr "Aceitar Sair Automaticamente" #: main/main.cpp scene/main/scene_tree.cpp #, fuzzy @@ -16746,15 +16558,15 @@ msgstr "Encaixar nos Lados do Nó" #: main/main.cpp msgid "Dynamic Fonts" -msgstr "" +msgstr "Fontes Dinâmicas" #: main/main.cpp msgid "Use Oversampling" -msgstr "" +msgstr "Utilizar Oversampling" #: modules/bullet/register_types.cpp modules/bullet/space_bullet.cpp msgid "Active Soft World" -msgstr "" +msgstr "Ativar Mundo Macio" #: modules/csg/csg_gizmos.cpp msgid "CSG" @@ -16777,35 +16589,30 @@ msgid "Change Torus Outer Radius" msgstr "Alterar Raio Externo do Toro" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Operation" -msgstr "Opções" +msgstr "Operação" #: modules/csg/csg_shape.cpp msgid "Calculate Tangents" -msgstr "" +msgstr "Calcular Tangentes" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Use Collision" -msgstr "Colisão" +msgstr "Usar Colisão" #: modules/csg/csg_shape.cpp servers/physics_2d_server.cpp -#, fuzzy msgid "Collision Layer" -msgstr "Modo Colisão" +msgstr "Camada de Colisão" #: modules/csg/csg_shape.cpp scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp #: scene/3d/ray_cast.cpp scene/3d/spring_arm.cpp #: scene/resources/navigation_mesh.cpp servers/physics_server.cpp -#, fuzzy msgid "Collision Mask" -msgstr "Modo Colisão" +msgstr "Máscara de Colisão" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Invert Faces" -msgstr "Converter Maíusculas/Minúsculas" +msgstr "Inverter Faces" #: modules/csg/csg_shape.cpp scene/2d/navigation_agent_2d.cpp #: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_agent.cpp @@ -16823,14 +16630,12 @@ msgid "Radial Segments" msgstr "Segmentos Radiais" #: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Rings" -msgstr "Avisos" +msgstr "Anéis" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Smooth Faces" -msgstr "Passo suave" +msgstr "Suavizar Faces" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16839,7 +16644,7 @@ msgstr "Mostrar Guias" #: modules/csg/csg_shape.cpp msgid "Cone" -msgstr "" +msgstr "Cone" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16853,27 +16658,25 @@ msgstr "Alterar Raio Externo do Toro" #: modules/csg/csg_shape.cpp msgid "Ring Sides" -msgstr "" +msgstr "Lados de Anel" #: modules/csg/csg_shape.cpp scene/2d/collision_polygon_2d.cpp #: scene/2d/light_occluder_2d.cpp scene/2d/polygon_2d.cpp #: scene/3d/collision_polygon.cpp -#, fuzzy msgid "Polygon" -msgstr "Polígonos" +msgstr "Polígono" #: modules/csg/csg_shape.cpp msgid "Spin Degrees" -msgstr "" +msgstr "Graus de Rotação" #: modules/csg/csg_shape.cpp msgid "Spin Sides" -msgstr "" +msgstr "Lados de Rotação" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Node" -msgstr "Colar Nós" +msgstr "Caminho do Nó" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16882,11 +16685,11 @@ msgstr "Criar Vertex Interno" #: modules/csg/csg_shape.cpp msgid "Path Interval" -msgstr "" +msgstr "Intervalo de Caminho" #: modules/csg/csg_shape.cpp msgid "Path Simplify Angle" -msgstr "" +msgstr "Ângulo de Simplificação de Caminho" #: modules/csg/csg_shape.cpp msgid "Path Rotation" @@ -16911,58 +16714,52 @@ msgid "Path Joined" msgstr "Caminho Unido" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Compression Mode" -msgstr "Modo Colisão" +msgstr "Modo de Compressão" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Transfer Channel" -msgstr "Alteração de Transformação" +msgstr "Transferir Canal" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Channel Count" -msgstr "Instância" +msgstr "Quantidade de Canais" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Always Ordered" -msgstr "Sempre Mostrar Grade" +msgstr "Sempre Ordenado" #: modules/enet/networked_multiplayer_enet.cpp msgid "Server Relay" -msgstr "" +msgstr "Retransmissor de Servidor" #: modules/enet/networked_multiplayer_enet.cpp msgid "DTLS Verify" -msgstr "" +msgstr "Virificar DTLS" #: modules/enet/networked_multiplayer_enet.cpp msgid "DTLS Hostname" -msgstr "" +msgstr "Nome de Host DTLS" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Use DTLS" -msgstr "Use Encaixar" +msgstr "Usar DTLS" #: modules/fbx/editor_scene_importer_fbx.cpp msgid "FBX" -msgstr "" +msgstr "FBX" #: modules/fbx/editor_scene_importer_fbx.cpp msgid "Use FBX" -msgstr "" +msgstr "Utilizar FBX" #: modules/gdnative/gdnative.cpp msgid "Config File" msgstr "Arquivo de Configuração" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Load Once" -msgstr "Carregar Recurso" +msgstr "Carregar Apenas uma Vez" #: modules/gdnative/gdnative.cpp #: modules/visual_script/visual_script_func_nodes.cpp @@ -16975,9 +16772,8 @@ msgid "Symbol Prefix" msgstr "Prefixo do Símbolo" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Reloadable" -msgstr "Recarregar" +msgstr "Recarregável" #: modules/gdnative/gdnative.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp @@ -17042,9 +16838,8 @@ msgid "Script Class" msgstr "Classe do Script" #: modules/gdnative/nativescript/nativescript.cpp -#, fuzzy msgid "Icon Path" -msgstr "Habilitar" +msgstr "Caminho para Ícone" #: modules/gdnative/register_types.cpp msgid "GDNative" @@ -17057,7 +16852,7 @@ msgstr "GDScript" #: modules/gdscript/editor/gdscript_highlighter.cpp msgid "Function Definition Color" -msgstr "" +msgstr "Cor de Definição de Função" #: modules/gdscript/editor/gdscript_highlighter.cpp #, fuzzy @@ -17066,19 +16861,19 @@ msgstr "Copiar Caminho do Nó" #: modules/gdscript/gdscript.cpp modules/visual_script/visual_script.cpp msgid "Max Call Stack" -msgstr "" +msgstr "Tamanho Máximo da Pilha de Chamadas de Função" #: modules/gdscript/gdscript.cpp msgid "Treat Warnings As Errors" -msgstr "" +msgstr "Trate Alertas como Erros" #: modules/gdscript/gdscript.cpp msgid "Exclude Addons" -msgstr "" +msgstr "Excluir Addons" #: modules/gdscript/gdscript.cpp msgid "Autocomplete Setters And Getters" -msgstr "" +msgstr "Auto Completar Setters e Getters" #: modules/gdscript/gdscript_functions.cpp msgid "Step argument is zero!" @@ -17129,11 +16924,11 @@ msgstr "Não foi possível resolver" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Show Native Symbols In Editor" -msgstr "" +msgstr "Exibir Simbolos Nativos no Editor" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Use Thread" -msgstr "" +msgstr "Utilize Thread" #: modules/gltf/editor_scene_exporter_gltf_plugin.cpp msgid "Export Mesh GLTF2" @@ -17153,9 +16948,8 @@ msgid "Byte Offset" msgstr "Deslocamento do Byte" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Component Type" -msgstr "Componentes" +msgstr "Tipo do Componente" #: modules/gltf/gltf_accessor.cpp #, fuzzy @@ -17167,14 +16961,12 @@ msgid "Count" msgstr "Quantidade" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Min" -msgstr "MiB" +msgstr "Min" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Max" -msgstr "Misturar" +msgstr "Max" #: modules/gltf/gltf_accessor.cpp #, fuzzy @@ -17216,9 +17008,8 @@ msgid "Byte Stride" msgstr "" #: modules/gltf/gltf_buffer_view.cpp -#, fuzzy msgid "Indices" -msgstr "Todos os dispositivos" +msgstr "Índices" #: modules/gltf/gltf_camera.cpp msgid "FOV Size" @@ -17241,19 +17032,17 @@ msgstr "Linear" #: scene/resources/environment.cpp scene/resources/material.cpp #: scene/resources/particles_material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp -#, fuzzy msgid "Color" -msgstr "Cores" +msgstr "Cor" #: modules/gltf/gltf_light.cpp scene/3d/reflection_probe.cpp #: scene/resources/environment.cpp msgid "Intensity" -msgstr "" +msgstr "Intensidade" #: modules/gltf/gltf_light.cpp scene/2d/light_2d.cpp scene/3d/light.cpp -#, fuzzy msgid "Range" -msgstr "Alterar" +msgstr "Intervalo" #: modules/gltf/gltf_light.cpp msgid "Inner Cone Angle" @@ -17284,35 +17073,31 @@ msgstr "Plataforma" #: modules/gltf/gltf_node.cpp scene/3d/mesh_instance.cpp msgid "Skin" -msgstr "" +msgstr "Skin" #: modules/gltf/gltf_node.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Translation" -msgstr "Traduções" +msgstr "Tradução" #: modules/gltf/gltf_node.cpp -#, fuzzy msgid "Children" -msgstr "Filhos Editáveis" +msgstr "Filhos" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints" -msgstr "Ponto" +msgstr "Pontos" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp msgid "Roots" -msgstr "" +msgstr "Raízes" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_state.cpp msgid "Unique Names" -msgstr "" +msgstr "Nomes Únicos" #: modules/gltf/gltf_skeleton.cpp -#, fuzzy msgid "Godot Bone Node" -msgstr "Nó TimeSeek" +msgstr "Nó de Osso Godot" #: modules/gltf/gltf_skin.cpp #, fuzzy @@ -17320,9 +17105,8 @@ msgid "Skin Root" msgstr "Nova Raiz de Cena" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints Original" -msgstr "Origem do Foco" +msgstr "Pontos Originais" #: modules/gltf/gltf_skin.cpp msgid "Inverse Binds" @@ -17367,12 +17151,11 @@ msgstr "" #: modules/gltf/gltf_state.cpp msgid "Json" -msgstr "" +msgstr "Json" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Major Version" -msgstr "Versão" +msgstr "Versão Importante" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17402,28 +17185,25 @@ msgid "Scene Name" msgstr "Nome da Cena" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Root Nodes" -msgstr "Nome do nó raiz" +msgstr "Nós Raízes" #: modules/gltf/gltf_state.cpp scene/2d/particles_2d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_progress.cpp -#, fuzzy msgid "Textures" -msgstr "Funcionalidades" +msgstr "Texturas" #: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp msgid "Images" -msgstr "" +msgstr "Imagens" #: modules/gltf/gltf_state.cpp msgid "Cameras" -msgstr "" +msgstr "Câmeras" #: modules/gltf/gltf_state.cpp servers/visual_server.cpp -#, fuzzy msgid "Lights" -msgstr "Luz" +msgstr "Luzes" #: modules/gltf/gltf_state.cpp msgid "Unique Animation Names" @@ -17434,9 +17214,8 @@ msgid "Skeletons" msgstr "Esqueletos" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeleton To Node" -msgstr "Selecione um Nó" +msgstr "Esqueleto Para Nó" #: modules/gltf/gltf_state.cpp msgid "Animations" @@ -17463,7 +17242,7 @@ msgstr "Faça mapas de luz" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp msgid "Cell" -msgstr "" +msgstr "Célula" #: modules/gridmap/grid_map.cpp #, fuzzy @@ -17471,25 +17250,22 @@ msgid "Octant Size" msgstr "Visão Frontal" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center X" -msgstr "Centro" +msgstr "Centro X" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Y" -msgstr "Centro" +msgstr "Centro Y" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Z" -msgstr "Centro" +msgstr "Centro Z" #: modules/gridmap/grid_map.cpp scene/2d/collision_object_2d.cpp #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp #: scene/resources/material.cpp msgid "Mask" -msgstr "" +msgstr "Máscara" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp #, fuzzy @@ -17500,9 +17276,8 @@ msgstr "Navegação" #: scene/2d/navigation_agent_2d.cpp scene/2d/navigation_polygon.cpp #: scene/2d/tile_map.cpp scene/3d/navigation.cpp scene/3d/navigation_agent.cpp #: scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Navigation Layers" -msgstr "Modo Navegação" +msgstr "Camadas da Navegação" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Plane" @@ -17804,7 +17579,7 @@ msgstr "Pronto!" #: modules/opensimplex/noise_texture.cpp msgid "Seamless" -msgstr "" +msgstr "Sem Emenda" #: modules/opensimplex/noise_texture.cpp msgid "As Normal Map" @@ -17824,7 +17599,7 @@ msgstr "Deslocamento do Ruído" #: modules/opensimplex/open_simplex_noise.cpp msgid "Octaves" -msgstr "" +msgstr "Oitavas" #: modules/opensimplex/open_simplex_noise.cpp msgid "Period" @@ -17841,7 +17616,7 @@ msgstr "" #: modules/regex/regex.cpp msgid "Subject" -msgstr "" +msgstr "Sujeito" #: modules/regex/regex.cpp #, fuzzy @@ -18293,7 +18068,7 @@ msgstr "Iterador" #: modules/visual_script/visual_script_flow_control.cpp msgid "for (elem) in (input):" -msgstr "" +msgstr "para (elem) em (input):" #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable:" @@ -18327,7 +18102,7 @@ msgstr "Switch" #: modules/visual_script/visual_script_flow_control.cpp msgid "'input' is:" -msgstr "" +msgstr "'input' é:" #: modules/visual_script/visual_script_flow_control.cpp msgid "Type Cast" @@ -18579,7 +18354,7 @@ msgstr "Chamadas" #: modules/visual_script/visual_script_nodes.cpp scene/gui/graph_node.cpp msgid "Title" -msgstr "" +msgstr "Título" #: modules/visual_script/visual_script_nodes.cpp #, fuzzy @@ -18658,7 +18433,7 @@ msgstr "Modo Prioridade" #: modules/webrtc/webrtc_data_channel.h msgid "WebRTC" -msgstr "" +msgstr "WebRTC" #: modules/webrtc/webrtc_data_channel.h #, fuzzy @@ -18892,7 +18667,7 @@ msgstr "Inspecionar a Instância Anterior" #: platform/android/export/export_plugin.cpp msgid "Code" -msgstr "" +msgstr "Código" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp #, fuzzy @@ -18985,7 +18760,7 @@ msgstr "Interface de Usuário" #: platform/android/export/export_plugin.cpp msgid "Allow" -msgstr "" +msgstr "Permitir" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp #, fuzzy @@ -19003,7 +18778,7 @@ msgstr "Expressão" #: platform/android/export/export_plugin.cpp msgid "Salt" -msgstr "" +msgstr "Sal" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -19298,10 +19073,8 @@ msgstr "" "do projeto" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files to gradle project." -msgstr "" -"Não foi possível exportar os arquivos do projeto ao projeto do gradle\n" +msgstr "Não foi possível exportar os arquivos do projeto ao projeto do gradle" #: platform/android/export/export_plugin.cpp msgid "Could not write expansion package file!" @@ -19385,19 +19158,19 @@ msgstr "" #: platform/iphone/export/export.cpp msgid "iPhone 2436 X 1125" -msgstr "" +msgstr "IPhone 2436 X 1125" #: platform/iphone/export/export.cpp msgid "iPhone 2208 X 1242" -msgstr "" +msgstr "iPhone 2208 X 1242" #: platform/iphone/export/export.cpp msgid "iPad 1024 X 768" -msgstr "" +msgstr "iPad 1024 X 768" #: platform/iphone/export/export.cpp msgid "iPad 2048 X 1536" -msgstr "" +msgstr "iPad 2048 X 1536" #: platform/iphone/export/export.cpp msgid "Portrait Launch Screens" @@ -19405,31 +19178,31 @@ msgstr "" #: platform/iphone/export/export.cpp msgid "iPhone 640 X 960" -msgstr "" +msgstr "iPhone 640 X 960" #: platform/iphone/export/export.cpp msgid "iPhone 640 X 1136" -msgstr "" +msgstr "iPhone 640 X 1136" #: platform/iphone/export/export.cpp msgid "iPhone 750 X 1334" -msgstr "" +msgstr "iPhone 750 X 1334" #: platform/iphone/export/export.cpp msgid "iPhone 1125 X 2436" -msgstr "" +msgstr "iPhone 1125 X 2436" #: platform/iphone/export/export.cpp msgid "iPad 768 X 1024" -msgstr "" +msgstr "iPad 768 X 1024" #: platform/iphone/export/export.cpp msgid "iPad 1536 X 2048" -msgstr "" +msgstr "iPad 1536 X 2048" #: platform/iphone/export/export.cpp msgid "iPhone 1242 X 2208" -msgstr "" +msgstr "iPhone 1242 X 2208" #: platform/iphone/export/export.cpp msgid "App Store Team ID" @@ -19466,7 +19239,7 @@ msgstr "" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp msgid "Info" -msgstr "" +msgstr "Informação" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp msgid "Identifier" @@ -19536,23 +19309,23 @@ msgstr "Descrições da Propriedade" #: platform/iphone/export/export.cpp msgid "iPhone 120 X 120" -msgstr "" +msgstr "iPhone 120 X 120" #: platform/iphone/export/export.cpp msgid "iPhone 180 X 180" -msgstr "" +msgstr "iPhone 180 X 180" #: platform/iphone/export/export.cpp msgid "iPad 76 X 76" -msgstr "" +msgstr "iPad 76 X 76" #: platform/iphone/export/export.cpp msgid "iPad 152 X 152" -msgstr "" +msgstr "iPad 152 X 152" #: platform/iphone/export/export.cpp msgid "iPad 167 X 167" -msgstr "" +msgstr "iPad 167 X 167" #: platform/iphone/export/export.cpp msgid "App Store 1024 X 1024" @@ -19636,14 +19409,12 @@ msgid "Could not open template for export: \"%s\"." msgstr "Não foi possível abrir o modelo para exportação: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Invalid export template: \"%s\"." -msgstr "Template de exportação inválido:" +msgstr "Template de exportação inválido: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not write file: \"%s\"." -msgstr "Não foi possível escrever o arquivo:" +msgstr "Não foi possível escrever o arquivo: \"%s\"." #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #, fuzzy @@ -19656,7 +19427,7 @@ msgstr "Não foi possível ler o arquivo: \"%s\"." #: platform/javascript/export/export.cpp msgid "PWA" -msgstr "" +msgstr "PWA" #: platform/javascript/export/export.cpp msgid "Variant" @@ -19674,15 +19445,15 @@ msgstr "Expressão" #: platform/javascript/export/export.cpp msgid "For Desktop" -msgstr "" +msgstr "Para Desktop" #: platform/javascript/export/export.cpp msgid "For Mobile" -msgstr "" +msgstr "Para Mobile" #: platform/javascript/export/export.cpp msgid "HTML" -msgstr "" +msgstr "HTML" #: platform/javascript/export/export.cpp #, fuzzy @@ -19703,8 +19474,9 @@ msgid "Canvas Resize Policy" msgstr "" #: platform/javascript/export/export.cpp +#, fuzzy msgid "Focus Canvas On Start" -msgstr "" +msgstr "Focar Canvas ao Iniciar" #: platform/javascript/export/export.cpp #, fuzzy @@ -19713,11 +19485,11 @@ msgstr "Filtrar sinais" #: platform/javascript/export/export.cpp msgid "Progressive Web App" -msgstr "" +msgstr "Progressive Web App" #: platform/javascript/export/export.cpp msgid "Offline Page" -msgstr "" +msgstr "Página Offline" #: platform/javascript/export/export.cpp msgid "Icon 144 X 144" @@ -19736,9 +19508,8 @@ msgid "Could not read HTML shell: \"%s\"." msgstr "Não foi possível ler o shell HTML: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not create HTTP server directory: %s." -msgstr "Não foi possível criar o diretório do servidor HTTP:" +msgstr "Não foi possível criar o diretório do servidor HTTP: \"%s\"." #: platform/javascript/export/export.cpp msgid "Error starting HTTP server: %d." @@ -19746,7 +19517,7 @@ msgstr "Erro ao iniciar o servidor HTTP: %d." #: platform/javascript/export/export.cpp msgid "Web" -msgstr "" +msgstr "Web" #: platform/javascript/export/export.cpp msgid "HTTP Host" @@ -19763,7 +19534,7 @@ msgstr "Use Encaixar" #: platform/javascript/export/export.cpp msgid "SSL Key" -msgstr "" +msgstr "Chave SSL" #: platform/osx/export/codesign.cpp msgid "Can't get filesystem access." @@ -19803,7 +19574,7 @@ msgstr "Caminho base inválido." #: platform/osx/export/codesign.cpp msgid "Already signed!" -msgstr "" +msgstr "Já assinado!" #: platform/osx/export/codesign.cpp #, fuzzy @@ -19843,7 +19614,7 @@ msgstr "" #: platform/osx/export/codesign.cpp msgid "Unknown object type." -msgstr "" +msgstr "Tipo de objeto desconhecido." #: platform/osx/export/export.cpp msgid "App Category" @@ -19851,7 +19622,7 @@ msgstr "Categoria do Aplicativo" #: platform/osx/export/export.cpp msgid "High Res" -msgstr "" +msgstr "Alta Resolução" #: platform/osx/export/export.cpp #, fuzzy @@ -19931,7 +19702,7 @@ msgstr "Recortar Nós" #: platform/osx/export/export.cpp msgid "Allow JIT Code Execution" -msgstr "" +msgstr "Permitir Execução de Código JIT" #: platform/osx/export/export.cpp msgid "Allow Unsigned Executable Memory" @@ -19953,7 +19724,7 @@ msgstr "Adicionar Entrada" #: platform/osx/export/export.cpp msgid "Address Book" -msgstr "" +msgstr "Contatos" #: platform/osx/export/export.cpp msgid "Calendars" @@ -19995,7 +19766,7 @@ msgstr "Dispositivo" #: platform/osx/export/export.cpp msgid "Device Bluetooth" -msgstr "" +msgstr "Bluetooth do Dispositivo" #: platform/osx/export/export.cpp #, fuzzy @@ -20067,6 +19838,8 @@ msgid "" "You can check progress manually by opening a Terminal and running the " "following command:" msgstr "" +"Você pode verificar o progresso manualmente abrindo um Terminal e rodando o " +"seguinte comando:" #: platform/osx/export/export.cpp msgid "" @@ -20096,6 +19869,8 @@ msgid "" "Could not start codesign executable, make sure Xcode command line tools are " "installed." msgstr "" +"Não foi possível iniciar o executável codesign, tenha certeza que as " +"utilidades de linha de comando do Xcode estão instaladas." #: platform/osx/export/export.cpp platform/windows/export/export.cpp #, fuzzy @@ -20156,7 +19931,7 @@ msgstr "" #: platform/osx/export/export.cpp msgid "Making PKG" -msgstr "" +msgstr "Criando PKG" #: platform/osx/export/export.cpp msgid "" @@ -20170,7 +19945,7 @@ msgstr "" #: platform/osx/export/export.cpp msgid "Making DMG" -msgstr "" +msgstr "Criando DMG" #: platform/osx/export/export.cpp msgid "Code signing DMG" @@ -20178,7 +19953,7 @@ msgstr "" #: platform/osx/export/export.cpp msgid "Making ZIP" -msgstr "" +msgstr "Criando ZIP" #: platform/osx/export/export.cpp msgid "" @@ -20341,7 +20116,7 @@ msgstr "Nome Curto" #: platform/uwp/export/export.cpp msgid "Publisher" -msgstr "" +msgstr "Publicadora" #: platform/uwp/export/export.cpp msgid "Publisher Display Name" @@ -20389,7 +20164,7 @@ msgstr "Revisão" #: platform/uwp/export/export.cpp msgid "Landscape" -msgstr "" +msgstr "Paisagem" #: platform/uwp/export/export.cpp #, fuzzy @@ -20398,11 +20173,11 @@ msgstr "Inverter Horizontalmente" #: platform/uwp/export/export.cpp msgid "Landscape Flipped" -msgstr "" +msgstr "Paisagem Invertido" #: platform/uwp/export/export.cpp msgid "Portrait Flipped" -msgstr "" +msgstr "Retrato Invertido" #: platform/uwp/export/export.cpp #, fuzzy @@ -20504,7 +20279,7 @@ msgstr "Dimensões inválidas da tela de abertura (deve ser 620x300)." #: platform/uwp/export/export.cpp msgid "UWP" -msgstr "" +msgstr "UWP" #: platform/uwp/export/export.cpp platform/windows/export/export.cpp #, fuzzy @@ -20521,13 +20296,13 @@ msgid "Debug Algorithm" msgstr "Depurador" #: platform/windows/export/export.cpp -#, fuzzy msgid "Failed to rename temporary file \"%s\"." -msgstr "Não é possível remover o arquivo temporário:" +msgstr "Falha ao renomear arquivo temporário \"%s\"." #: platform/windows/export/export.cpp +#, fuzzy msgid "Identity Type" -msgstr "" +msgstr "Tipo de Identidade" #: platform/windows/export/export.cpp msgid "Timestamp Server URL" @@ -20567,7 +20342,7 @@ msgstr "Descrição" #: platform/windows/export/export.cpp msgid "Trademarks" -msgstr "" +msgstr "Marca Registrada (Trademarks)" #: platform/windows/export/export.cpp #, fuzzy @@ -20586,15 +20361,15 @@ msgstr "O keystore não foi encontrado, não foi possível exportar." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Extensão inválida." #: platform/windows/export/export.cpp #, fuzzy @@ -20617,15 +20392,15 @@ msgstr "Nome Inválido." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Extensão inválida." #: platform/windows/export/export.cpp msgid "Failed to remove temporary file \"%s\"." @@ -20673,7 +20448,7 @@ msgstr "Nova Janela" #: platform/windows/export/export.cpp msgid "Rcedit" -msgstr "" +msgstr "Rcedit" #: platform/windows/export/export.cpp msgid "Osslsigncode" @@ -20872,7 +20647,7 @@ msgstr "Modo de Movimentação" #: scene/2d/camera_2d.cpp msgid "Limit" -msgstr "" +msgstr "Limite" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp @@ -21172,7 +20947,7 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp msgid "Drawing" -msgstr "" +msgstr "Desenhando" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -21183,7 +20958,7 @@ msgstr "Projetos Locais" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp msgid "Draw Order" -msgstr "" +msgstr "Ordem de Desenho" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21240,7 +21015,7 @@ msgstr "Velocidade" #: scene/resources/particles_material.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp msgid "Angular Velocity" -msgstr "" +msgstr "Velocidade Angular" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21309,7 +21084,7 @@ msgstr "Dvidir Curva" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp scene/3d/light.cpp #: scene/resources/particles_material.cpp msgid "Angle" -msgstr "" +msgstr "Ângulo" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21435,7 +21210,7 @@ msgstr "" #: scene/2d/joints_2d.cpp scene/resources/animation.cpp #: scene/resources/ray_shape.cpp scene/resources/segment_shape_2d.cpp msgid "Length" -msgstr "" +msgstr "Comprimento" #: scene/2d/joints_2d.cpp #, fuzzy @@ -21471,7 +21246,7 @@ msgstr "Região da Textura" #: scene/3d/light.cpp scene/resources/environment.cpp #: scene/resources/material.cpp scene/resources/sky.cpp msgid "Energy" -msgstr "" +msgstr "Energia" #: scene/2d/light_2d.cpp msgid "Z Min" @@ -21549,7 +21324,7 @@ msgstr "Padrão" #: scene/2d/line_2d.cpp scene/resources/texture.cpp msgid "Fill" -msgstr "" +msgstr "Preencher" #: scene/2d/line_2d.cpp scene/resources/texture.cpp #, fuzzy @@ -21894,7 +21669,7 @@ msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Mass" -msgstr "" +msgstr "Massa" #: scene/2d/physics_body_2d.cpp msgid "Inertia" @@ -21943,7 +21718,7 @@ msgstr "Úmido" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Angular" -msgstr "" +msgstr "Angular" #: scene/2d/physics_body_2d.cpp msgid "Applied Forces" @@ -22056,15 +21831,15 @@ msgstr "Criar Nó Shader" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp msgid "Collide With" -msgstr "" +msgstr "Colidir com" #: scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp scene/3d/ray_cast.cpp msgid "Areas" -msgstr "" +msgstr "Áreas" #: scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp scene/3d/ray_cast.cpp msgid "Bodies" -msgstr "" +msgstr "Corpos" #: scene/2d/remote_transform_2d.cpp msgid "Path property must point to a valid Node2D node to work." @@ -22306,15 +22081,15 @@ msgstr "Nó de Animação" #: scene/3d/audio_stream_player_3d.cpp msgid "Unit dB" -msgstr "" +msgstr "Unidade dB" #: scene/3d/audio_stream_player_3d.cpp msgid "Unit Size" -msgstr "" +msgstr "Tamanho da Unidade" #: scene/3d/audio_stream_player_3d.cpp msgid "Max dB" -msgstr "" +msgstr "Max dB" #: scene/3d/audio_stream_player_3d.cpp msgid "Out Of Range Mode" @@ -22362,7 +22137,7 @@ msgstr "Empacotando" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/reflection_probe.cpp msgid "Interior" -msgstr "" +msgstr "Interior" #: scene/3d/baked_lightmap.cpp msgid "Finding meshes and lights" @@ -22413,7 +22188,7 @@ msgstr "Usar Redutor de Ruído" #: scene/3d/baked_lightmap.cpp scene/resources/texture.cpp msgid "Use HDR" -msgstr "" +msgstr "Usar HDR" #: scene/3d/baked_lightmap.cpp #, fuzzy @@ -22512,7 +22287,7 @@ msgstr "Mais próximo" #: scene/3d/camera.cpp msgid "Far" -msgstr "" +msgstr "Longe" #: scene/3d/camera.cpp scene/3d/collision_polygon.cpp scene/3d/spring_arm.cpp #: scene/gui/control.cpp scene/resources/default_theme/default_theme.cpp @@ -22764,9 +22539,8 @@ msgid "Font" msgstr "Fontes" #: scene/3d/label_3d.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Horizontal Alignment" -msgstr "Horizontal:" +msgstr "Alinhamento Horizontal" #: scene/3d/label_3d.cpp #, fuzzy @@ -22877,6 +22651,8 @@ msgid "" "be removed in a future version. Use 'NavigationServer.map_get_path()' " "instead." msgstr "" +"O nó 'Navigation' e 'Navigation.get_simple_path()' estão depreciados e serão " +"removidos em versões futuras. Use 'NavigationServer.map_get_path()' no lugar." #: scene/3d/navigation.cpp scene/resources/curve.cpp #, fuzzy @@ -23131,15 +22907,15 @@ msgstr "Animação" #: scene/3d/physics_body.cpp msgid "X" -msgstr "" +msgstr "X" #: scene/3d/physics_body.cpp msgid "Y" -msgstr "" +msgstr "Y" #: scene/3d/physics_body.cpp msgid "Z" -msgstr "" +msgstr "Z" #: scene/3d/physics_body.cpp #, fuzzy @@ -23456,7 +23232,7 @@ msgstr "Depurador" #: scene/3d/ray_cast.cpp scene/resources/style_box.cpp msgid "Thickness" -msgstr "" +msgstr "Espessura" #: scene/3d/reflection_probe.cpp scene/main/viewport.cpp #, fuzzy @@ -23563,7 +23339,7 @@ msgstr "Só Deve existir um RoomManager na SceneTree." #: scene/3d/room_manager.cpp msgid "Main" -msgstr "" +msgstr "Principal" #: scene/3d/room_manager.cpp scene/animation/animation_blend_tree.cpp #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp @@ -23789,7 +23565,7 @@ msgstr "Manter Transformação Global" #: scene/3d/spatial.cpp msgid "Matrix" -msgstr "" +msgstr "Matriz" #: scene/3d/spatial.cpp #, fuzzy @@ -23807,7 +23583,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp msgid "Opacity" -msgstr "" +msgstr "Opacidade" #: scene/3d/sprite_3d.cpp scene/resources/material.cpp msgid "Transparent" @@ -23906,9 +23682,8 @@ msgid "Cast Shadow" msgstr "Criar Nó Shader" #: scene/3d/visual_instance.cpp -#, fuzzy msgid "Extra Cull Margin" -msgstr "Argumentos de Chamada Extras:" +msgstr "Margem de Descarte Extra" #: scene/3d/visual_instance.cpp #, fuzzy @@ -23930,9 +23705,8 @@ msgstr "" #: scene/3d/visual_instance.cpp scene/animation/skeleton_ik.cpp #: scene/resources/material.cpp -#, fuzzy msgid "Min Distance" -msgstr "Escolha uma Distância:" +msgstr "Distância Mínima" #: scene/3d/visual_instance.cpp msgid "Min Hysteresis" @@ -23979,33 +23753,28 @@ msgid "Mix Mode" msgstr "Nó Mix" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Fadein Time" -msgstr "Tempo do X-Fade (s):" +msgstr "Tempo de Esmaecer de Entrada" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Fadeout Time" -msgstr "Tempo do X-Fade (s):" +msgstr "Tempo de Esmaecer de Saída" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Auto Restart" -msgstr "Reinício Automático:" +msgstr "Reinício Automático" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Autorestart" -msgstr "Reinício Automático:" +msgstr "Reinício Automático" #: scene/animation/animation_blend_tree.cpp msgid "Delay" -msgstr "" +msgstr "Atraso" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Random Delay" -msgstr "Inclinação aleatória:" +msgstr "Atraso Aleatório" #: scene/animation/animation_blend_tree.cpp #, fuzzy @@ -24029,9 +23798,8 @@ msgstr "Adicionar porta de entrada" #: scene/animation/animation_blend_tree.cpp #: scene/animation/animation_node_state_machine.cpp -#, fuzzy msgid "Xfade Time" -msgstr "Tempo do X-Fade (s):" +msgstr "Tempo do Esmaecer Cruzado" #: scene/animation/animation_node_state_machine.cpp #, fuzzy @@ -24064,7 +23832,7 @@ msgstr "Adicionar Animação" #: scene/animation/animation_player.cpp msgid "Reset On Save" -msgstr "" +msgstr "Redefinir ao Salvar" #: scene/animation/animation_player.cpp #, fuzzy @@ -24077,9 +23845,8 @@ msgid "Current Animation Position" msgstr "Adicionar ponto de Animação" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Playback Options" -msgstr "Opções da Classe:" +msgstr "Opções de Playback" #: scene/animation/animation_player.cpp #, fuzzy @@ -24122,9 +23889,8 @@ msgid "The AnimationPlayer root node is not a valid node." msgstr "O nó raiz do AnimationPlayer não é um nó válido." #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Tree Root" -msgstr "Criar nó raiz:" +msgstr "Nó Raiz" #: scene/animation/animation_tree.cpp #, fuzzy @@ -24234,7 +24000,7 @@ msgstr "Modo de Seleção" #: scene/gui/aspect_ratio_container.cpp scene/gui/box_container.cpp msgid "Alignment" -msgstr "" +msgstr "Alinhamento" #: scene/gui/base_button.cpp #, fuzzy @@ -24272,11 +24038,11 @@ msgstr "Copiar Texto" #: scene/gui/button.cpp scene/gui/label.cpp scene/gui/line_edit.cpp #: scene/gui/spin_box.cpp msgid "Align" -msgstr "" +msgstr "Alinhar" #: scene/gui/button.cpp msgid "Icon Align" -msgstr "" +msgstr "Alinhamento do Ícone" #: scene/gui/button.cpp #, fuzzy @@ -24380,14 +24146,12 @@ msgid "Grow Direction" msgstr "Direções" #: scene/gui/control.cpp scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Min Size" -msgstr "Tamanho do Contorno:" +msgstr "Tamanho Mínimo" #: scene/gui/control.cpp -#, fuzzy msgid "Pivot Offset" -msgstr "Deslocamento da Grade:" +msgstr "Deslocamento do Pivô" #: scene/gui/control.cpp #, fuzzy @@ -24435,7 +24199,7 @@ msgstr "Anterior" #: scene/gui/control.cpp msgid "Mouse" -msgstr "" +msgstr "Mouse" #: scene/gui/control.cpp msgid "Default Cursor Shape" @@ -24461,7 +24225,7 @@ msgstr "Propriedades do Tema" #: scene/gui/dialogs.cpp msgid "Window Title" -msgstr "" +msgstr "Título da Janela" #: scene/gui/dialogs.cpp #, fuzzy @@ -24495,14 +24259,12 @@ msgid "Right Disconnects" msgstr "Desconectar" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Scroll Offset" -msgstr "Deslocamento da Grade:" +msgstr "Deslocamento da Rolagem" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Snap Distance" -msgstr "Escolha uma Distância:" +msgstr "Distância de Encaixe" #: scene/gui/graph_edit.cpp #, fuzzy @@ -24527,7 +24289,7 @@ msgstr "Mostrar Ossos" #: scene/gui/graph_edit.cpp scene/gui/text_edit.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Minimap" -msgstr "" +msgstr "Mini-Mapa" #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." @@ -24600,9 +24362,8 @@ msgid "Fixed Column Width" msgstr "" #: scene/gui/item_list.cpp -#, fuzzy msgid "Icon Scale" -msgstr "Escala aleatória:" +msgstr "Escala de Ícone" #: scene/gui/item_list.cpp #, fuzzy @@ -24615,9 +24376,8 @@ msgid "V Align" msgstr "Atribuir" #: scene/gui/label.cpp scene/gui/rich_text_label.cpp -#, fuzzy msgid "Visible Characters" -msgstr "Caracteres válidos:" +msgstr "Caracteres Visiveis" #: scene/gui/label.cpp scene/gui/rich_text_label.cpp #, fuzzy @@ -24641,9 +24401,8 @@ msgid "Secret" msgstr "" #: scene/gui/line_edit.cpp -#, fuzzy msgid "Secret Character" -msgstr "Caracteres válidos:" +msgstr "Caracteres Secretos" #: scene/gui/line_edit.cpp msgid "Expand To Text Length" @@ -24700,20 +24459,19 @@ msgstr "" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Caret" -msgstr "" +msgstr "Circunflexo" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Blink" -msgstr "" +msgstr "Piscar" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Blink Speed" -msgstr "Velocidade:" +msgstr "Velocidade de Piscar" #: scene/gui/link_button.cpp msgid "Underline" -msgstr "" +msgstr "Sublinhado" #: scene/gui/menu_button.cpp #, fuzzy @@ -24796,9 +24554,8 @@ msgid "Allow Search" msgstr "Pesquisar" #: scene/gui/progress_bar.cpp -#, fuzzy msgid "Percent" -msgstr "Recente:" +msgstr "Porcentagem" #: scene/gui/range.cpp msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." @@ -24858,9 +24615,8 @@ msgid "Absolute Index" msgstr "Auto Recuar" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Elapsed Time" -msgstr "Tempos de Mistura:" +msgstr "Tempo Decorrido" #: scene/gui/rich_text_effect.cpp #, fuzzy @@ -24868,9 +24624,8 @@ msgid "Env" msgstr "Fim" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Character" -msgstr "Caracteres válidos:" +msgstr "Caractere" #: scene/gui/rich_text_label.cpp msgid "BBCode" @@ -24881,9 +24636,8 @@ msgid "Meta Underlined" msgstr "" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Tab Size" -msgstr "Tamanho:" +msgstr "Tamanho da Tabulação" #: scene/gui/rich_text_label.cpp #, fuzzy @@ -24904,9 +24658,8 @@ msgid "Selection Enabled" msgstr "Selecionar Apenas" #: scene/gui/rich_text_label.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Override Selected Font Color" -msgstr "Configurar Perfil Selecionado:" +msgstr "Sobrescrever Cor da Fonte Selecionada" #: scene/gui/rich_text_label.cpp #, fuzzy @@ -24934,9 +24687,8 @@ msgid "Follow Focus" msgstr "Popular Superfície" #: scene/gui/scroll_container.cpp -#, fuzzy msgid "Horizontal Enabled" -msgstr "Horizontal:" +msgstr "Horizontal Habilitado" #: scene/gui/scroll_container.cpp #, fuzzy @@ -24957,24 +24709,20 @@ msgid "Tick Count" msgstr "Escolher Cor" #: scene/gui/slider.cpp -#, fuzzy msgid "Ticks On Borders" -msgstr "Renomear pasta:" +msgstr "Pontos Nas Bordas" #: scene/gui/spin_box.cpp -#, fuzzy msgid "Prefix" -msgstr "Prefixo:" +msgstr "Prefixo" #: scene/gui/spin_box.cpp -#, fuzzy msgid "Suffix" -msgstr "Sufixo:" +msgstr "Sufixo" #: scene/gui/split_container.cpp -#, fuzzy msgid "Split Offset" -msgstr "Deslocamento da Grade:" +msgstr "Deslocamento de Divisão" #: scene/gui/split_container.cpp scene/gui/tree.cpp #, fuzzy @@ -24991,9 +24739,8 @@ msgid "Tab Align" msgstr "" #: scene/gui/tab_container.cpp scene/gui/tabs.cpp -#, fuzzy msgid "Current Tab" -msgstr "Atual:" +msgstr "Aba Atual" #: scene/gui/tab_container.cpp #, fuzzy @@ -25035,9 +24782,8 @@ msgid "Breakpoint Gutter" msgstr "Pular Breakpoints" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Fold Gutter" -msgstr "Pasta:" +msgstr "Espaçamento de Dobra" #: scene/gui/text_edit.cpp #, fuzzy @@ -25055,19 +24801,16 @@ msgid "Wrap Enabled" msgstr "Habilitar" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Scroll Vertical" -msgstr "Vertical:" +msgstr "Scroll Vertical" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Scroll Horizontal" -msgstr "Horizontal:" +msgstr "Scroll Horizontal" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Draw" -msgstr "Chamadas de Desenho:" +msgstr "Desenhar" #: scene/gui/text_edit.cpp #, fuzzy @@ -25125,9 +24868,8 @@ msgid "Progress Offset" msgstr "" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Fill Mode" -msgstr "Modo Panorâmico:" +msgstr "Modo de Preenchimento" #: scene/gui/texture_progress.cpp scene/resources/material.cpp msgid "Tint" @@ -25195,9 +24937,8 @@ msgid "Hide Folding" msgstr "Botão Desativado" #: scene/gui/tree.cpp -#, fuzzy msgid "Hide Root" -msgstr "Criar nó raiz:" +msgstr "Esconder Raiz" #: scene/gui/tree.cpp msgid "Drop Mode Flags" @@ -25210,7 +24951,7 @@ msgstr "Adicionar Faixa" #: scene/gui/video_player.cpp scene/main/scene_tree.cpp scene/main/timer.cpp msgid "Paused" -msgstr "" +msgstr "Pausado" #: scene/gui/video_player.cpp #, fuzzy @@ -25295,19 +25036,16 @@ msgid "Filename" msgstr "Renomear" #: scene/main/node.cpp -#, fuzzy msgid "Owner" -msgstr "Donos De:" +msgstr "Dono" #: scene/main/node.cpp scene/main/scene_tree.cpp -#, fuzzy msgid "Multiplayer" -msgstr "Definir Múltiplos:" +msgstr "Multijogador" #: scene/main/node.cpp -#, fuzzy msgid "Custom Multiplayer" -msgstr "Definir Múltiplos:" +msgstr "Multijogador Personalizado" #: scene/main/node.cpp #, fuzzy @@ -25340,17 +25078,16 @@ msgstr "Nova Raiz de Cena" #: scene/main/scene_tree.cpp msgid "Root" -msgstr "" +msgstr "Raiz" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Multiplayer Poll" -msgstr "Definir Múltiplos:" +msgstr "" #: scene/main/scene_tree.cpp scene/resources/mesh_library.cpp #: scene/resources/shape_2d.cpp msgid "Shapes" -msgstr "" +msgstr "Formas" #: scene/main/scene_tree.cpp msgid "Shape Color" @@ -25384,9 +25121,8 @@ msgid "Reflections" msgstr "Reflexões" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Atlas Size" -msgstr "Tamanho do Contorno:" +msgstr "Tamanho do Atlas" #: scene/main/scene_tree.cpp msgid "Atlas Subdiv" @@ -25398,7 +25134,7 @@ msgstr "" #: scene/main/scene_tree.cpp msgid "Use FXAA" -msgstr "" +msgstr "Usar FXAA" #: scene/main/scene_tree.cpp msgid "Use Debanding" @@ -25406,7 +25142,7 @@ msgstr "" #: scene/main/scene_tree.cpp scene/main/viewport.cpp msgid "HDR" -msgstr "" +msgstr "HDR" #: scene/main/scene_tree.cpp scene/main/viewport.cpp msgid "Use 32 BPC Depth" @@ -25444,9 +25180,8 @@ msgstr "" "Timer para tempos de espera muito baixos." #: scene/main/timer.cpp -#, fuzzy msgid "Autostart" -msgstr "Reinício Automático:" +msgstr "Início Automático" #: scene/main/viewport.cpp #, fuzzy @@ -25472,7 +25207,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "ARVR" -msgstr "" +msgstr "ARVR" #: scene/main/viewport.cpp #, fuzzy @@ -25485,11 +25220,11 @@ msgstr "" #: scene/main/viewport.cpp scene/resources/world_2d.cpp msgid "World" -msgstr "" +msgstr "Mundo" #: scene/main/viewport.cpp msgid "World 2D" -msgstr "" +msgstr "Mundo 2D" #: scene/main/viewport.cpp #, fuzzy @@ -25503,7 +25238,7 @@ msgstr "Alterar Valor da Entrada" #: scene/main/viewport.cpp msgid "FXAA" -msgstr "" +msgstr "FXAA" #: scene/main/viewport.cpp #, fuzzy @@ -25521,8 +25256,9 @@ msgid "Keep 3D Linear" msgstr "Linear Esquerda" #: scene/main/viewport.cpp +#, fuzzy msgid "Render Direct To Screen" -msgstr "" +msgstr "Renderizar Diretamente para a Tela" #: scene/main/viewport.cpp #, fuzzy @@ -25530,9 +25266,8 @@ msgid "Debug Draw" msgstr "Depuração" #: scene/main/viewport.cpp -#, fuzzy msgid "Render Target" -msgstr "Renderizador:" +msgstr "Alvo do Renderizador" #: scene/main/viewport.cpp msgid "V Flip" @@ -25640,7 +25375,7 @@ msgstr "Navegação" #: scene/register_scene_types.cpp msgid "Use hiDPI" -msgstr "" +msgstr "Usar hiDPI" #: scene/register_scene_types.cpp #, fuzzy @@ -25660,12 +25395,11 @@ msgstr "Nó Mix" #: scene/resources/audio_stream_sample.cpp msgid "Stereo" -msgstr "" +msgstr "Stereo" #: scene/resources/concave_polygon_shape_2d.cpp -#, fuzzy msgid "Segments" -msgstr "Argumentos da Cena Principal:" +msgstr "Segmentos" #: scene/resources/curve.cpp #, fuzzy @@ -25678,7 +25412,7 @@ msgstr "" #: scene/resources/default_theme/default_theme.cpp msgid "Panel" -msgstr "" +msgstr "Painel" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25706,9 +25440,8 @@ msgid "Font Color Disabled" msgstr "Corte Desabilitado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "H Separation" -msgstr "Separação:" +msgstr "Separação Horizontal" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25717,7 +25450,7 @@ msgstr "Loop da Animação" #: scene/resources/default_theme/default_theme.cpp msgid "Arrow" -msgstr "" +msgstr "Seta" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25796,14 +25529,12 @@ msgid "Font Outline Modulate" msgstr "Forçar Módulo Branco" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Shadow Offset X" -msgstr "Deslocamento da Grade X:" +msgstr "Deslocamento da Sombra em X" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Shadow Offset Y" -msgstr "Deslocamento da Grade Y:" +msgstr "Deslocamento da Sombra em Y" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25861,14 +25592,12 @@ msgid "Space" msgstr "Cena Principal" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Folded" -msgstr "Pasta:" +msgstr "Dobrado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Fold" -msgstr "Pasta:" +msgstr "Dobrar" #: scene/resources/default_theme/default_theme.cpp msgid "Font Color Readonly" @@ -26036,9 +25765,8 @@ msgid "Font Color Separator" msgstr "Separador de Cor da Fonte" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "V Separation" -msgstr "Separação:" +msgstr "Separação Vertical" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26091,9 +25819,8 @@ msgid "Close Offset" msgstr "Deslocamento do Ruído" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Port Offset" -msgstr "Deslocamento da Grade:" +msgstr "Deslocamento de Porta" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26203,14 +25930,12 @@ msgid "Draw Guides" msgstr "Mostrar Guias" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Scroll Border" -msgstr "Vertical:" +msgstr "Borda da Barra de Rolagem" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Scroll Speed" -msgstr "Deslocamento da Grade:" +msgstr "Velocidade de Rolagem" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26218,9 +25943,8 @@ msgid "Icon Margin" msgstr "Definir Margem" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Line Separation" -msgstr "Separação:" +msgstr "Separação de Linha" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26239,7 +25963,7 @@ msgstr "Item Desativado" #: scene/resources/default_theme/default_theme.cpp msgid "Menu" -msgstr "" +msgstr "Menu" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26280,9 +26004,8 @@ msgid "Large" msgstr "Destino" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Folder" -msgstr "Pasta:" +msgstr "Pasta" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26374,7 +26097,7 @@ msgstr "Cena Principal" #: scene/resources/default_theme/default_theme.cpp msgid "Bold Italics Font" -msgstr "" +msgstr "Fonte Negrito Itálica" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26382,14 +26105,12 @@ msgid "Mono Font" msgstr "Cena Principal" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Table H Separation" -msgstr "Separação:" +msgstr "Separação Horizontal da Tabela" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Table V Separation" -msgstr "Separação:" +msgstr "Separação Vertical da Tabela" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26418,11 +26139,11 @@ msgstr "Auto Fatiar" #: scene/resources/default_theme/default_theme.cpp msgid "Minus" -msgstr "" +msgstr "Menos" #: scene/resources/default_theme/default_theme.cpp msgid "More" -msgstr "" +msgstr "Mais" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26482,9 +26203,8 @@ msgid "Font Path" msgstr "Habilitar" #: scene/resources/dynamic_font.cpp -#, fuzzy msgid "Outline Size" -msgstr "Tamanho do Contorno:" +msgstr "Tamanho do Contorno" #: scene/resources/dynamic_font.cpp #, fuzzy @@ -26497,14 +26217,12 @@ msgid "Use Mipmaps" msgstr "Sinais" #: scene/resources/dynamic_font.cpp -#, fuzzy msgid "Extra Spacing" -msgstr "Opções Extra:" +msgstr "Espaçamento Extra" #: scene/resources/dynamic_font.cpp -#, fuzzy msgid "Char" -msgstr "Caracteres válidos:" +msgstr "Caractere" #: scene/resources/dynamic_font.cpp #, fuzzy @@ -26517,7 +26235,7 @@ msgstr "" #: scene/resources/environment.cpp scene/resources/sky.cpp msgid "Sky" -msgstr "" +msgstr "Céu" #: scene/resources/environment.cpp #, fuzzy @@ -26530,9 +26248,8 @@ msgid "Sky Orientation" msgstr "Documentação Online" #: scene/resources/environment.cpp -#, fuzzy msgid "Sky Rotation" -msgstr "Passo de Rotação:" +msgstr "Rotação do Céu" #: scene/resources/environment.cpp msgid "Sky Rotation Degrees" @@ -26561,14 +26278,12 @@ msgid "Fog" msgstr "Névoa" #: scene/resources/environment.cpp -#, fuzzy msgid "Sun Color" -msgstr "Armazenando Arquivo:" +msgstr "Cor do Sol" #: scene/resources/environment.cpp -#, fuzzy msgid "Sun Amount" -msgstr "Quantidade:" +msgstr "Quantidade do Sol" #: scene/resources/environment.cpp #, fuzzy @@ -26632,7 +26347,7 @@ msgstr "Exportação" #: scene/resources/environment.cpp msgid "White" -msgstr "" +msgstr "Branco" #: scene/resources/environment.cpp msgid "Auto Exposure" @@ -26657,14 +26372,12 @@ msgid "Max Steps" msgstr "Passo" #: scene/resources/environment.cpp -#, fuzzy msgid "Fade In" -msgstr "[i]Fade In[/i](s):" +msgstr "Esmaecer de Entrada" #: scene/resources/environment.cpp -#, fuzzy msgid "Fade Out" -msgstr "[i]Fade Out[/i](s):" +msgstr "Esmaecer de Saída" #: scene/resources/environment.cpp #, fuzzy @@ -26677,12 +26390,11 @@ msgstr "Rugosidade" #: scene/resources/environment.cpp msgid "SSAO" -msgstr "" +msgstr "SSAO" #: scene/resources/environment.cpp -#, fuzzy msgid "Radius 2" -msgstr "Raio:" +msgstr "Raio 2" #: scene/resources/environment.cpp msgid "Intensity 2" @@ -26700,7 +26412,7 @@ msgstr "Depuração do Canal UV" #: scene/resources/environment.cpp msgid "Blur" -msgstr "" +msgstr "Blur" #: scene/resources/environment.cpp msgid "Edge Sharpness" @@ -26711,9 +26423,8 @@ msgid "DOF Far Blur" msgstr "" #: scene/resources/environment.cpp scene/resources/material.cpp -#, fuzzy msgid "Distance" -msgstr "Escolha uma Distância:" +msgstr "Distância" #: scene/resources/environment.cpp msgid "Transition" @@ -26796,18 +26507,16 @@ msgid "Brightness" msgstr "Luz" #: scene/resources/environment.cpp -#, fuzzy msgid "Saturation" -msgstr "Separação:" +msgstr "Separação" #: scene/resources/environment.cpp msgid "Color Correction" msgstr "Correção de Cor" #: scene/resources/font.cpp -#, fuzzy msgid "Ascent" -msgstr "Recente:" +msgstr "Subida" #: scene/resources/font.cpp #, fuzzy @@ -26820,9 +26529,8 @@ msgid "Raw Data" msgstr "Profundidade" #: scene/resources/gradient.cpp -#, fuzzy msgid "Offsets" -msgstr "Deslocamento:" +msgstr "Deslocamentos" #: scene/resources/height_map_shape.cpp msgid "Map Width" @@ -26902,7 +26610,7 @@ msgstr "" #: scene/resources/material.cpp msgid "Is sRGB" -msgstr "" +msgstr "É sRGB" #: scene/resources/material.cpp servers/visual_server.cpp msgid "Parameters" @@ -26948,9 +26656,8 @@ msgid "Grow" msgstr "Crescer" #: scene/resources/material.cpp -#, fuzzy msgid "Grow Amount" -msgstr "Quantidade:" +msgstr "Quantidade de Crescimento" #: scene/resources/material.cpp msgid "Use Alpha Scissor" @@ -27105,7 +26812,7 @@ msgstr "Faça mapas de luz" #: scene/resources/mesh.cpp scene/resources/primitive_meshes.cpp msgid "Custom AABB" -msgstr "" +msgstr "AABB Personalizado" #: scene/resources/mesh_library.cpp #, fuzzy @@ -27139,9 +26846,8 @@ msgid "Visible Instance Count" msgstr "" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Sampling" -msgstr "Escala:" +msgstr "Mostragem" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -27162,12 +26868,11 @@ msgstr "Origem do Nome do Grupo" #: scene/resources/navigation_mesh.cpp msgid "Cells" -msgstr "" +msgstr "Células" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Agents" -msgstr "Argumentos da Cena Principal:" +msgstr "Agentes" #: scene/resources/navigation_mesh.cpp msgid "Max Climb" @@ -27189,7 +26894,7 @@ msgstr "Fundir a partir de Cena" #: scene/resources/navigation_mesh.cpp msgid "Edges" -msgstr "" +msgstr "Arestas" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -27206,9 +26911,8 @@ msgid "Details" msgstr "Detalhe" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Sample Distance" -msgstr "Escolha uma Distância:" +msgstr "Distância de Amostra" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -27278,9 +26982,8 @@ msgid "Color Modifier" msgstr "Modificador de velocidade lenta da Visão Livre" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Point Texture" -msgstr "Pontos de Emissão:" +msgstr "Textura de Ponto" #: scene/resources/particles_material.cpp msgid "Normal Texture" @@ -27297,9 +27000,8 @@ msgid "Point Count" msgstr "Adicionar porta de entrada" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Scale Random" -msgstr "Razão de Escala:" +msgstr "Randomização de Escala" #: scene/resources/particles_material.cpp #, fuzzy @@ -27315,9 +27017,8 @@ msgid "Absorbent" msgstr "" #: scene/resources/plane_shape.cpp -#, fuzzy msgid "Plane" -msgstr "Plano:" +msgstr "Plano" #: scene/resources/primitive_meshes.cpp #, fuzzy @@ -27341,9 +27042,8 @@ msgid "Subdivide Depth" msgstr "" #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Top Radius" -msgstr "Raio:" +msgstr "Raio do Topo" #: scene/resources/primitive_meshes.cpp #, fuzzy @@ -27392,13 +27092,12 @@ msgid "Bone" msgstr "Ossos" #: scene/resources/sky.cpp -#, fuzzy msgid "Radiance Size" -msgstr "Tamanho do Contorno:" +msgstr "Tamanho da Radiância" #: scene/resources/sky.cpp msgid "Panorama" -msgstr "" +msgstr "Panorama" #: scene/resources/sky.cpp #, fuzzy @@ -27406,9 +27105,8 @@ msgid "Top Color" msgstr "Próximo Chão" #: scene/resources/sky.cpp -#, fuzzy msgid "Horizon Color" -msgstr "Armazenando Arquivo:" +msgstr "Cor do Horizonte" #: scene/resources/sky.cpp #, fuzzy @@ -27432,7 +27130,7 @@ msgstr "Substituir" #: scene/resources/sky.cpp msgid "Longitude" -msgstr "" +msgstr "Longitude" #: scene/resources/sky.cpp msgid "Angle Min" @@ -27467,7 +27165,7 @@ msgstr "" #: scene/resources/style_box.cpp msgid "Anti Aliasing" -msgstr "" +msgstr "Anti Aliasing" #: scene/resources/style_box.cpp msgid "Grow Begin" @@ -27517,9 +27215,8 @@ msgid "Lossy Storage Quality" msgstr "Capturar" #: scene/resources/texture.cpp -#, fuzzy msgid "From" -msgstr "Modo Panorâmico:" +msgstr "À Partir de" #: scene/resources/texture.cpp #, fuzzy @@ -27723,9 +27420,8 @@ msgid "Audio Stream" msgstr "Item Rádio" #: servers/audio/audio_stream.cpp -#, fuzzy msgid "Random Pitch" -msgstr "Inclinação aleatória:" +msgstr "Timbre Aleatório" #: servers/audio/effects/audio_effect_capture.cpp #: servers/audio/effects/audio_effect_spectrum_analyzer.cpp @@ -27741,21 +27437,21 @@ msgstr "" #: servers/audio/effects/audio_effect_delay.cpp #: servers/audio/effects/audio_effect_reverb.cpp msgid "Dry" -msgstr "" +msgstr "Seco" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_reverb.cpp msgid "Wet" -msgstr "" +msgstr "Molhado" #: servers/audio/effects/audio_effect_chorus.cpp msgid "Voice" -msgstr "" +msgstr "Voz" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp msgid "Delay (ms)" -msgstr "" +msgstr "Atraso (ms)" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_phaser.cpp @@ -27770,23 +27466,22 @@ msgstr "Profundidade" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp msgid "Level dB" -msgstr "" +msgstr "Nível dB" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp #: servers/audio/effects/audio_effect_panner.cpp -#, fuzzy msgid "Pan" -msgstr "Plano:" +msgstr "Panoramizar" #: servers/audio/effects/audio_effect_compressor.cpp #: servers/audio/effects/audio_effect_filter.cpp msgid "Gain" -msgstr "" +msgstr "Ganho" #: servers/audio/effects/audio_effect_compressor.cpp msgid "Attack (µs)" -msgstr "" +msgstr "Ataque (µs)" #: servers/audio/effects/audio_effect_compressor.cpp #, fuzzy @@ -27823,7 +27518,7 @@ msgstr "Ignorar" #: servers/audio/effects/audio_effect_distortion.cpp msgid "Pre Gain" -msgstr "" +msgstr "Pré Ganho" #: servers/audio/effects/audio_effect_distortion.cpp msgid "Keep Hf Hz" @@ -27831,7 +27526,7 @@ msgstr "" #: servers/audio/effects/audio_effect_distortion.cpp msgid "Drive" -msgstr "" +msgstr "Drive" #: servers/audio/effects/audio_effect_distortion.cpp #, fuzzy @@ -27873,21 +27568,20 @@ msgstr "" #: servers/audio/effects/audio_effect_pitch_shift.cpp #: servers/audio/effects/audio_effect_spectrum_analyzer.cpp -#, fuzzy msgid "FFT Size" -msgstr "Tamanho:" +msgstr "Tamanho FFT" #: servers/audio/effects/audio_effect_reverb.cpp msgid "Predelay" -msgstr "" +msgstr "Pré Atraso" #: servers/audio/effects/audio_effect_reverb.cpp msgid "Msec" -msgstr "" +msgstr "Msec" #: servers/audio/effects/audio_effect_reverb.cpp msgid "Room Size" -msgstr "" +msgstr "Tamanho da Sala" #: servers/audio/effects/audio_effect_reverb.cpp #, fuzzy @@ -27970,9 +27664,8 @@ msgid "Time Before Sleep" msgstr "" #: servers/physics_2d/physics_2d_server_sw.cpp -#, fuzzy msgid "BP Hash Table Size" -msgstr "Tamanho:" +msgstr "Tamanho da \"BP Hash Table\"" #: servers/physics_2d/physics_2d_server_sw.cpp msgid "Large Object Surface Threshold In Cells" @@ -28345,7 +28038,7 @@ msgstr "" #: servers/visual_server.cpp msgid "Compatibility" -msgstr "" +msgstr "Compatibilidade" #: servers/visual_server.cpp msgid "Disable Half Float" diff --git a/editor/translations/ro.po b/editor/translations/ro.po index 395185bd3e..a78712c6ba 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -2186,14 +2186,15 @@ msgstr "Favorite:" msgid "Recent:" msgstr "Recent:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cautați:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Potriviri:" @@ -2253,8 +2254,8 @@ msgstr "Cautați Înlocuitor Resursă:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2835,8 +2836,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Copiază Selecția" #: editor/editor_export.cpp #, fuzzy @@ -5633,6 +5635,10 @@ msgid "Drag And Drop Selection" msgstr "Toată selecția" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12024,6 +12030,11 @@ msgid "New Animation" msgstr "Animație" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Metode de filtrare" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20729,15 +20740,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Trebuie să utilizaţi o extensie valida." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20759,15 +20770,15 @@ msgstr "Nume nevalid." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Trebuie să utilizaţi o extensie valida." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/ru.po b/editor/translations/ru.po index befaceac4c..1df1d87308 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -85,7 +85,7 @@ # kyanukovich <ianu0001@algonquinlive.com>, 2020. # Ron788 <ustinov200511@gmail.com>, 2020. # Daniel <dan.ef1999@gmail.com>, 2020. -# NeoLan Qu <it.bulla@mail.ru>, 2020. +# NeoLan Qu <it.bulla@mail.ru>, 2020, 2022. # Nikita Epifanov <nikgreens@protonmail.com>, 2020. # Cube Show <griiv.06@gmail.com>, 2020. # Roman Tolkachyov <roman@tolkachyov.name>, 2020. @@ -118,13 +118,14 @@ # Jasuse <jasusemaele@gmail.com>, 2022. # Vadim Mitroshkin <Vadim7540@yandex.ru>, 2022. # Maksim Marchukov <mar.maksim63@gmail.com>, 2022. +# Slava Beloglazov <slavathedeveloper@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-17 07:14+0000\n" -"Last-Translator: Maksim Marchukov <mar.maksim63@gmail.com>\n" +"PO-Revision-Date: 2022-07-26 01:55+0000\n" +"Last-Translator: NeoLan Qu <it.bulla@mail.ru>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" "Language: ru\n" @@ -561,7 +562,7 @@ msgstr "Давление" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Перо Инвертировано" #: core/os/input_event.cpp msgid "Relative" @@ -1244,9 +1245,8 @@ msgid "Value" msgstr "Значение" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Arg Count" -msgstr "Количество" +msgstr "Количество Аргументов" #: editor/animation_track_editor.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp @@ -1437,24 +1437,22 @@ msgid "(Invalid, expected type: %s)" msgstr "(Неверный, ожидаемый тип: %s)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Easing:" -msgstr "Переход В-ИЗ" +msgstr "Переход В-ИЗ:" #: editor/animation_track_editor.cpp #, fuzzy msgid "In-Handle:" -msgstr "Задать обработчик" +msgstr "Обработчик Ввода:" #: editor/animation_track_editor.cpp #, fuzzy msgid "Out-Handle:" -msgstr "Задать обработчик" +msgstr "Обработчик Вывода:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Stream:" -msgstr "Поток" +msgstr "Поток:" #: editor/animation_track_editor.cpp msgid "Start (s):" @@ -2215,14 +2213,15 @@ msgstr "Избранное:" msgid "Recent:" msgstr "Недавнее:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Поиск:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Совпадения:" @@ -2282,8 +2281,8 @@ msgstr "Найти заменяемый ресурс:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2292,7 +2291,7 @@ msgstr "Открыть" #: editor/dependency_editor.cpp msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "Владельцы: %s (Всего: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2342,9 +2341,8 @@ msgid "Fix Dependencies" msgstr "Исправить зависимости" #: editor/dependency_editor.cpp -#, fuzzy msgid "Errors loading!" -msgstr "Ошибки загружаются!" +msgstr "Ошибки при загрузке!" #: editor/dependency_editor.cpp msgid "Permanently delete %d item(s)? (No undo!)" @@ -2851,17 +2849,16 @@ msgstr "Выбрать" #: editor/editor_export.cpp msgid "Project export for platform:" -msgstr "" +msgstr "Экспорт проекта для платформы:" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." -msgstr "Завершать пути файлов" +msgid "Completed with warnings." +msgstr "Завершено с ошибками." #: editor/editor_export.cpp -#, fuzzy msgid "Completed successfully." -msgstr "Пакет успешно установлен!" +msgstr "Завершено без ошибок." #: editor/editor_export.cpp #, fuzzy @@ -2881,9 +2878,8 @@ msgid "Packing" msgstr "Упаковывание" #: editor/editor_export.cpp -#, fuzzy msgid "Save PCK" -msgstr "Сохранить как" +msgstr "Сохранить PCK" #: editor/editor_export.cpp #, fuzzy @@ -2910,16 +2906,16 @@ msgid "" "Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " "Etc' in Project Settings." msgstr "" -"Целевая платформа требует сжатие текстур «ETC» для GLES2. Включите «Import " -"Etc» в Настройках проекта." +"Целевая платформа требует сжатие текстур «ETC» для GLES2. Включите " +"«Импортировать Etc» в Настройках Проекта." #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC2' texture compression for GLES3. Enable " "'Import Etc 2' in Project Settings." msgstr "" -"Целевая платформа требует компрессию текстур «ETC2» для GLES2. Включите " -"«Import Etc 2» в Настройках проекта." +"Целевая платформа требует компрессию текстур «ETC2» для GLES3. Включите " +"«Импортировать Etc 2» в Настройках Проекта." #: editor/editor_export.cpp msgid "" @@ -2929,8 +2925,8 @@ msgid "" "Enabled'." msgstr "" "Целевая платформа требует сжатия текстур «ETC» для отката драйвера к GLES2.\n" -"Включите «Import Etc» в Настройках проекта или отключите «Driver Fallback " -"Enabled»." +"Включите «Импортировать Etc» в Настройках проекта или отключите «Driver " +"Fallback Enabled»." #: editor/editor_export.cpp msgid "" @@ -2946,7 +2942,8 @@ msgid "" "Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." msgstr "" "Целевая платформа требует компрессию текстур «ETC2» или «PVRTC» для GLES3. " -"Включите «Import Etc 2» или «Import Pvrtc» в Настройках проекта." +"Включите «Импортировать Etc 2» или «Импортировать Pvrtc» в Настройках " +"Проекта." #: editor/editor_export.cpp msgid "" @@ -5604,6 +5601,10 @@ msgid "Drag And Drop Selection" msgstr "Выделение сетки" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Внешний вид" @@ -7257,12 +7258,17 @@ msgid "" "%s: Texture detected as used as a normal map in 3D. Enabling red-green " "texture compression to reduce memory usage (blue channel is discarded)." msgstr "" +"%s: Выбранная текстура используется как карта нормалей в 3D. Включено красно-" +"зелёное сжатие текстуры для уменьшения использования памяти (синий канал " +"отбрасывается)." #: editor/import/resource_importer_texture.cpp msgid "" "%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap " "generation and VRAM texture compression." msgstr "" +"%s: Текстура используется в 3D. Включена фильтрация, повторение и генерация " +"mipmap-карт, а также VRAM сжатие текстуры." #: editor/import/resource_importer_texture.cpp msgid "2D, Detect 3D" @@ -11699,6 +11705,11 @@ msgid "New Animation" msgstr "Новая анимация" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Фильтр методов" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Скорость:" @@ -15361,7 +15372,7 @@ msgstr "Сделать локальным" #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp msgid "Another node already uses this unique name in the scene." -msgstr "Имя узла уже использовано в сцене" +msgstr "Данное уникальное имя уже использовано у другого узла в сцене." #: editor/scene_tree_dock.cpp msgid "Enable Scene Unique Name" @@ -15794,9 +15805,8 @@ msgid "Attach Node Script" msgstr "Прикрепить скрипт" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Remote %s:" -msgstr "Удаленный " +msgstr "Удаленный %s:" #: editor/script_editor_debugger.cpp msgid "Bytes:" @@ -16774,7 +16784,7 @@ msgstr "Выключен GDNative синглтон" #: modules/gdnative/gdnative_library_singleton_editor.cpp #, fuzzy msgid "Libraries:" -msgstr "Библиотеки: " +msgstr "Библиотеки:" #: modules/gdnative/nativescript/nativescript.cpp msgid "Class Name" @@ -17050,7 +17060,7 @@ msgstr "Сфокусироваться на начале координат" #: modules/gltf/gltf_skin.cpp msgid "Inverse Binds" -msgstr "" +msgstr "Инвертировать Связи" #: modules/gltf/gltf_skin.cpp #, fuzzy @@ -17059,11 +17069,11 @@ msgstr "Передвинуть сустав" #: modules/gltf/gltf_skin.cpp msgid "Joint I To Bone I" -msgstr "" +msgstr "Узел I к Кости I" #: modules/gltf/gltf_skin.cpp msgid "Joint I To Name" -msgstr "" +msgstr "Узел I К Имени" #: modules/gltf/gltf_skin.cpp msgid "Godot Skin" @@ -17079,7 +17089,7 @@ msgstr "Диффузный фактор" #: modules/gltf/gltf_spec_gloss.cpp msgid "Gloss Factor" -msgstr "" +msgstr "Коэфф. Глянца" #: modules/gltf/gltf_spec_gloss.cpp #, fuzzy @@ -17628,9 +17638,8 @@ msgstr "" "памяти! Исправьте узел пожалуйста." #: modules/visual_script/visual_script.cpp -#, fuzzy msgid "Node returned an invalid sequence output:" -msgstr "Узел вернул ошибочную последовательность: " +msgstr "Узел вернул ошибочный вывод последовательности:" #: modules/visual_script/visual_script.cpp msgid "Found sequence bit but not the node in the stack, report bug!" @@ -17640,7 +17649,7 @@ msgstr "" #: modules/visual_script/visual_script.cpp #, fuzzy msgid "Stack overflow with stack depth:" -msgstr "Переполнение стека с глубиной стека: " +msgstr "Переполнение стека с глубиной стека:" #: modules/visual_script/visual_script.cpp msgid "Visual Script" @@ -18009,7 +18018,7 @@ msgstr "для (элемент) в (вход):" #: modules/visual_script/visual_script_flow_control.cpp #, fuzzy msgid "Input type not iterable:" -msgstr "Входной тип не итерируемый: " +msgstr "Входной тип не итерируемый:" #: modules/visual_script/visual_script_flow_control.cpp msgid "Iterator became invalid" @@ -18018,7 +18027,7 @@ msgstr "Итератор стал недействительным" #: modules/visual_script/visual_script_flow_control.cpp #, fuzzy msgid "Iterator became invalid:" -msgstr "Итератор стал недействительным: " +msgstr "Итератор стал недействительным:" #: modules/visual_script/visual_script_flow_control.cpp msgid "Sequence" @@ -18172,14 +18181,12 @@ msgid "Operator" msgstr "Оператор" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Invalid argument of type:" -msgstr ": Недопустимый аргумент типа: " +msgstr "Недопустимый аргумент типа:" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Invalid arguments:" -msgstr ": Недопустимые аргументы: " +msgstr "Недопустимые аргументы:" #: modules/visual_script/visual_script_nodes.cpp msgid "a if cond, else b" @@ -18190,14 +18197,13 @@ msgid "Var Name" msgstr "Имя переменной" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "VariableGet not found in script:" -msgstr "VariableGet не найден в скрипте: " +msgstr "VariableGet отсутствует в скрипте:" #: modules/visual_script/visual_script_nodes.cpp #, fuzzy msgid "VariableSet not found in script:" -msgstr "VariableSet не найден в скрипте: " +msgstr "VariableSet не найден в скрипте:" #: modules/visual_script/visual_script_nodes.cpp msgid "Preload" @@ -18334,7 +18340,7 @@ msgstr "Режим записи" #: modules/webrtc/webrtc_data_channel.h msgid "WebRTC" -msgstr "" +msgstr "WebRTC" #: modules/webrtc/webrtc_data_channel.h #, fuzzy @@ -18350,36 +18356,32 @@ msgid "Trusted SSL Certificate" msgstr "Доверенный SSL-сертификат" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Client" -msgstr "Сетевой узел" +msgstr "Клиент WebSocket" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max In Buffer (KB)" -msgstr "Максимальный размер (КБ)" +msgstr "Максимальный Входной Буфер (КБ)" #: modules/websocket/websocket_macros.h msgid "Max In Packets" -msgstr "" +msgstr "Максимальные Входящие Пакеты" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max Out Buffer (KB)" -msgstr "Максимальный размер (КБ)" +msgstr "Максимальный Буфер Вывода (КБ)" #: modules/websocket/websocket_macros.h msgid "Max Out Packets" -msgstr "" +msgstr "Максимальный Вывод Пакетов" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Server" -msgstr "Сетевой узел" +msgstr "Сервер WebSocket" #: modules/websocket/websocket_server.cpp msgid "Bind IP" -msgstr "" +msgstr "Привязать IP" #: modules/websocket/websocket_server.cpp msgid "Private Key" @@ -18403,14 +18405,12 @@ msgid "Session Mode" msgstr "Режим сессии" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Required Features" -msgstr "Необходимые функции" +msgstr "Необходимые Компоненты" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Optional Features" -msgstr "Дополнительные функции" +msgstr "Дополнительные Компоненты" #: modules/webxr/webxr_interface.cpp msgid "Requested Reference Space Types" @@ -18421,9 +18421,8 @@ msgid "Reference Space Type" msgstr "" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Visibility State" -msgstr "Переключить видимость" +msgstr "Видимость" #: modules/webxr/webxr_interface.cpp #, fuzzy @@ -18431,9 +18430,8 @@ msgid "Bounds Geometry" msgstr "Повторить" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "XR Standard Mapping" -msgstr "Интеллектуальная привязка" +msgstr "Стандартный Маппинг XR" #: platform/android/export/export.cpp msgid "Android SDK Path" @@ -18462,19 +18460,19 @@ msgstr "Выключение ADB при выходе" #: platform/android/export/export_plugin.cpp msgid "Launcher Icons" -msgstr "" +msgstr "Иконки Лаунчера" #: platform/android/export/export_plugin.cpp msgid "Main 192 X 192" -msgstr "" +msgstr "Основная 192 X 192" #: platform/android/export/export_plugin.cpp msgid "Adaptive Foreground 432 X 432" -msgstr "" +msgstr "Адаптивный Передний Фон 432 X 432" #: platform/android/export/export_plugin.cpp msgid "Adaptive Background 432 X 432" -msgstr "" +msgstr "Адаптивный Задний Фон 432 X 432" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -18501,39 +18499,32 @@ msgid "The package must have at least one '.' separator." msgstr "Пакет должен иметь хотя бы один разделитель «.»." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Custom Build" -msgstr "Использовать собственную директорию данных пользователя" +msgstr "Настраиваемая Сборка" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Use Custom Build" -msgstr "Использовать собственную директорию данных пользователя" +msgstr "Использовать Настраиваемую Сборку" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Export Format" -msgstr "Путь экспорта" +msgstr "Формат Экспорта" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Min SDK" -msgstr "Минимальный размер" +msgstr "Min SDK" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Target SDK" -msgstr "Целевой FPS" +msgstr "Целевой SDK" #: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp -#, fuzzy msgid "Architectures" -msgstr "Добавить поле архитектуры" +msgstr "Архитектуры" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Keystore" -msgstr "Отладочное хранилище ключей" +msgstr "Хранилище ключей" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18557,31 +18548,27 @@ msgstr "Пароль" #: platform/android/export/export_plugin.cpp msgid "One Click Deploy" -msgstr "" +msgstr "Развёртывание в Один Клик" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Clear Previous Install" -msgstr "Осмотреть предыдущий экземпляр" +msgstr "Очистить Предыдущую Установку" #: platform/android/export/export_plugin.cpp msgid "Code" msgstr "Код" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Package" -msgstr "Упаковывание" +msgstr "Пакет" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Unique Name" -msgstr "Уникальные имена" +msgstr "Уникальное Имя" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Signed" -msgstr "Сигнал" +msgstr "Подписано" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18891,14 +18878,12 @@ msgid "Code Signing" msgstr "Подпись кода DMG" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "'apksigner' could not be found. Please check that the command is available " "in the Android SDK build-tools directory. The resulting %s is unsigned." msgstr "" -"Не удалось найти команду «apksigner».\n" -"Пожалуйста, проверьте наличие программы в каталоге Android SDK build-tools.\n" -"Результат %s не подписан." +"Не удалось найти «apksigner». Пожалуйста, убедитесь в наличии команды в " +"каталоге build-tools Android SDK. Результирующий %s не подписан." #: platform/android/export/export_plugin.cpp msgid "Signing debug %s..." @@ -18913,9 +18898,8 @@ msgid "Could not find keystore, unable to export." msgstr "Не удалось найти хранилище ключей, невозможно экспортировать." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not start apksigner executable." -msgstr "Не удаётся запустить подпроцесс!" +msgstr "Не удаётся запустить исполняемый файл apksigner." #: platform/android/export/export_plugin.cpp msgid "'apksigner' returned with error #%d" @@ -18946,9 +18930,8 @@ msgid "Invalid filename! Android APK requires the *.apk extension." msgstr "Неверное имя файла! Android APK требует расширения *.apk." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Unsupported export format!" -msgstr "Неподдерживаемый формат экспорта!\n" +msgstr "Неподдерживаемый формат экспорта!" #: platform/android/export/export_plugin.cpp msgid "" @@ -18959,15 +18942,12 @@ msgstr "" "не существует. Пожалуйста, переустановите из меню «Проект»." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Android build version mismatch: Template installed: %s, Godot version: %s. " "Please reinstall Android build template from 'Project' menu." msgstr "" -"Несоответствие версии сборки Android:\n" -" Установлен шаблон: %s\n" -" Версия Godot: %s\n" -"Пожалуйста, переустановите шаблон сборки Android из меню «Проект»." +"Несоответствие версии сборки Android: Установлен шаблон: %s, версия Godot: " +"%s. Пожалуйста, переустановите шаблон сборки Android из меню «Проект»." #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18977,9 +18957,8 @@ msgstr "" "Невозможно перезаписать файлы res://android/build/res/*.xml с именем проекта" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files to gradle project." -msgstr "Не удалось экспортировать файлы проекта в проект gradle\n" +msgstr "Не удалось экспортировать файлы проекта в проект gradle." #: platform/android/export/export_plugin.cpp msgid "Could not write expansion package file!" @@ -18990,14 +18969,13 @@ msgid "Building Android Project (gradle)" msgstr "Сборка проекта Android (gradle)" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Building of Android project failed, check output for the error. " "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" -"Сборка проекта Android не удалась, проверьте вывод на ошибки.\n" -"Также посетите docs.godotengine.org для получения документации по сборке " -"Android." +"Сборка Android проекта не удалась, проверьте вывод на ошибки. Вы также " +"можете посетить docs.godotengine.org для получения документации по сборке " +"для Android." #: platform/android/export/export_plugin.cpp msgid "Moving output" @@ -19021,22 +18999,18 @@ msgid "Creating APK..." msgstr "Создание APK..." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not find template APK to export: \"%s\"." -msgstr "" -"Не удалось найти шаблон APK для экспорта:\n" -"%s" +msgstr "Не удалось найти шаблон APK для экспорта: \"%s\"." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Missing libraries in the export template for the selected architectures: %s. " "Please build a template with all required libraries, or uncheck the missing " "architectures in the export preset." msgstr "" -"В шаблоне экспорта отсутствуют библиотеки для выбранных архитектур: %s.\n" -"Пожалуйста, создайте шаблон со всеми необходимыми библиотеками или снимите " -"флажки с отсутствующих архитектур в пресете экспорта." +"В шаблоне экспорта отсутствуют библиотеки для выбранных архитектур: %s. " +"Пожалуйста, постройте шаблон со всеми необходимыми библиотеками или снимите " +"флажки с отсутствующих архитектур в предустановках экспорта." #: platform/android/export/export_plugin.cpp msgid "Adding files..." @@ -19726,9 +19700,8 @@ msgid "Could not open icon file \"%s\"." msgstr "Не удалось экспортировать файлы проекта" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not start xcrun executable." -msgstr "Не удаётся запустить подпроцесс!" +msgstr "Не удаётся запустить исполняемый файл xcrun." #: platform/osx/export/export.cpp #, fuzzy @@ -19812,9 +19785,8 @@ msgid "DMG Creation" msgstr "Направление" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not start hdiutil executable." -msgstr "Не удаётся запустить подпроцесс!" +msgstr "Не удаётся запустить исполняемый файл hdiutil." #: platform/osx/export/export.cpp msgid "`hdiutil create` failed - file exists." @@ -19901,9 +19873,8 @@ msgid "ZIP Creation" msgstr "Проекция" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not open file to read from path \"%s\"." -msgstr "Не удалось экспортировать файлы проекта в проект gradle\n" +msgstr "Не удалось открыть файл для чтения по пути \"%s\"." #: platform/osx/export/export.cpp msgid "Invalid bundle identifier:" @@ -20310,17 +20281,17 @@ msgstr "Не удалось найти хранилище ключей, нево #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" "Инструмент rcedit должен быть настроен в Настройках редактора (Export > " "Windows > Rcedit) для изменения значка или информационных данных приложения." #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Недопустимый исполняемый файл." #: platform/windows/export/export.cpp #, fuzzy @@ -20345,17 +20316,17 @@ msgstr "Недопустимое имя." #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" "Инструмент rcedit должен быть настроен в Настройках редактора (Export > " "Windows > Rcedit) для изменения значка или информационных данных приложения." #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Недопустимый исполняемый файл." #: platform/windows/export/export.cpp #, fuzzy @@ -22940,11 +22911,11 @@ msgstr "" #: scene/3d/physics_body.cpp msgid "Angular Spring Damping" -msgstr "" +msgstr "Угловое Затухание Пружины" #: scene/3d/physics_body.cpp msgid "Angular Equilibrium Point" -msgstr "" +msgstr "Угловая Точка Равновесия" #: scene/3d/physics_body.cpp #, fuzzy @@ -22973,7 +22944,7 @@ msgstr "Узел А и Узел В должны быть различными о #: scene/3d/physics_joint.cpp msgid "Solver" -msgstr "" +msgstr "Разрешитель" #: scene/3d/physics_joint.cpp #, fuzzy @@ -22987,7 +22958,7 @@ msgstr "Параметры" #: scene/3d/physics_joint.cpp msgid "Angular Limit" -msgstr "" +msgstr "Угловой Предел" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23001,7 +22972,7 @@ msgstr "нижний регистр" #: scene/3d/physics_joint.cpp msgid "Motor" -msgstr "" +msgstr "Мотор" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23085,11 +23056,11 @@ msgstr "Межстрочный интервал" #: scene/3d/physics_joint.cpp msgid "Equilibrium Point" -msgstr "" +msgstr "Точка Равновесия" #: scene/3d/physics_joint.cpp msgid "Angular Limit X" -msgstr "" +msgstr "X Углового Предела" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23098,7 +23069,7 @@ msgstr "Угловая скорость" #: scene/3d/physics_joint.cpp msgid "Angular Spring X" -msgstr "" +msgstr "X Угловой Пружины" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23117,7 +23088,7 @@ msgstr "Межстрочный интервал" #: scene/3d/physics_joint.cpp msgid "Angular Limit Y" -msgstr "" +msgstr "Y Углового Предела" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23126,7 +23097,7 @@ msgstr "Угловая скорость" #: scene/3d/physics_joint.cpp msgid "Angular Spring Y" -msgstr "" +msgstr "Y Угловой Пружины" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23145,7 +23116,7 @@ msgstr "Межстрочный интервал" #: scene/3d/physics_joint.cpp msgid "Angular Limit Z" -msgstr "" +msgstr "Z Углового Предела" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23154,7 +23125,7 @@ msgstr "Угловая скорость" #: scene/3d/physics_joint.cpp msgid "Angular Spring Z" -msgstr "" +msgstr "Z Угловой Пружины" #: scene/3d/portal.cpp msgid "The RoomManager should not be a child or grandchild of a Portal." @@ -23174,7 +23145,7 @@ msgstr "Портал активен" #: scene/3d/portal.cpp scene/resources/occluder_shape_polygon.cpp msgid "Two Way" -msgstr "" +msgstr "В обе Стороны" #: scene/3d/portal.cpp msgid "Linked Room" @@ -27789,14 +27760,12 @@ msgid "Import S3TC" msgstr "Импорт" #: servers/visual_server.cpp -#, fuzzy msgid "Import ETC" -msgstr "Импорт" +msgstr "Импортировать ETC" #: servers/visual_server.cpp -#, fuzzy msgid "Import ETC2" -msgstr "Импорт" +msgstr "Импортировать ETC2" #: servers/visual_server.cpp #, fuzzy diff --git a/editor/translations/si.po b/editor/translations/si.po index bfba193a6a..8ce2d1d628 100644 --- a/editor/translations/si.po +++ b/editor/translations/si.po @@ -2120,14 +2120,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2183,8 +2184,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2744,8 +2745,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "ශ්රිත:" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5345,6 +5347,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11392,6 +11398,11 @@ msgid "New Animation" msgstr "සජීවීකරණ පුනරාවර්ථනය" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ශ්රිත:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19610,14 +19621,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19639,14 +19649,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/sk.po b/editor/translations/sk.po index f711be3039..7cba3886ba 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -2204,14 +2204,15 @@ msgstr "Obľúbené:" msgid "Recent:" msgstr "Nedávne:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Hľadať:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Zhody:" @@ -2271,8 +2272,8 @@ msgstr "Hľadať Náhradný Zdroj:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2853,8 +2854,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Skopírovať Výber" #: editor/editor_export.cpp #, fuzzy @@ -5658,6 +5660,10 @@ msgid "Drag And Drop Selection" msgstr "Všetky vybrané" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11963,6 +11969,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filter:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20652,15 +20663,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Nesprávna veľkosť písma." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20682,15 +20693,15 @@ msgstr "Neplatný Názov." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Nesprávna veľkosť písma." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/sl.po b/editor/translations/sl.po index aae6c8ba68..ceb21aa750 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -2223,14 +2223,15 @@ msgstr "Priljubljene:" msgid "Recent:" msgstr "Nedavni:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Iskanje:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Zadetki:" @@ -2292,8 +2293,8 @@ msgstr "Iskanje Nadomestnih Virov:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2886,8 +2887,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Odstrani izbrano" #: editor/editor_export.cpp #, fuzzy @@ -5729,6 +5731,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap Izbriši Izbor" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12183,6 +12189,11 @@ msgid "New Animation" msgstr "Animacija" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Lastnosti objekta." + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20951,15 +20962,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Uporabiti moraš valjavno razširitev." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20981,15 +20992,15 @@ msgstr "Neveljavno ime." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Uporabiti moraš valjavno razširitev." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/sq.po b/editor/translations/sq.po index f405b8b8a9..af72b686b9 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -2162,14 +2162,15 @@ msgstr "Të Preferuarat:" msgid "Recent:" msgstr "Të fundit:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Kërko:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Përputhjet:" @@ -2231,8 +2232,8 @@ msgstr "Kërko Resursin Zëvendësues:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2823,8 +2824,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Animacionet:" #: editor/editor_export.cpp #, fuzzy @@ -5665,6 +5667,10 @@ msgid "Drag And Drop Selection" msgstr "Fshi të Selektuarat" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11886,6 +11892,11 @@ msgid "New Animation" msgstr "Animacionin i Ri" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Nyjet filtruese" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20422,15 +20433,15 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Duhet të perdorësh një shtesë të lejuar." #: platform/windows/export/export.cpp msgid "Could not find signtool executable at \"%s\"." @@ -20452,15 +20463,15 @@ msgstr "Emër i palejuar." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Duhet të perdorësh një shtesë të lejuar." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index 9d7c4c5db8..4231d62c6b 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -2333,14 +2333,15 @@ msgstr "Омиљене:" msgid "Recent:" msgstr "Честе:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Тражи:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Подударање:" @@ -2402,8 +2403,8 @@ msgstr "Потражи замену за ресурс:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -3002,7 +3003,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Копирај Путању Чвора" #: editor/editor_export.cpp @@ -5978,6 +5979,10 @@ msgid "Drag And Drop Selection" msgstr "МапаМреже Испуни Одабрано" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12753,6 +12758,11 @@ msgstr "Анимација" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy +msgid "Filter animations" +msgstr "Филтрирај методе" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Speed:" msgstr "Брзина (FPS):" @@ -22352,15 +22362,15 @@ msgstr "Неуспешно отварање нацрта за извоз:" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Мора се користити важећа екстензија." #: platform/windows/export/export.cpp #, fuzzy @@ -22384,15 +22394,15 @@ msgstr "Неважеће име." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Мора се користити важећа екстензија." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index d3f588aca6..b898108402 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -2137,14 +2137,15 @@ msgstr "Omiljeno:" msgid "Recent:" msgstr "Nedavno:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Pretraga:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Podudaranja:" @@ -2204,8 +2205,8 @@ msgstr "Traži Resurs Zamene:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2768,8 +2769,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Kopiraj Označeno" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5364,6 +5366,10 @@ msgid "Drag And Drop Selection" msgstr "Sve sekcije" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11398,6 +11404,11 @@ msgid "New Animation" msgstr "Nova Animacija" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Animacija" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19699,14 +19710,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19728,14 +19738,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/sv.po b/editor/translations/sv.po index 08b57d1a25..9fd6b9bf67 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -14,7 +14,7 @@ # Mattias Münster <mattiasmun@gmail.com>, 2019. # Anonymous <noreply@weblate.org>, 2020. # Joakim Lundberg <joakim@joakimlundberg.com>, 2020. -# Kristoffer Grundström <swedishsailfishosuser@tutanota.com>, 2020, 2021. +# Kristoffer Grundström <swedishsailfishosuser@tutanota.com>, 2020, 2021, 2022. # Jonas Robertsson <jonas.robertsson@posteo.net>, 2020, 2021. # André Andersson <andre.eric.andersson@gmail.com>, 2020. # Andreas Westrell <andreas.westrell@gmail.com>, 2020. @@ -22,16 +22,18 @@ # Shaggy <anton_christoffersson@hotmail.com>, 2020. # Marcus Toftedahl <marcus.toftedahl@his.se>, 2020. # Alex25820 <Alexander_sjogren@hotmail.se>, 2021. -# Leon <joel.lundborg@gmail.com>, 2021. +# Leon <joel.lundborg@gmail.com>, 2021, 2022. # Kent Jofur <kent.jofur@gmail.com>, 2021. # Alex25820 <alexs25820@gmail.com>, 2021. +# Björn Åkesson <bjorn.akesson@gmail.com>, 2022. +# Kenny Andersson <kenny@ordinary.se>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-20 18:53+0000\n" -"Last-Translator: Alex25820 <alexs25820@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: Kenny Andersson <kenny@ordinary.se>\n" "Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/" "godot/sv/>\n" "Language: sv\n" @@ -39,11 +41,12 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.10\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp +#, fuzzy msgid "Tablet Driver" -msgstr "" +msgstr "Drivrutin för surfplatta" #: core/bind/core_bind.cpp #, fuzzy @@ -51,18 +54,16 @@ msgid "Clipboard" msgstr "Klippbordet är tomt!" #: core/bind/core_bind.cpp -#, fuzzy msgid "Current Screen" -msgstr "Nuvarande Scen" +msgstr "Nuvarande Skärm" #: core/bind/core_bind.cpp msgid "Exit Code" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "V-Sync Enabled" -msgstr "Aktivera" +msgstr "V-Synk Aktivt" #: core/bind/core_bind.cpp main/main.cpp msgid "V-Sync Via Compositor" @@ -73,9 +74,8 @@ msgid "Delta Smoothing" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "Low Processor Usage Mode" -msgstr "Exportera Projekt" +msgstr "Läge för låg processoranvändning" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode Sleep (µsec)" @@ -86,9 +86,8 @@ msgid "Keep Screen On" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "Min Window Size" -msgstr "Storlek:" +msgstr "Minsta fönsterstorlek" #: core/bind/core_bind.cpp #, fuzzy @@ -108,11 +107,11 @@ msgstr "Nytt Fönster" #: core/bind/core_bind.cpp core/project_settings.cpp msgid "Borderless" -msgstr "" +msgstr "Kantlös" #: core/bind/core_bind.cpp msgid "Per Pixel Transparency Enabled" -msgstr "" +msgstr "Genomskinlighet per pixel aktiverad" #: core/bind/core_bind.cpp core/project_settings.cpp #, fuzzy @@ -121,16 +120,16 @@ msgstr "Växla Fullskärm" #: core/bind/core_bind.cpp msgid "Maximized" -msgstr "" +msgstr "Maximerad" #: core/bind/core_bind.cpp msgid "Minimized" -msgstr "" +msgstr "Minimerad" #: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp #: scene/gui/graph_node.cpp msgid "Resizable" -msgstr "" +msgstr "Anpassningsbar" #: core/bind/core_bind.cpp core/os/input_event.cpp scene/2d/node_2d.cpp #: scene/2d/physics_body_2d.cpp scene/2d/remote_transform_2d.cpp @@ -150,36 +149,32 @@ msgstr "Dockposition" #: scene/resources/primitive_meshes.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp #: scene/resources/visual_shader.cpp servers/visual_server.cpp -#, fuzzy msgid "Size" -msgstr "Storlek:" +msgstr "Storlek" #: core/bind/core_bind.cpp msgid "Endian Swap" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "Editor Hint" -msgstr "Redigera Tema" +msgstr "Redigeringsförslag" #: core/bind/core_bind.cpp msgid "Print Error Messages" -msgstr "" +msgstr "Skriv ut felmeddelanden" #: core/bind/core_bind.cpp -#, fuzzy msgid "Iterations Per Second" -msgstr "Interpolationsläge" +msgstr "Upprepningar per sekund" #: core/bind/core_bind.cpp msgid "Target FPS" -msgstr "" +msgstr "Mål FPS" #: core/bind/core_bind.cpp -#, fuzzy msgid "Time Scale" -msgstr "Skala" +msgstr "Tidsskala" #: core/bind/core_bind.cpp main/main.cpp #, fuzzy @@ -201,13 +196,12 @@ msgid "Error Line" msgstr "Fel vid sparande" #: core/bind/core_bind.cpp -#, fuzzy msgid "Result" -msgstr "Sök Hjälp" +msgstr "Resultat" #: core/command_queue_mt.cpp core/message_queue.cpp main/main.cpp msgid "Memory" -msgstr "" +msgstr "Minne" #: core/command_queue_mt.cpp core/message_queue.cpp #: core/register_core_types.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp @@ -218,7 +212,7 @@ msgstr "" #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: servers/visual_server.cpp msgid "Limits" -msgstr "" +msgstr "Begränsningar" #: core/command_queue_mt.cpp #, fuzzy @@ -227,68 +221,63 @@ msgstr "Ctrl: Rotera" #: core/command_queue_mt.cpp msgid "Multithreading Queue Size (KB)" -msgstr "" +msgstr "Flertrådsköstorlek (KB)" #: core/func_ref.cpp modules/visual_script/visual_script_builtin_funcs.cpp #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp #: scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Function" -msgstr "Funktioner" +msgstr "Funktion" #: core/image.cpp core/packed_data_container.cpp scene/2d/polygon_2d.cpp #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Data" -msgstr "" +msgstr "Data" #: core/io/file_access_network.cpp core/register_core_types.cpp #: editor/editor_file_dialog.cpp editor/editor_settings.cpp main/main.cpp #: modules/gdscript/language_server/gdscript_language_server.cpp #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: scene/gui/file_dialog.cpp -#, fuzzy msgid "Network" -msgstr "Nätverksprofilerare" +msgstr "Nätverk" #: core/io/file_access_network.cpp -#, fuzzy msgid "Remote FS" -msgstr "Ta bort" +msgstr "Fjärr FS" #: core/io/file_access_network.cpp -#, fuzzy msgid "Page Size" -msgstr "Sida: " +msgstr "Sidstorlek" #: core/io/file_access_network.cpp msgid "Page Read Ahead" -msgstr "" +msgstr "Sida läs framåt" #: core/io/http_client.cpp msgid "Blocking Mode Enabled" -msgstr "" +msgstr "Blockeringsläge Aktiverat" #: core/io/http_client.cpp -#, fuzzy msgid "Connection" -msgstr "Anslut" +msgstr "Anslutning" #: core/io/http_client.cpp msgid "Read Chunk Size" -msgstr "" +msgstr "Läs segmentstorlek" #: core/io/marshalls.cpp msgid "Object ID" -msgstr "" +msgstr "Objekt ID" #: core/io/multiplayer_api.cpp core/io/packet_peer.cpp msgid "Allow Object Decoding" -msgstr "" +msgstr "Tillåt objekt avkodning" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp msgid "Refuse New Network Connections" -msgstr "" +msgstr "Neka nya nätverksanslutningar" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp #, fuzzy @@ -312,36 +301,35 @@ msgstr "Transformera" #: core/io/packet_peer.cpp msgid "Encode Buffer Max Size" -msgstr "" +msgstr "Maxstorlek för kodningsbufferten" #: core/io/packet_peer.cpp msgid "Input Buffer Max Size" -msgstr "" +msgstr "Maximal storlek på inmatningsbufferten" #: core/io/packet_peer.cpp msgid "Output Buffer Max Size" -msgstr "" +msgstr "Maxstorlek för utgångsbuffert" #: core/io/packet_peer.cpp msgid "Stream Peer" -msgstr "" +msgstr "Strömningsenhet" #: core/io/stream_peer.cpp msgid "Big Endian" -msgstr "" +msgstr "Big Endian" #: core/io/stream_peer.cpp msgid "Data Array" -msgstr "" +msgstr "Datamatris" #: core/io/stream_peer_ssl.cpp msgid "Blocking Handshake" -msgstr "" +msgstr "Blockering av handskakning" #: core/io/udp_server.cpp -#, fuzzy msgid "Max Pending Connections" -msgstr "Redigera Koppling:" +msgstr "Max väntande anslutningar" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -356,12 +344,11 @@ msgstr "Förväntade en sträng av längden 1 (ett tecken)." #: modules/mono/glue/gd_glue.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Not enough bytes for decoding bytes, or invalid format." -msgstr "Inte nog med bytes för att avkoda, eller ogiltigt format." +msgstr "Otillräckligt antal bytes för att avkoda, eller ogiltigt format." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %d (not passed) in expression" -msgstr "Ogiltig indata %i (ej överförd) i uttrycket" +msgstr "Ogiltig inmatning %d (ej överförd) i uttrycket" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -390,7 +377,7 @@ msgstr "I anrop till '%s':" #: core/math/random_number_generator.cpp #: modules/opensimplex/open_simplex_noise.cpp msgid "Seed" -msgstr "" +msgstr "Seed" #: core/math/random_number_generator.cpp #, fuzzy @@ -399,11 +386,11 @@ msgstr "Status" #: core/message_queue.cpp msgid "Message Queue" -msgstr "" +msgstr "Meddelandekö" #: core/message_queue.cpp msgid "Max Size (KB)" -msgstr "" +msgstr "Maxstorlek (KB)" #: core/os/input.cpp #, fuzzy @@ -412,7 +399,7 @@ msgstr "Växla Läge" #: core/os/input.cpp msgid "Use Accumulated Input" -msgstr "" +msgstr "Använd ackumulerad input" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: servers/audio_server.cpp @@ -420,13 +407,12 @@ msgid "Device" msgstr "Enhet" #: core/os/input_event.cpp -#, fuzzy msgid "Alt" -msgstr "Alla" +msgstr "Alt" #: core/os/input_event.cpp msgid "Shift" -msgstr "" +msgstr "Shift" #: core/os/input_event.cpp #, fuzzy @@ -435,7 +421,7 @@ msgstr "Versionshantering" #: core/os/input_event.cpp msgid "Meta" -msgstr "" +msgstr "Meta" #: core/os/input_event.cpp #, fuzzy @@ -455,9 +441,8 @@ msgid "Pressed" msgstr "Återställ Zoom" #: core/os/input_event.cpp -#, fuzzy msgid "Scancode" -msgstr "Skanna" +msgstr "Scancode" #: core/os/input_event.cpp msgid "Physical Scancode" @@ -465,7 +450,7 @@ msgstr "" #: core/os/input_event.cpp msgid "Unicode" -msgstr "" +msgstr "Unicode" #: core/os/input_event.cpp msgid "Echo" @@ -482,9 +467,8 @@ msgid "Global Position" msgstr "Konstant" #: core/os/input_event.cpp -#, fuzzy msgid "Factor" -msgstr "Vektor" +msgstr "Faktor" #: core/os/input_event.cpp #, fuzzy @@ -493,25 +477,23 @@ msgstr "Automatisk Indentering" #: core/os/input_event.cpp msgid "Doubleclick" -msgstr "" +msgstr "Dubbelklick" #: core/os/input_event.cpp msgid "Tilt" msgstr "" #: core/os/input_event.cpp -#, fuzzy msgid "Pressure" -msgstr "Återställ Zoom" +msgstr "Tryck" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Invertera penna" #: core/os/input_event.cpp -#, fuzzy msgid "Relative" -msgstr "GDNative" +msgstr "Relativ" #: core/os/input_event.cpp scene/2d/camera_2d.cpp scene/2d/cpu_particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/interpolated_camera.cpp @@ -527,9 +509,8 @@ msgid "Axis" msgstr "Axel" #: core/os/input_event.cpp -#, fuzzy msgid "Axis Value" -msgstr "Värde" +msgstr "Axelvärde" #: core/os/input_event.cpp modules/visual_script/visual_script_func_nodes.cpp #, fuzzy @@ -545,21 +526,19 @@ msgstr "Åtgärd" #: core/os/input_event.cpp scene/resources/environment.cpp #: scene/resources/material.cpp msgid "Strength" -msgstr "" +msgstr "Styrka" #: core/os/input_event.cpp msgid "Delta" -msgstr "" +msgstr "Delta" #: core/os/input_event.cpp -#, fuzzy msgid "Channel" -msgstr "Ändra" +msgstr "Kanal" #: core/os/input_event.cpp main/main.cpp -#, fuzzy msgid "Message" -msgstr "Synkronisera Skript-ändringar" +msgstr "Meddelande" #: core/os/input_event.cpp #, fuzzy @@ -570,11 +549,11 @@ msgstr "Växla" #: scene/2d/physics_body_2d.cpp scene/3d/cpu_particles.cpp #: scene/3d/physics_body.cpp scene/resources/particles_material.cpp msgid "Velocity" -msgstr "" +msgstr "Hastighet" #: core/os/input_event.cpp msgid "Instrument" -msgstr "" +msgstr "Instrument" #: core/os/input_event.cpp #, fuzzy @@ -588,13 +567,13 @@ msgstr "" #: core/project_settings.cpp editor/editor_node.cpp main/main.cpp #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Application" -msgstr "Åtgärd" +msgstr "Applikation" #: core/project_settings.cpp main/main.cpp +#, fuzzy msgid "Config" -msgstr "" +msgstr "Konfigurera" #: core/project_settings.cpp #, fuzzy @@ -630,7 +609,7 @@ msgstr "Kör" #: core/project_settings.cpp editor/editor_node.cpp #: editor/run_settings_dialog.cpp main/main.cpp msgid "Main Scene" -msgstr "" +msgstr "Huvudscen" #: core/project_settings.cpp #, fuzzy @@ -644,15 +623,15 @@ msgstr "Avaktiverad" #: core/project_settings.cpp msgid "Use Hidden Project Data Directory" -msgstr "" +msgstr "Använda dold projektdatakatalog" #: core/project_settings.cpp msgid "Use Custom User Dir" -msgstr "" +msgstr "Använd anpassad användarkatalog" #: core/project_settings.cpp msgid "Custom User Dir Name" -msgstr "" +msgstr "Anpassad användarkatalognamn" #: core/project_settings.cpp main/main.cpp #: platform/javascript/export/export.cpp platform/osx/export/export.cpp @@ -665,7 +644,7 @@ msgstr "Ersätt Alla" #: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp #: scene/3d/label_3d.cpp scene/gui/text_edit.cpp scene/resources/texture.cpp msgid "Width" -msgstr "" +msgstr "Bredd" #: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp #: modules/gltf/gltf_node.cpp modules/opensimplex/noise_texture.cpp @@ -673,13 +652,12 @@ msgstr "" #: scene/resources/capsule_shape_2d.cpp scene/resources/cylinder_shape.cpp #: scene/resources/font.cpp scene/resources/navigation_mesh.cpp #: scene/resources/primitive_meshes.cpp scene/resources/texture.cpp -#, fuzzy msgid "Height" -msgstr "Höger" +msgstr "Höjd" #: core/project_settings.cpp msgid "Always On Top" -msgstr "" +msgstr "Alltid överst" #: core/project_settings.cpp #, fuzzy @@ -706,11 +684,11 @@ msgstr "Ladda standard Buss-Layouten." #: editor/editor_settings.cpp editor/script_create_dialog.cpp #: scene/2d/camera_2d.cpp scene/3d/light.cpp scene/main/node.cpp msgid "Editor" -msgstr "" +msgstr "Redigerare" #: core/project_settings.cpp msgid "Main Run Args" -msgstr "" +msgstr "Huvudkörnings arg" #: core/project_settings.cpp #, fuzzy @@ -719,11 +697,12 @@ msgstr "Scen Filsökväg:" #: core/project_settings.cpp msgid "Search In File Extensions" -msgstr "" +msgstr "Sök i filändelser" #: core/project_settings.cpp +#, fuzzy msgid "Script Templates Search Path" -msgstr "" +msgstr "Sökväg för skriptmallar" #: core/project_settings.cpp #, fuzzy @@ -738,16 +717,16 @@ msgstr "Versionshantering" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp msgid "Input" -msgstr "" +msgstr "Input" #: core/project_settings.cpp +#, fuzzy msgid "UI Accept" -msgstr "" +msgstr "UI Acceptera" #: core/project_settings.cpp -#, fuzzy msgid "UI Select" -msgstr "Välj" +msgstr "Ui Välj" #: core/project_settings.cpp #, fuzzy @@ -779,9 +758,8 @@ msgid "UI Up" msgstr "" #: core/project_settings.cpp -#, fuzzy msgid "UI Down" -msgstr "Ladda ner" +msgstr "UI Ner" #: core/project_settings.cpp #, fuzzy @@ -790,11 +768,11 @@ msgstr "Sida: " #: core/project_settings.cpp msgid "UI Page Down" -msgstr "" +msgstr "UI sida ner" #: core/project_settings.cpp msgid "UI Home" -msgstr "" +msgstr "UI hem" #: core/project_settings.cpp msgid "UI End" @@ -931,7 +909,7 @@ msgstr "" #: core/register_core_types.cpp msgid "TCP" -msgstr "" +msgstr "TCP" #: core/register_core_types.cpp #, fuzzy @@ -944,11 +922,12 @@ msgstr "" #: core/register_core_types.cpp msgid "Max Buffer (Power of 2)" -msgstr "" +msgstr "Max buffer (2 potenser)" #: core/register_core_types.cpp editor/editor_settings.cpp main/main.cpp +#, fuzzy msgid "SSL" -msgstr "" +msgstr "SSL" #: core/register_core_types.cpp main/main.cpp #, fuzzy @@ -964,7 +943,7 @@ msgstr "Resurs" #: core/resource.cpp #, fuzzy msgid "Local To Scene" -msgstr "Stäng Scen" +msgstr "Lokalt till scenen" #: core/resource.cpp editor/dependency_editor.cpp #: editor/editor_autoload_settings.cpp editor/plugins/path_editor_plugin.cpp @@ -983,12 +962,13 @@ msgid "Locale" msgstr "" #: core/translation.cpp +#, fuzzy msgid "Test" -msgstr "" +msgstr "Test" #: core/translation.cpp scene/resources/font.cpp msgid "Fallback" -msgstr "" +msgstr "Reserv" #: core/ustring.cpp scene/resources/segment_shape_2d.cpp msgid "B" @@ -1023,18 +1003,21 @@ msgstr "EiB" #: drivers/gles3/rasterizer_canvas_base_gles3.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp modules/gltf/gltf_state.cpp +#, fuzzy msgid "Buffers" -msgstr "" +msgstr "Buffertar" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp +#, fuzzy msgid "Canvas Polygon Buffer Size (KB)" -msgstr "" +msgstr "Buffertstorlek för canvaspolygon (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp +#, fuzzy msgid "Canvas Polygon Index Buffer Size (KB)" -msgstr "" +msgstr "Buffertstorlek för Canvas Polygon Index (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp editor/editor_settings.cpp @@ -1045,8 +1028,9 @@ msgstr "" #: servers/physics_2d/physics_2d_server_wrap_mt.h #: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp #: servers/visual_server.cpp +#, fuzzy msgid "2D" -msgstr "" +msgstr "2D" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp @@ -1057,42 +1041,47 @@ msgstr "Alternativ" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Use GPU Pixel Snap" -msgstr "" +msgstr "Använd GPU pixel vidhäftning" #: drivers/gles2/rasterizer_scene_gles2.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Immediate Buffer Size (KB)" -msgstr "" +msgstr "Omedelbar buffertstorlek (KB)" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp +#, fuzzy msgid "Lightmapping" -msgstr "" +msgstr "Ljusmappning" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp +#, fuzzy msgid "Use Bicubic Sampling" -msgstr "" +msgstr "Använd bikubisk sampling" #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Max Renderable Elements" -msgstr "" +msgstr "Max återgivningsbara element" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Lights" -msgstr "" +msgstr "Max renderbara ljuskällor" #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Max Renderable Reflections" -msgstr "" +msgstr "Max renderingsbara reflektioner" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Lights Per Object" -msgstr "" +msgstr "Max antal ljuskällor per objekt" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Subsurface Scattering" -msgstr "" +msgstr "Subsurface Scattering" #: drivers/gles3/rasterizer_scene_gles3.cpp editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp @@ -1116,16 +1105,19 @@ msgid "Weight Samples" msgstr "" #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Voxel Cone Tracing" -msgstr "" +msgstr "Voxel Kon Spårning" #: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp +#, fuzzy msgid "High Quality" -msgstr "" +msgstr "Hög kvalitet" #: drivers/gles3/rasterizer_storage_gles3.cpp +#, fuzzy msgid "Blend Shape Max Buffer Size (KB)" -msgstr "" +msgstr "Mixform Max buffertstorlek (KB)" #. TRANSLATORS: Adjective, refers to the mode for Bezier handles (Free, Balanced, Mirror). #: editor/animation_bezier_editor.cpp @@ -1178,7 +1170,7 @@ msgstr "Anim Ta Bort Nycklar" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Time" -msgstr "Anim Ändra Nyckelbildstid" +msgstr "Anim Ändra Tidsnyckelns Tid" #: editor/animation_track_editor.cpp msgid "Anim Change Transition" @@ -1236,7 +1228,7 @@ msgstr "Välj Färg" #: editor/animation_track_editor.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp msgid "Args" -msgstr "" +msgstr "Argument" #: editor/animation_track_editor.cpp editor/editor_settings.cpp #: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp @@ -1247,23 +1239,25 @@ msgstr "Typ" #: editor/animation_track_editor.cpp msgid "In Handle" -msgstr "" +msgstr "Handtag in" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Out Handle" -msgstr "" +msgstr "Handtag ut" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp +#, fuzzy msgid "Stream" -msgstr "" +msgstr "Ström" #: editor/animation_track_editor.cpp #, fuzzy msgid "Start Offset" -msgstr "Icon Läge" +msgstr "Startförskjutning" #: editor/animation_track_editor.cpp #, fuzzy @@ -1282,7 +1276,7 @@ msgstr "Animation" #: editor/animation_track_editor.cpp msgid "Easing" -msgstr "" +msgstr "Lätta" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -1435,7 +1429,7 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Out-Handle:" -msgstr "" +msgstr "Handtag ut:" #: editor/animation_track_editor.cpp #, fuzzy @@ -1448,8 +1442,9 @@ msgid "Start (s):" msgstr "Starta" #: editor/animation_track_editor.cpp +#, fuzzy msgid "End (s):" -msgstr "" +msgstr "Slut (s):" #: editor/animation_track_editor.cpp #, fuzzy @@ -1509,7 +1504,7 @@ msgstr "Duplicera Nycklar" #: editor/animation_track_editor.cpp msgid "Add RESET Value(s)" -msgstr "" +msgstr "Lägg till RESET-värde(n)" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -1591,7 +1586,7 @@ msgstr "" #. TRANSLATORS: This describes the target of new animation track, will be inserted into another string. #: editor/animation_track_editor.cpp msgid "property '%s'" -msgstr "egenskapen '%s'" +msgstr "egenskap '%s'" #: editor/animation_track_editor.cpp msgid "Anim Create & Insert" @@ -1824,9 +1819,8 @@ msgid "Go to Previous Step" msgstr "Gå till Föregående Steg" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Apply Reset" -msgstr "Återställ Zoom" +msgstr "Verkställ återställning" #: editor/animation_track_editor.cpp msgid "Optimize Animation" @@ -2209,14 +2203,15 @@ msgstr "Favoriter:" msgid "Recent:" msgstr "Senaste:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Sök:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Matchar:" @@ -2276,8 +2271,8 @@ msgstr "Sök Ersättningsresurs:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2286,17 +2281,17 @@ msgstr "Öppna" #: editor/dependency_editor.cpp msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "Ägare av: %s (Totalt: %d)" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Remove the selected files from the project? (Cannot be undone.)\n" "Depending on your filesystem configuration, the files will either be moved " "to the system trash or deleted permanently." msgstr "" -"Ta bort valda filer från projektet? (Kan ej återställas)\n" -"Du kan hitta de borttagna filerna i systemets papperskorg." +"Ta bort de valda filerna från projektet? (Kan ej ångras.)\n" +"Beroende på hur ditt filsystem är konfigurerat så kommer filerna antingen " +"flyttas till systemets papperskorg eller tas bort permanent." #: editor/dependency_editor.cpp msgid "" @@ -2381,7 +2376,7 @@ msgstr "Tack från Godot-gemenskapen!" #: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp msgid "Click to copy." -msgstr "Klicka för att kopiera." +msgstr "Klicka för att kopiera" #: editor/editor_about.cpp msgid "Godot Engine contributors" @@ -2479,30 +2474,32 @@ msgid "Licenses" msgstr "Licenser" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Error opening asset file for \"%s\" (not in ZIP format)." -msgstr "Fel vid öppning av paketetfil, inte i zip-format." +msgstr "Fel vid öppning av tillgångsfilen för \"%s\" (inte i ZIP-format)." #: editor/editor_asset_installer.cpp msgid "%s (already exists)" msgstr "%s (existerar redan)" #: editor/editor_asset_installer.cpp +#, fuzzy msgid "Contents of asset \"%s\" - %d file(s) conflict with your project:" msgstr "" +"Innehållet i resursen \"%s\" - %d fil(er) står i konflikt med ditt projekt:" #: editor/editor_asset_installer.cpp +#, fuzzy msgid "Contents of asset \"%s\" - No files conflict with your project:" msgstr "" +"Innehållet i resursen \"%s\" - Inga filer står i konflikt med ditt projekt:" #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" msgstr "Dekomprimerar Tillgångar" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "The following files failed extraction from asset \"%s\":" -msgstr "Följande filer misslyckades att packas upp från paketet:" +msgstr "Följande filer misslyckades att packas upp från paketet \"%s\":" #: editor/editor_asset_installer.cpp msgid "(and %s more files)" @@ -2510,7 +2507,7 @@ msgstr "(och %s fler filer)" #: editor/editor_asset_installer.cpp msgid "Asset \"%s\" installed successfully!" -msgstr "Paketet \"%s\" har installerats!" +msgstr "Installation av tillgången \"%s\" lyckades!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -2522,9 +2519,8 @@ msgid "Install" msgstr "Installera" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Asset Installer" -msgstr "Paketinstallerare" +msgstr "Tillgångsinstallerare" #: editor/editor_audio_buses.cpp msgid "Speakers" @@ -2705,8 +2701,9 @@ msgid "Invalid name." msgstr "Ogiltigt namn." #: editor/editor_autoload_settings.cpp +#, fuzzy msgid "Cannot begin with a digit." -msgstr "" +msgstr "Kan inte börja med en siffra." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -2771,7 +2768,7 @@ msgstr "%s är en ogiltig genväg. Filen existerar inte." #: editor/editor_autoload_settings.cpp msgid "%s is an invalid path. Not in resource path (res://)." -msgstr "" +msgstr "%s är en ogiltig genväg. Inte i resurs-genväg (res://)." #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" @@ -2851,11 +2848,11 @@ msgstr "Välj" #: editor/editor_export.cpp msgid "Project export for platform:" -msgstr "" +msgstr "Projektexport för plattformen:" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Kopiera Nod-Sökväg" #: editor/editor_export.cpp @@ -2938,8 +2935,8 @@ msgid "" "Target platform requires 'PVRTC' texture compression for GLES2. Enable " "'Import Pvrtc' in Project Settings." msgstr "" -"Målplattformen kräver 'PVRTC'-texturkomprimering för GLES2. Aktivera 'Import " -"Pvrtc' i projektinställningarna." +"Målplattformen kräver 'PVRTC' texturkomprimering för GLES2. Aktivera " +"'Importera Pvrtc' i Projektinställningarna." #: editor/editor_export.cpp msgid "" @@ -2971,7 +2968,7 @@ msgstr "Redigera Tema" #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #: platform/uwp/export/export.cpp msgid "Release" -msgstr "" +msgstr "Släpp" #: editor/editor_export.cpp #, fuzzy @@ -2980,11 +2977,12 @@ msgstr "Färg enhetlig." #: editor/editor_export.cpp msgid "64 Bits" -msgstr "" +msgstr "64 bitar" #: editor/editor_export.cpp +#, fuzzy msgid "Embed PCK" -msgstr "" +msgstr "Bädda in PCK" #: editor/editor_export.cpp platform/osx/export/export.cpp #, fuzzy @@ -3046,7 +3044,7 @@ msgstr "Hantera exportmallar..." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp msgid "PCK Embedding" -msgstr "" +msgstr "PCK Inbäddning" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." @@ -3054,7 +3052,7 @@ msgstr "Den inbäddade PCK får inte vara större än 4 GiB på 32 bitars export #: editor/editor_export.cpp msgid "Convert Text Resources To Binary On Export" -msgstr "" +msgstr "Konvertera textresurser till binära vid export" #: editor/editor_feature_profile.cpp msgid "3D Editor" @@ -3083,9 +3081,8 @@ msgid "FileSystem Dock" msgstr "FilSystem" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Importera" +msgstr "Importera Brygga" #: editor/editor_feature_profile.cpp msgid "Allows to view and edit 3D scenes." @@ -3097,17 +3094,19 @@ msgstr "Tillåter att redigera skript via den integrerade skript-redigeraren." #: editor/editor_feature_profile.cpp msgid "Provides built-in access to the Asset Library." -msgstr "" +msgstr "Ger inbyggd tillgång till tillgångsbiblioteket." #: editor/editor_feature_profile.cpp +#, fuzzy msgid "Allows editing the node hierarchy in the Scene dock." -msgstr "" +msgstr "Tillåter redigering av nodhierarkin i scendockan." #: editor/editor_feature_profile.cpp msgid "" "Allows to work with signals and groups of the node selected in the Scene " "dock." msgstr "" +"Tillåter arbete med signaler och grupper av noden som valts i Scendockan." #: editor/editor_feature_profile.cpp msgid "Allows to browse the local file system via a dedicated dock." @@ -3145,19 +3144,16 @@ msgid "(Editor Disabled, Properties Disabled)" msgstr "(Editor inaktiverad, Egenskaper inaktiverad)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Egenskaper" +msgstr "(Egenskaper avstängda)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Redigera Variabel" +msgstr "(Redigeraren är avstängd)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Beskrivning:" +msgstr "Klassalternativ:" #: editor/editor_feature_profile.cpp msgid "Enable Contextual Editor" @@ -3194,9 +3190,8 @@ msgid "Error saving profile to path: '%s'." msgstr "Fel vid laddning av mall '%s'." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Reset to Default" -msgstr "Ladda Standard" +msgstr "Återställ till Standard" #: editor/editor_feature_profile.cpp msgid "Current Profile:" @@ -3249,18 +3244,16 @@ msgid "Create or import a profile to edit available classes and properties." msgstr "" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Nytt namn:" +msgstr "Nytt profilnamn:" #: editor/editor_feature_profile.cpp msgid "Godot Feature Profile" msgstr "Godot funktions profil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "%d fler filer" +msgstr "Importera profil(er)" #: editor/editor_feature_profile.cpp #, fuzzy @@ -3294,9 +3287,8 @@ msgid "Copy Path" msgstr "Kopiera Sökväg" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "Open in File Manager" -msgstr "Visa I Filhanteraren" +msgstr "Öppna i filhanteraren" #: editor/editor_file_dialog.cpp editor/editor_node.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp @@ -5556,7 +5548,7 @@ msgstr "Miniatyr..." #: editor/editor_settings.cpp msgid "Docks" -msgstr "" +msgstr "Anslutningar" #: editor/editor_settings.cpp #, fuzzy @@ -5674,6 +5666,10 @@ msgid "Drag And Drop Selection" msgstr "Alla urval" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11301,7 +11297,7 @@ msgstr "Spela" #: editor/plugins/spatial_editor_plugin.cpp msgid "Orthogonal" -msgstr "" +msgstr "Ortogonal" #: editor/plugins/spatial_editor_plugin.cpp modules/gltf/gltf_camera.cpp msgid "Perspective" @@ -11468,7 +11464,7 @@ msgstr "Partiklar" #: editor/plugins/spatial_editor_plugin.cpp msgid "FPS: %d (%s ms)" -msgstr "" +msgstr "FPS: %d (%s ms)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Top View." @@ -12049,6 +12045,11 @@ msgid "New Animation" msgstr "Animation" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrera noder" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20722,15 +20723,15 @@ msgstr "Det gick inte att hitta nyckellager, det gick inte att exportera." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Måste använda en giltigt filändelse." #: platform/windows/export/export.cpp #, fuzzy @@ -20754,15 +20755,15 @@ msgstr "Ogiltigt namn." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Måste använda en giltigt filändelse." #: platform/windows/export/export.cpp #, fuzzy @@ -24738,8 +24739,9 @@ msgid "Alpha" msgstr "" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#, fuzzy msgid "Caret" -msgstr "" +msgstr "Markör" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Blink" @@ -25397,9 +25399,8 @@ msgid "Draw 2D Outlines" msgstr "" #: scene/main/scene_tree.cpp servers/visual_server.cpp -#, fuzzy msgid "Reflections" -msgstr "Riktningar" +msgstr "Reflektioner" #: scene/main/scene_tree.cpp msgid "Atlas Size" @@ -28332,12 +28333,13 @@ msgid "UV Contract Amount" msgstr "" #: servers/visual_server.cpp +#, fuzzy msgid "Use Simple PVS" -msgstr "" +msgstr "Använd enkel PVS" #: servers/visual_server.cpp msgid "PVS Logging" -msgstr "" +msgstr "PVS loggning" #: servers/visual_server.cpp #, fuzzy @@ -28350,8 +28352,9 @@ msgid "Remove Danglers" msgstr "Ta Bort Mall" #: servers/visual_server.cpp +#, fuzzy msgid "Flip Imported Portals" -msgstr "" +msgstr "Vänd importerade portaler" #: servers/visual_server.cpp #, fuzzy @@ -28359,8 +28362,9 @@ msgid "Occlusion Culling" msgstr "Redigera Polygon" #: servers/visual_server.cpp +#, fuzzy msgid "Max Active Spheres" -msgstr "" +msgstr "Max aktiva sfärer" #: servers/visual_server.cpp #, fuzzy @@ -28373,13 +28377,15 @@ msgid "Shader Compilation Mode" msgstr "Interpolationsläge" #: servers/visual_server.cpp +#, fuzzy msgid "Max Simultaneous Compiles" -msgstr "" +msgstr "Max samtidiga kompileringar" #: servers/visual_server.cpp msgid "Log Active Async Compiles Count" msgstr "" #: servers/visual_server.cpp +#, fuzzy msgid "Shader Cache Size (MB)" -msgstr "" +msgstr "Shader Cache Storlek (MB)" diff --git a/editor/translations/te.po b/editor/translations/te.po index 98eb54ce5c..af4c65f062 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -2074,14 +2074,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2137,8 +2138,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2697,8 +2698,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "సంఘం" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5271,6 +5273,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11232,6 +11238,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "గణనలు" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -19314,14 +19325,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -19342,14 +19352,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/th.po b/editor/translations/th.po index 9460318ef8..f1eb8b716f 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -2223,14 +2223,15 @@ msgstr "ที่ชื่นชอบ:" msgid "Recent:" msgstr "ล่าสุด:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "ค้นหา:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "พบ:" @@ -2291,8 +2292,8 @@ msgstr "ค้นหาทรัพยากรมาแทนที่:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2874,7 +2875,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "คัดลอกตำแหน่งโหนด" #: editor/editor_export.cpp @@ -5653,6 +5654,10 @@ msgid "Drag And Drop Selection" msgstr "เติมที่เลือกใน GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11947,6 +11952,11 @@ msgid "New Animation" msgstr "แอนิเมชันใหม่" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "วิธีการกรอง" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "ความเร็ว:" @@ -20700,15 +20710,15 @@ msgstr "เปิดเทมเพลตเพื่อส่งออกไม #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "นามสกุลไม่ถูกต้อง" #: platform/windows/export/export.cpp #, fuzzy @@ -20732,15 +20742,15 @@ msgstr "ชื่อผิดพลาด" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "นามสกุลไม่ถูกต้อง" #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/tl.po b/editor/translations/tl.po index a7a9bacaeb..fec7766383 100644 --- a/editor/translations/tl.po +++ b/editor/translations/tl.po @@ -2175,14 +2175,15 @@ msgstr "Mga Paborito:" msgid "Recent:" msgstr "Kamakailan:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Maghanap:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Mga Tugma:" @@ -2242,8 +2243,8 @@ msgstr "Maghanap ng Pangpalit na Resource:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2813,8 +2814,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr "Kopyahin Ang Pinagpipilian" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5467,6 +5469,10 @@ msgid "Drag And Drop Selection" msgstr "Kopyahin Ang Pinagpipilian" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11573,6 +11579,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Salain ang mga method" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Bilis:" @@ -19970,14 +19981,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -20000,14 +20010,13 @@ msgstr "Di-wastong pangalan." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 3cbd52b7e4..ab58a87c36 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -74,13 +74,17 @@ # Ramazan Aslan <legendraslan@gmail.com>, 2022. # paledega <paledega@yandex.ru>, 2022. # Yekez <yasintonge@gmail.com>, 2022. +# Deleted User <noreply+46833@weblate.org>, 2022. +# Emre <mr.inkaya@gmail.com>, 2022. +# Deleted User <noreply+46858@weblate.org>, 2022. +# Ümid Quliyev <lucifer25x@protonmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-03 00:44+0000\n" -"Last-Translator: Yekez <yasintonge@gmail.com>\n" +"PO-Revision-Date: 2022-08-05 01:04+0000\n" +"Last-Translator: Ümid Quliyev <lucifer25x@protonmail.com>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot/tr/>\n" "Language: tr\n" @@ -88,7 +92,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -333,15 +337,15 @@ msgstr "Transfer Modu" #: core/io/packet_peer.cpp msgid "Encode Buffer Max Size" -msgstr "" +msgstr "Kodlama Arabelleği Maksimum Boyutu" #: core/io/packet_peer.cpp msgid "Input Buffer Max Size" -msgstr "" +msgstr "Giriş Arabelleği Maksimum Boyutu" #: core/io/packet_peer.cpp msgid "Output Buffer Max Size" -msgstr "" +msgstr "Çıkış Arabelleği Maksimum Boyutu" #: core/io/packet_peer.cpp msgid "Stream Peer" @@ -349,15 +353,15 @@ msgstr "" #: core/io/stream_peer.cpp msgid "Big Endian" -msgstr "" +msgstr "big-endian" #: core/io/stream_peer.cpp msgid "Data Array" -msgstr "" +msgstr "Veri Dizisi" #: core/io/stream_peer_ssl.cpp msgid "Blocking Handshake" -msgstr "" +msgstr "Tokalaşmayı blokla" #: core/io/udp_server.cpp msgid "Max Pending Connections" @@ -383,12 +387,10 @@ msgid "Invalid input %d (not passed) in expression" msgstr "İfadede geçersiz giriş %d" #: core/math/expression.cpp -#, fuzzy msgid "self can't be used because instance is null (not passed)" msgstr "self kullanılamaz çünkü örnek boş (geçilmedi)" #: core/math/expression.cpp -#, fuzzy msgid "Invalid operands to operator %s, %s and %s." msgstr "\"%s\" işlecinde geçersiz terimler, '%s' ve '%s'." @@ -411,7 +413,7 @@ msgstr "'%s' çağrıldığında:" #: core/math/random_number_generator.cpp #: modules/opensimplex/open_simplex_noise.cpp msgid "Seed" -msgstr "" +msgstr "Tohum" #: core/math/random_number_generator.cpp msgid "State" @@ -426,14 +428,12 @@ msgid "Max Size (KB)" msgstr "En Büyük Boyut (KB)" #: core/os/input.cpp -#, fuzzy msgid "Mouse Mode" -msgstr "Biçimi Taşı" +msgstr "Fare Modu" #: core/os/input.cpp -#, fuzzy msgid "Use Accumulated Input" -msgstr "Girişi Sil" +msgstr "Birikmiş Girdiyi Kullan" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: servers/audio_server.cpp @@ -449,12 +449,10 @@ msgid "Shift" msgstr "Shift" #: core/os/input_event.cpp -#, fuzzy msgid "Control" -msgstr "Ctrl" +msgstr "Kontrol Tuşu" #: core/os/input_event.cpp -#, fuzzy msgid "Meta" msgstr "Meta" @@ -463,9 +461,8 @@ msgid "Command" msgstr "Komut" #: core/os/input_event.cpp -#, fuzzy msgid "Physical" -msgstr " (Fiziksel)" +msgstr "Fiziksel" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp @@ -474,7 +471,6 @@ msgid "Pressed" msgstr "Basılmış" #: core/os/input_event.cpp -#, fuzzy msgid "Scancode" msgstr "Tarama kodu" @@ -483,14 +479,12 @@ msgid "Physical Scancode" msgstr "Fiziksel Tuş Kodu" #: core/os/input_event.cpp -#, fuzzy msgid "Unicode" -msgstr "Unicode" +msgstr "Evrensel Kod" #: core/os/input_event.cpp -#, fuzzy msgid "Echo" -msgstr "Eko" +msgstr "Yankı" #: core/os/input_event.cpp scene/gui/base_button.cpp msgid "Button Mask" @@ -501,9 +495,8 @@ msgid "Global Position" msgstr "Global Pozisyon" #: core/os/input_event.cpp -#, fuzzy msgid "Factor" -msgstr "Vektör" +msgstr "Etken" #: core/os/input_event.cpp msgid "Button Index" @@ -522,8 +515,9 @@ msgid "Pressure" msgstr "Baskı" #: core/os/input_event.cpp +#, fuzzy msgid "Pen Inverted" -msgstr "" +msgstr "Ters Kalem" #: core/os/input_event.cpp msgid "Relative" @@ -584,18 +578,16 @@ msgid "Velocity" msgstr "Hız" #: core/os/input_event.cpp -#, fuzzy msgid "Instrument" msgstr "Alet" #: core/os/input_event.cpp -#, fuzzy msgid "Controller Number" -msgstr "Satır Numarası:" +msgstr "Denetleyici Numarası" #: core/os/input_event.cpp msgid "Controller Value" -msgstr "" +msgstr "Denetleyici Değeri" #: core/project_settings.cpp editor/editor_node.cpp main/main.cpp #: platform/iphone/export/export.cpp platform/osx/export/export.cpp @@ -719,7 +711,7 @@ msgstr "Ana Sahne Değiştirgenleri:" #: core/project_settings.cpp #, fuzzy msgid "Scene Naming" -msgstr "Sahne Yolu:" +msgstr "Sahne Adlandırma" #: core/project_settings.cpp msgid "Search In File Extensions" @@ -732,12 +724,12 @@ msgstr "Script Dosyalarını Aramak İçin Dosya Yolu" #: core/project_settings.cpp #, fuzzy msgid "Version Control Autoload On Startup" -msgstr "Başlangıçta Otomatik Yükleme" +msgstr "Başlangıçta Otomatik Sürüm Kontrolü" #: core/project_settings.cpp #, fuzzy msgid "Version Control Plugin Name" -msgstr "Sürüm Kontrol" +msgstr "Sürüm Denetimi Eklenti Adı" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp @@ -921,7 +913,6 @@ msgid "Modules" msgstr "Modüller" #: core/register_core_types.cpp -#, fuzzy msgid "TCP" msgstr "TCP" @@ -930,8 +921,9 @@ msgid "Connect Timeout Seconds" msgstr "Bağlanma Zaman Aşımı Süresi(Saniye)" #: core/register_core_types.cpp +#, fuzzy msgid "Packet Peer Stream" -msgstr "" +msgstr "Paket Eş Akışı" #: core/register_core_types.cpp msgid "Max Buffer (Power of 2)" @@ -977,7 +969,7 @@ msgstr "Deneme" #: core/translation.cpp scene/resources/font.cpp msgid "Fallback" -msgstr "" +msgstr "Geri Dönüş" #: core/ustring.cpp scene/resources/segment_shape_2d.cpp msgid "B" @@ -1018,12 +1010,12 @@ msgstr "Arabellek" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Canvas Polygon Buffer Size (KB)" -msgstr "" +msgstr "Tuval Çokgen Arabellek Boyutu (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Canvas Polygon Index Buffer Size (KB)" -msgstr "" +msgstr "Tuval Çokgen Dizini Arabellek Boyutu (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp editor/editor_settings.cpp @@ -1039,36 +1031,33 @@ msgstr "2D" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Snapping" msgstr "Akıllı Hizalama" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Use GPU Pixel Snap" msgstr "Piksel Yapışması Kullan" #: drivers/gles2/rasterizer_scene_gles2.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Immediate Buffer Size (KB)" -msgstr "" +msgstr "Anlık Arabellek Boyutu (KB)" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp -#, fuzzy msgid "Lightmapping" -msgstr "Işık-Haritalarını Pişir" +msgstr "Işık Haritalama" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp +#, fuzzy msgid "Use Bicubic Sampling" -msgstr "" +msgstr "Bicubic Örneklemeyi Kullanın" #: drivers/gles3/rasterizer_scene_gles3.cpp -#, fuzzy msgid "Max Renderable Elements" -msgstr "Maks. Renderlanabilinecek Ögeler" +msgstr "Maksimum İşlenebilir Öğeler" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Lights" @@ -1105,11 +1094,12 @@ msgstr "Yüzeyi Takip Et" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Weight Samples" -msgstr "" +msgstr "Ağırlık Örnekleri" #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Voxel Cone Tracing" -msgstr "" +msgstr "Işın İzleme" #: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp msgid "High Quality" @@ -1117,7 +1107,7 @@ msgstr "Yüksek Kalite" #: drivers/gles3/rasterizer_storage_gles3.cpp msgid "Blend Shape Max Buffer Size (KB)" -msgstr "" +msgstr "Karışım Şekli Maksimum Arabellek Boyutu (KB)" #. TRANSLATORS: Adjective, refers to the mode for Bezier handles (Free, Balanced, Mirror). #: editor/animation_bezier_editor.cpp @@ -1191,9 +1181,8 @@ msgstr "Animasyon Değişikliği Çağrısı" #: editor/animation_track_editor.cpp scene/2d/animated_sprite.cpp #: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Frame" -msgstr "Kare %" +msgstr "Kare" #: editor/animation_track_editor.cpp editor/editor_profiler.cpp #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp @@ -1248,8 +1237,9 @@ msgstr "Tutamacı Ayarla" #: editor/import/resource_importer_texture.cpp #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp +#, fuzzy msgid "Stream" -msgstr "" +msgstr "Aktarım" #: editor/animation_track_editor.cpp #, fuzzy @@ -1410,7 +1400,7 @@ msgstr "Tür:" #: editor/animation_track_editor.cpp #, fuzzy msgid "(Invalid, expected type: %s)" -msgstr "Geçersiz Dışa Aktarım Şablonu:" +msgstr "(Geçersiz Dışa Aktarım Şablonu: %s)" #: editor/animation_track_editor.cpp msgid "Easing:" @@ -1429,22 +1419,22 @@ msgstr "Tutamacı Ayarla" #: editor/animation_track_editor.cpp #, fuzzy msgid "Stream:" -msgstr "Radyo Ögesi" +msgstr "Aktarım:" #: editor/animation_track_editor.cpp #, fuzzy msgid "Start (s):" -msgstr "Yeniden Başlat (sn):" +msgstr "Başlangıç (lar):" #: editor/animation_track_editor.cpp #, fuzzy msgid "End (s):" -msgstr "Açılma (sn):" +msgstr "Bitiş (ler):" #: editor/animation_track_editor.cpp #, fuzzy msgid "Animation Clip:" -msgstr "Animasyonlar:" +msgstr "Animasyon Klibi:" #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" @@ -1535,7 +1525,7 @@ msgstr "Düzenleyici" #: editor/animation_track_editor.cpp editor/editor_settings.cpp #, fuzzy msgid "Confirm Insert Track" -msgstr "Animasyon İz & Anahtar Ekle" +msgstr "Parça Eklemeyi Onayla" #. TRANSLATORS: %s will be replaced by a phrase describing the target of track. #: editor/animation_track_editor.cpp @@ -1662,7 +1652,7 @@ msgstr "Yöntem İz Anahtarı Ekle" #: editor/animation_track_editor.cpp #, fuzzy msgid "Method not found in object:" -msgstr "Metot, nesne içinde bulunamadı: " +msgstr "Metot, nesne içinde bulunamadı:" #: editor/animation_track_editor.cpp msgid "Anim Move Keys" @@ -2195,14 +2185,15 @@ msgstr "Beğeniler:" msgid "Recent:" msgstr "Yakın zamanda:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Ara:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Eşleşmeler:" @@ -2262,8 +2253,8 @@ msgstr "Yerine Geçecek Kaynak Ara:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2271,8 +2262,9 @@ msgid "Open" msgstr "Aç" #: editor/dependency_editor.cpp +#, fuzzy msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "Sahipleri: %s (Toplam: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2631,7 +2623,7 @@ msgstr "'%s' dosyası bulunamadı." #: editor/editor_audio_buses.cpp #, fuzzy msgid "Layout:" -msgstr "Yerleşim Düzeni" +msgstr "Yerleşim Düzeni:" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -2682,7 +2674,7 @@ msgstr "Yeni bir Bus Yerleşim Düzeni oluştur." #: editor/editor_audio_buses.cpp #, fuzzy msgid "Audio Bus Layout" -msgstr "Audio Bus Yerleşim Düzenini Aç" +msgstr "Ses Veri Yolu Düzeni" #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -2834,23 +2826,24 @@ msgid "Choose" msgstr "Seç" #: editor/editor_export.cpp +#, fuzzy msgid "Project export for platform:" -msgstr "" +msgstr "Platform için proje dışa aktarımı:" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." -msgstr "Düğüm Yolunu Kopyala" +msgid "Completed with warnings." +msgstr "Hatalarla tamamlandı." #: editor/editor_export.cpp #, fuzzy msgid "Completed successfully." -msgstr "Paket Başarı ile Kuruldu!" +msgstr "Başarıyla tamamlandı." #: editor/editor_export.cpp #, fuzzy msgid "Failed." -msgstr "Başarısız:" +msgstr "Başarısız." #: editor/editor_export.cpp msgid "Storing File:" @@ -2867,27 +2860,27 @@ msgstr "Çıkınla" #: editor/editor_export.cpp #, fuzzy msgid "Save PCK" -msgstr "Farklı Kaydet" +msgstr "PCK'yi kaydet" #: editor/editor_export.cpp #, fuzzy msgid "Cannot create file \"%s\"." -msgstr "Klasör oluşturulamadı." +msgstr "\"%s\" dosyası oluşturulamıyor." #: editor/editor_export.cpp #, fuzzy msgid "Failed to export project files." -msgstr "Proje dosyaları dışa aktarılamadı" +msgstr "Proje dosyaları dışa aktarılamadı." #: editor/editor_export.cpp #, fuzzy msgid "Can't open file to read from path \"%s\"." -msgstr "Dosya yazmak için açılamıyor:" +msgstr "\"%s\" yolundan okunacak dosya açılamıyor." #: editor/editor_export.cpp #, fuzzy msgid "Save ZIP" -msgstr "Farklı Kaydet" +msgstr "ZIP dosyasını kaydet" #: editor/editor_export.cpp msgid "" @@ -2950,7 +2943,7 @@ msgstr "" #: platform/osx/export/export.cpp platform/uwp/export/export.cpp #, fuzzy msgid "Custom Template" -msgstr "Editör Teması" +msgstr "Özel Şablon" #: editor/editor_export.cpp editor/project_export.cpp #: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp @@ -2962,36 +2955,42 @@ msgstr "Yayınlamak" #: editor/editor_export.cpp #, fuzzy msgid "Binary Format" -msgstr "Renk operatörü." +msgstr "Çift Biçim" #: editor/editor_export.cpp +#, fuzzy msgid "64 Bits" -msgstr "" +msgstr "64 Bit" #: editor/editor_export.cpp +#, fuzzy msgid "Embed PCK" -msgstr "" +msgstr "PCK'yı yerleştirin" #: editor/editor_export.cpp platform/osx/export/export.cpp #, fuzzy msgid "Texture Format" -msgstr "DokuBölgesi" +msgstr "Doku Biçimi" #: editor/editor_export.cpp +#, fuzzy msgid "BPTC" -msgstr "" +msgstr "BPTC" #: editor/editor_export.cpp platform/osx/export/export.cpp +#, fuzzy msgid "S3TC" -msgstr "" +msgstr "S3TC" #: editor/editor_export.cpp platform/osx/export/export.cpp +#, fuzzy msgid "ETC" -msgstr "" +msgstr "ETC" #: editor/editor_export.cpp platform/osx/export/export.cpp +#, fuzzy msgid "ETC2" -msgstr "" +msgstr "ETC2" #: editor/editor_export.cpp #, fuzzy @@ -3013,7 +3012,7 @@ msgstr "Özel yayınlama şablonu bulunamadı." #: editor/editor_export.cpp #, fuzzy msgid "Prepare Template" -msgstr "Şablonlarını Yönet" +msgstr "Şablon Hazırla" #: editor/editor_export.cpp platform/osx/export/export.cpp #, fuzzy @@ -3023,12 +3022,12 @@ msgstr "Belirtilen Dışa aktarım yolu mevcut değil:" #: editor/editor_export.cpp platform/javascript/export/export.cpp #, fuzzy msgid "Template file not found: \"%s\"." -msgstr "Şablon dosyası bulunamadı:" +msgstr "Şablon dosyası bulunamadı: \"%s\"." #: editor/editor_export.cpp #, fuzzy msgid "Failed to copy export template." -msgstr "Geçersiz Dışa Aktarım Şablonu:" +msgstr "Dışa aktarma şablonu kopyalanamadı." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp @@ -3041,8 +3040,9 @@ msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." msgstr "32-bit dışa aktarımlarda gömülü PCK 4GiB'tan büyük olamaz." #: editor/editor_export.cpp +#, fuzzy msgid "Convert Text Resources To Binary On Export" -msgstr "" +msgstr "Dışa Aktarmada Metin Kaynaklarını İkili Dosyaya Dönüştür" #: editor/editor_feature_profile.cpp msgid "3D Editor" @@ -3253,7 +3253,7 @@ msgstr "Dışa Aktarım Şablonlarını Yönet" #: editor/editor_feature_profile.cpp #, fuzzy msgid "Default Feature Profile" -msgstr "Godot Özellik Profili" +msgstr "Varsayılan Özellik Profili" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -3327,12 +3327,12 @@ msgstr "Bir Dosya Kaydet" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp #, fuzzy msgid "Access" -msgstr "Başarılı!" +msgstr "Erişim" #: editor/editor_file_dialog.cpp editor/editor_settings.cpp #, fuzzy msgid "Display Mode" -msgstr "Oynatma Modu:" +msgstr "Ekran Modu" #: editor/editor_file_dialog.cpp #: editor/import/resource_importer_layered_texture.cpp @@ -3347,32 +3347,33 @@ msgstr "Oynatma Modu:" #: servers/audio/effects/audio_effect_distortion.cpp #, fuzzy msgid "Mode" -msgstr "Kaydırma Biçimi" +msgstr "Mod" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp #, fuzzy msgid "Current Dir" -msgstr "Geçerli:" +msgstr "Geçerli Dizin" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp #, fuzzy msgid "Current File" -msgstr "Şu Anki Profil:" +msgstr "Geçerli Dosya" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp #, fuzzy msgid "Current Path" -msgstr "Geçerli:" +msgstr "Geçerli Yol" #: editor/editor_file_dialog.cpp editor/editor_settings.cpp #: scene/gui/file_dialog.cpp #, fuzzy msgid "Show Hidden Files" -msgstr "Gizli Dosyalari Aç / Kapat" +msgstr "Gizli Dosyaları Göster" #: editor/editor_file_dialog.cpp +#, fuzzy msgid "Disable Overwrite Warning" -msgstr "" +msgstr "Üzerine Yazma Uyarısını Devre Dışı Bırak" #: editor/editor_file_dialog.cpp msgid "Go Back" @@ -3474,8 +3475,9 @@ msgid "(Re)Importing Assets" msgstr "Varlıklar Yeniden-İçe Aktarılıyor" #: editor/editor_file_system.cpp +#, fuzzy msgid "Reimport Missing Imported Files" -msgstr "" +msgstr "İçe Aktarılan Eksik Dosyaları Yeniden İçe Aktar" #: editor/editor_help.cpp scene/2d/camera_2d.cpp scene/gui/control.cpp #: scene/gui/nine_patch_rect.cpp scene/resources/dynamic_font.cpp @@ -3507,7 +3509,7 @@ msgstr "Özellikler" #: editor/editor_help.cpp #, fuzzy msgid "overrides %s:" -msgstr "% üzerine yazılmışlar:" +msgstr "%s'yi geçersiz kılar:" #: editor/editor_help.cpp msgid "default:" @@ -3579,7 +3581,7 @@ msgstr "" #: modules/gdscript/gdscript_editor.cpp #, fuzzy msgid "Text Editor" -msgstr "Düzenleyiciyi Aç" +msgstr "Metin Düzenleyici" #: editor/editor_help.cpp editor/editor_node.cpp editor/editor_settings.cpp #: editor/plugins/shader_editor_plugin.cpp @@ -3587,8 +3589,9 @@ msgid "Help" msgstr "Yardım" #: editor/editor_help.cpp +#, fuzzy msgid "Sort Functions Alphabetically" -msgstr "" +msgstr "Fonksiyonları Alfabetik Olarak Sırala" #: editor/editor_help_search.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp @@ -3670,34 +3673,34 @@ msgstr "Özellik:" #: editor/editor_inspector.cpp editor/editor_spin_slider.cpp #, fuzzy msgid "Label" -msgstr "Değer" +msgstr "Etiket" #: editor/editor_inspector.cpp editor/editor_spin_slider.cpp #: scene/resources/default_theme/default_theme.cpp #, fuzzy msgid "Read Only" -msgstr "Sadece Metotlar" +msgstr "Sadece Okunur" #: editor/editor_inspector.cpp editor/plugins/item_list_editor_plugin.cpp #, fuzzy msgid "Checkable" -msgstr "Öğeyi Denetle" +msgstr "Kontrol edilebilir" #: editor/editor_inspector.cpp editor/plugins/item_list_editor_plugin.cpp #: scene/resources/default_theme/default_theme.cpp #, fuzzy msgid "Checked" -msgstr "Denetlenen Öğe" +msgstr "Kontrol edildi" #: editor/editor_inspector.cpp #, fuzzy msgid "Draw Red" -msgstr "Çizim Çağrıları:" +msgstr "Kırmızı Çiz" #: editor/editor_inspector.cpp #, fuzzy msgid "Keying" -msgstr "Oynat" +msgstr "Anahtarlama" #: editor/editor_inspector.cpp msgid "Pin value" @@ -4062,12 +4065,12 @@ msgstr "Betiği Hızlı Aç..." #: editor/editor_node.cpp #, fuzzy msgid "Save & Reload" -msgstr "Kaydet ve Baştan Başlat" +msgstr "Kaydet ve Yeniden Yükle" #: editor/editor_node.cpp #, fuzzy msgid "Save changes to '%s' before reloading?" -msgstr "Kapatmadan önce değişklikler buraya '%s' kaydedilsin mi?" +msgstr "Çıkmadan önce değişiklikler '%s' ‘ye kaydedilsin mi?" #: editor/editor_node.cpp msgid "Save & Close" @@ -4188,7 +4191,7 @@ msgstr "Proje Yöneticisi Açılsın Mı?" #: editor/editor_node.cpp #, fuzzy msgid "Save changes to the following scene(s) before reloading?" -msgstr "Çıkmadan önce değişiklikler aşağıdaki sahne(ler)e kaydedilsin mi?" +msgstr "Çıkmadan önce değişiklikler sahne(ler)e kaydedilsin mi?" #: editor/editor_node.cpp msgid "Save & Quit" @@ -4372,54 +4375,53 @@ msgid "%d more files" msgstr "%d daha fazla dosyalar" #: editor/editor_node.cpp +#, fuzzy msgid "" "Unable to write to file '%s', file in use, locked or lacking permissions." msgstr "" +"'%s' dosyasına yazılamıyor, dosya kullanımda, kilitli veya izinler eksik." #: editor/editor_node.cpp editor/editor_settings.cpp editor/scene_tree_dock.cpp #: servers/arvr/arvr_interface.cpp -#, fuzzy msgid "Interface" -msgstr "Kullanıcı Arayüzü" +msgstr "Arayüz" #: editor/editor_node.cpp editor/editor_settings.cpp -#, fuzzy msgid "Scene Tabs" -msgstr "Sahne Sekmesine Geç" +msgstr "Sahne Sekmeleri" #: editor/editor_node.cpp -#, fuzzy msgid "Always Show Close Button" -msgstr "Daima Izgarayı Göster" +msgstr "Daima Kapatma Düğmesini Göster" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Resize If Many Tabs" -msgstr "" +msgstr "Çok Sayıda Sekme Varsa Yeniden Boyutlandır" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Minimum Width" -msgstr "" +msgstr "Minimum Genişlik" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Output" msgstr "Çıktı" #: editor/editor_node.cpp editor/editor_settings.cpp -#, fuzzy msgid "Always Clear Output On Play" -msgstr "Çıktıyı Temizle" +msgstr "Oynatıldığında Çıktıyı Daima Temizle" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Always Open Output On Play" -msgstr "" +msgstr "Oynatıldığında Çıktıyı Daima Aç" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Always Close Output On Stop" -msgstr "" +msgstr "Durdurulduğunda Çıktıyı Daima Kapat" #: editor/editor_node.cpp +#, fuzzy msgid "Save On Focus Loss" -msgstr "" +msgstr "Odak Kaybından Tasarruf Edin" #: editor/editor_node.cpp editor/editor_settings.cpp #, fuzzy @@ -4456,8 +4458,9 @@ msgid "Restore Scenes On Load" msgstr "Sahne Düğümünü Al" #: editor/editor_node.cpp editor/editor_settings.cpp +#, fuzzy msgid "Show Thumbnail On Hover" -msgstr "" +msgstr "Fareyle üzerine gelindiğinde küçük resmi göster" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Inspector" @@ -4483,11 +4486,11 @@ msgstr "" #: editor/editor_node.cpp msgid "Horizontal Vector2 Editing" -msgstr "" +msgstr "Yatay Vector2 Düzenleme" #: editor/editor_node.cpp msgid "Horizontal Vector Types Editing" -msgstr "" +msgstr "Yatay Vector tipleri düzenleme" #: editor/editor_node.cpp #, fuzzy @@ -4500,8 +4503,9 @@ msgid "Resources To Open In New Inspector" msgstr "Gözetmen Bölümünde Aç" #: editor/editor_node.cpp +#, fuzzy msgid "Default Color Picker Mode" -msgstr "" +msgstr "Varsayılan renk seçme modu" #: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Version Control" @@ -5235,9 +5239,8 @@ msgid "Size:" msgstr "Boyut:" #: editor/editor_properties_array_dict.cpp -#, fuzzy msgid "Page:" -msgstr "Sayfa: " +msgstr "Sayfa:" #: editor/editor_properties_array_dict.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -5378,19 +5381,19 @@ msgstr "Hepsini Görüntüle" #: editor/editor_settings.cpp msgid "Custom Display Scale" -msgstr "" +msgstr "Özel Ekran Ölçeği" #: editor/editor_settings.cpp msgid "Main Font Size" -msgstr "" +msgstr "Ana font ölçüsü" #: editor/editor_settings.cpp msgid "Code Font Size" -msgstr "" +msgstr "Kod font'u ölçüsü" #: editor/editor_settings.cpp msgid "Font Antialiased" -msgstr "" +msgstr "Kenarı yumuşatılmış font" #: editor/editor_settings.cpp msgid "Font Hinting" @@ -5403,7 +5406,7 @@ msgstr "Ana Sahne" #: editor/editor_settings.cpp msgid "Main Font Bold" -msgstr "" +msgstr "Ana font kalınlığı" #: editor/editor_settings.cpp #, fuzzy @@ -5411,8 +5414,9 @@ msgid "Code Font" msgstr "Düğüm Noktası Ekle" #: editor/editor_settings.cpp +#, fuzzy msgid "Dim Editor On Dialog Popup" -msgstr "" +msgstr "İletişim penceresinde Dim Editörü" #: editor/editor_settings.cpp main/main.cpp msgid "Low Processor Mode Sleep (µsec)" @@ -5429,11 +5433,12 @@ msgstr "Dikkat Dağıtmayan Kip" #: editor/editor_settings.cpp msgid "Automatically Open Screenshots" -msgstr "" +msgstr "Otomatik olarak ekran görüntülerini aç" #: editor/editor_settings.cpp +#, fuzzy msgid "Max Array Dictionary Items Per Page" -msgstr "" +msgstr "Her sayfada maks dizi sözlüğü öğesi" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp scene/gui/control.cpp @@ -5447,7 +5452,7 @@ msgstr "Ön ayar" #: editor/editor_settings.cpp msgid "Icon And Font Color" -msgstr "" +msgstr "Simge ve Font rengi" #: editor/editor_settings.cpp #, fuzzy @@ -5461,7 +5466,7 @@ msgstr "Renk Seç" #: editor/editor_settings.cpp scene/resources/environment.cpp msgid "Contrast" -msgstr "" +msgstr "Kontrast" #: editor/editor_settings.cpp msgid "Relationship Line Opacity" @@ -5537,7 +5542,7 @@ msgstr "Küçük Resim..." #: editor/editor_settings.cpp msgid "Docks" -msgstr "" +msgstr "Eklentiler" #: editor/editor_settings.cpp #, fuzzy @@ -5559,8 +5564,9 @@ msgid "Property Editor" msgstr "Grup Düzenleyici" #: editor/editor_settings.cpp +#, fuzzy msgid "Auto Refresh Interval" -msgstr "" +msgstr "Otomatik yenileme intervalı" #: editor/editor_settings.cpp #, fuzzy @@ -5575,7 +5581,7 @@ msgstr "Editör Teması" #: editor/editor_settings.cpp scene/3d/label_3d.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Line Spacing" -msgstr "" +msgstr "Satır aralığı" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp #: modules/gdscript/editor/gdscript_highlighter.cpp @@ -5594,7 +5600,7 @@ msgstr "" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Highlight Current Line" -msgstr "" +msgstr "Geçerli satırı vurgula" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp msgid "Highlight Type Safe Lines" @@ -5633,11 +5639,11 @@ msgstr "Gezinim" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Smooth Scrolling" -msgstr "" +msgstr "Pürüzsüz kaydırma" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "V Scroll Speed" -msgstr "" +msgstr "V kaydırma hızı" #: editor/editor_settings.cpp #, fuzzy @@ -5646,7 +5652,7 @@ msgstr "Başlatımı Göster" #: editor/editor_settings.cpp msgid "Minimap Width" -msgstr "" +msgstr "Küçük Harita Genişliği" #: editor/editor_settings.cpp msgid "Mouse Extra Buttons Navigate History" @@ -5658,8 +5664,13 @@ msgid "Drag And Drop Selection" msgstr "GridMap Seçimi" #: editor/editor_settings.cpp +#, fuzzy +msgid "Stay In Script Editor On Node Selected" +msgstr "Seçilmiş Düğümde Script Editöründe Kal" + +#: editor/editor_settings.cpp msgid "Appearance" -msgstr "" +msgstr "Dış görünüş" #: editor/editor_settings.cpp scene/gui/text_edit.cpp #, fuzzy @@ -5685,12 +5696,14 @@ msgid "Show Info Gutter" msgstr "" #: editor/editor_settings.cpp +#, fuzzy msgid "Code Folding" -msgstr "" +msgstr "Kod katlama" #: editor/editor_settings.cpp +#, fuzzy msgid "Word Wrap" -msgstr "" +msgstr "Kelime Paketle" #: editor/editor_settings.cpp msgid "Show Line Length Guidelines" @@ -5711,7 +5724,7 @@ msgstr "Kod Düzenleyici" #: editor/editor_settings.cpp msgid "Show Members Overview" -msgstr "" +msgstr "Üyelerin Genel Bakışını Göster" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -5728,16 +5741,19 @@ msgid "Autosave Interval Secs" msgstr "" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Restore Scripts On Load" -msgstr "" +msgstr "Script'leri Yüklemede Eski Haline Getir" #: editor/editor_settings.cpp +#, fuzzy msgid "Auto Reload And Parse Scripts On Save" -msgstr "" +msgstr "Kaydederken Script'leri Otomatik Tekrar yükle ve Ayrıştır" #: editor/editor_settings.cpp +#, fuzzy msgid "Auto Reload Scripts On External Change" -msgstr "" +msgstr "Dış Değişiklikte Otomatik Olarak Script'i Geri Yükle" #: editor/editor_settings.cpp #, fuzzy @@ -5750,11 +5766,11 @@ msgstr "" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Cursor" -msgstr "" +msgstr "İmleç" #: editor/editor_settings.cpp msgid "Scroll Past End Of File" -msgstr "" +msgstr "Dosyanın Sonunu Kaydır" #: editor/editor_settings.cpp msgid "Block Caret" @@ -5790,7 +5806,7 @@ msgstr "" #: editor/editor_settings.cpp msgid "Code Complete Delay" -msgstr "" +msgstr "Kod Tamamlama Gecikme Süresi" #: editor/editor_settings.cpp msgid "Put Callhint Tooltip Below Current Line" @@ -5847,12 +5863,14 @@ msgid "Preview Size" msgstr "Önizleme" #: editor/editor_settings.cpp +#, fuzzy msgid "Primary Grid Color" -msgstr "" +msgstr "Birincil Izgara Rengi" #: editor/editor_settings.cpp +#, fuzzy msgid "Secondary Grid Color" -msgstr "" +msgstr "İkincil Izgara Rengi" #: editor/editor_settings.cpp #, fuzzy @@ -5889,7 +5907,7 @@ msgstr "Nokta" #: scene/resources/particles_material.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp msgid "Shape" -msgstr "" +msgstr "Şekil" #: editor/editor_settings.cpp #, fuzzy @@ -6001,7 +6019,7 @@ msgstr "Gezinim Kipi" #: editor/editor_settings.cpp msgid "Orbit Sensitivity" -msgstr "" +msgstr "Yörünge Hassasiyeti" #: editor/editor_settings.cpp msgid "Orbit Inertia" @@ -6204,7 +6222,7 @@ msgstr "Önden Görünüm" #: modules/gdscript/language_server/gdscript_language_server.cpp #, fuzzy msgid "Remote Host" -msgstr "Uzak " +msgstr "Uzak Ana Bilgisayar" #: editor/editor_settings.cpp #: modules/gdscript/language_server/gdscript_language_server.cpp @@ -7199,7 +7217,7 @@ msgstr "İfade" #: editor/import/resource_importer_obj.cpp #, fuzzy msgid "Optimize Mesh Flags" -msgstr "Boyut: " +msgstr "Boyut:" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" @@ -7403,7 +7421,7 @@ msgstr "Işık-haritaları Üretiliyor" #: editor/import/resource_importer_scene.cpp #, fuzzy msgid "Generating for Mesh:" -msgstr "Örüntü için Üretiliyor: " +msgstr "Örüntü için Üretiliyor:" #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." @@ -7503,7 +7521,7 @@ msgstr "Rastgele Ölçek:" #: editor/import/resource_importer_texture.cpp #, fuzzy msgid "Size Limit" -msgstr "Boyut: " +msgstr "Boyut Limiti" #: editor/import/resource_importer_texture.cpp msgid "Detect 3D" @@ -8426,7 +8444,7 @@ msgstr "" #: editor/plugins/animation_state_machine_editor.cpp #, fuzzy msgid "Transition:" -msgstr "Geçiş: " +msgstr "Geçiş:" #: editor/plugins/animation_state_machine_editor.cpp msgid "Play Mode:" @@ -10195,7 +10213,7 @@ msgstr "Oylum" #: editor/plugins/particles_editor_plugin.cpp #, fuzzy msgid "Emission Source:" -msgstr "Emisyon Kaynağı: " +msgstr "Emisyon Kaynağı:" #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." @@ -11293,15 +11311,13 @@ msgstr "Çevir" #. TRANSLATORS: Refers to changing the scale of a node in the 3D editor. #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Scaling:" -msgstr "Ölçekleniyor: " +msgstr "Ölçekleniyor:" #. TRANSLATORS: Refers to changing the position of a node in the 3D editor. #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Translating:" -msgstr "Çeviriliyor: " +msgstr "Çevriliyor:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotating %s degrees." @@ -11843,19 +11859,17 @@ msgid "Sprite" msgstr "HayaliÇizimlik" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Simplification:" -msgstr "Sadeleştirme: " +msgstr "Sadeleştirme:" #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy msgid "Shrink (Pixels):" -msgstr "Sıkıştır (Pikselleri): " +msgstr "Sıkıştır (Pikselleri):" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Grow (Pixels):" -msgstr "Büyüt (Pikselleri): " +msgstr "Büyüt (Piksel):" #: editor/plugins/sprite_editor_plugin.cpp msgid "Update Preview" @@ -11918,6 +11932,11 @@ msgid "New Animation" msgstr "Yeni Animasyon" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Metotları filtrele" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Hız:" @@ -13308,7 +13327,6 @@ msgid "Select SSH private key path" msgstr "SSH özel anahtar yolu seç" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "SSH Passphrase" msgstr "SSH Parolası" @@ -16017,7 +16035,7 @@ msgstr "Düğüm Betiği İliştir" #: editor/script_editor_debugger.cpp #, fuzzy msgid "Remote %s:" -msgstr "Uzak " +msgstr "Uzak %s:" #: editor/script_editor_debugger.cpp msgid "Bytes:" @@ -17077,9 +17095,8 @@ msgid "Disabled GDNative Singleton" msgstr "GDNative İskeleti Pasifleştirildi" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Libraries:" -msgstr "Kütüphaneler: " +msgstr "Kütüphaneler:" #: modules/gdnative/nativescript/nativescript.cpp #, fuzzy @@ -17983,7 +18000,7 @@ msgstr "" #: modules/visual_script/visual_script.cpp #, fuzzy msgid "Node returned an invalid sequence output:" -msgstr "Düğüm geçersiz bir dizi çıktısı döndürdü: " +msgstr "Düğüm geçersiz bir dizi çıktısı döndürdü:" #: modules/visual_script/visual_script.cpp msgid "Found sequence bit but not the node in the stack, report bug!" @@ -18345,8 +18362,9 @@ msgid "if (cond) is:" msgstr "" #: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy msgid "While" -msgstr "While" +msgstr "Sürece" #: modules/visual_script/visual_script_flow_control.cpp msgid "while (cond):" @@ -20654,15 +20672,15 @@ msgstr "Anahtar deposu bulunamadı, dışa aktarılamadı." #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Geçersiz uzantı." #: platform/windows/export/export.cpp #, fuzzy @@ -20686,15 +20704,15 @@ msgstr "Geçersiz ad." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Geçersiz uzantı." #: platform/windows/export/export.cpp #, fuzzy @@ -22071,7 +22089,7 @@ msgstr "Kenar Boşluk Belirle" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #, fuzzy msgid "Sync To Physics" -msgstr " (Fiziksel)" +msgstr "Fiziğe Senkronize Et" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #, fuzzy @@ -23575,7 +23593,7 @@ msgstr "Bir RoomGroup, bir Portal'ın çocuğu veya torunu olmamalıdır." #: scene/3d/portal.cpp #, fuzzy msgid "Portal Active" -msgstr " [portallar aktif]" +msgstr "Portal Aktif" #: scene/3d/portal.cpp scene/resources/occluder_shape_polygon.cpp msgid "Two Way" @@ -24866,7 +24884,7 @@ msgstr "" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Caret" -msgstr "" +msgstr "Karet" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Blink" @@ -25788,14 +25806,12 @@ msgid "3D Render" msgstr "Oluşturucu:" #: scene/register_scene_types.cpp -#, fuzzy msgid "2D Physics" -msgstr " (Fiziksel)" +msgstr "2B Fizik" #: scene/register_scene_types.cpp -#, fuzzy msgid "3D Physics" -msgstr " (Fiziksel)" +msgstr "3B Fizik" #: scene/register_scene_types.cpp #, fuzzy diff --git a/editor/translations/uk.po b/editor/translations/uk.po index fd20ea0a29..d87aa168d7 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -29,7 +29,7 @@ msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-03 00:44+0000\n" +"PO-Revision-Date: 2022-07-26 01:55+0000\n" "Last-Translator: Artem <artem@molotov.work>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" @@ -39,7 +39,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -2116,14 +2116,15 @@ msgstr "Вибране:" msgid "Recent:" msgstr "Нещодавні:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Пошук:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Збіги:" @@ -2183,8 +2184,8 @@ msgstr "Знайти замінний ресурс:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2756,7 +2757,8 @@ msgid "Project export for platform:" msgstr "Експортування проєкту для платформи:" #: editor/editor_export.cpp -msgid "Completed with errors." +#, fuzzy +msgid "Completed with warnings." msgstr "Завершено з помилками." #: editor/editor_export.cpp @@ -5500,6 +5502,10 @@ msgid "Drag And Drop Selection" msgstr "Вибір GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Вигляд" @@ -11612,6 +11618,11 @@ msgid "New Animation" msgstr "Нова анімація" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Фільтрувати методи" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Швидкість:" @@ -20113,18 +20124,18 @@ msgstr "Не вдалося знайти сховище ключів. Немож #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" "Щоб мати змогу змінювати піктограму або дані щодо програми, має бути " "налаштовано інструмент rcedit у параметрах редактора (Експорт > Windows > " "Rcedit)." #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Некоректний виконуваний файл." #: platform/windows/export/export.cpp #, fuzzy @@ -20149,18 +20160,18 @@ msgstr "Некоректна назва." #: platform/windows/export/export.cpp #, fuzzy msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" "Щоб мати змогу змінювати піктограму або дані щодо програми, має бути " "налаштовано інструмент rcedit у параметрах редактора (Експорт > Windows > " "Rcedit)." #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Некоректний виконуваний файл." #: platform/windows/export/export.cpp #, fuzzy @@ -25888,11 +25899,11 @@ msgstr "Розмір крапки" #: scene/resources/material.cpp msgid "Billboard Mode" -msgstr "Режим афіші" +msgstr "Режим розголосника" #: scene/resources/material.cpp msgid "Billboard Keep Scale" -msgstr "Зберегти масштаб афіші" +msgstr "Зберегти масштаб розголосника" #: scene/resources/material.cpp msgid "Grow" diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index 46cd56a57b..a428250cc7 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -2132,14 +2132,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2195,8 +2196,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2763,8 +2764,9 @@ msgid "Project export for platform:" msgstr "" #: editor/editor_export.cpp -msgid "Completed with errors." -msgstr "" +#, fuzzy +msgid "Completed with warnings." +msgstr ".تمام کا انتخاب" #: editor/editor_export.cpp msgid "Completed successfully." @@ -5421,6 +5423,10 @@ msgid "Drag And Drop Selection" msgstr ".تمام کا انتخاب" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11599,6 +11605,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "سب سکریپشن بنائیں" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20052,14 +20063,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +msgid "rcedit failed to modify executable: %s." msgstr "" #: platform/windows/export/export.cpp @@ -20081,14 +20091,13 @@ msgstr "" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +msgid "Signtool failed to sign executable: %s." msgstr "" #: platform/windows/export/export.cpp diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 32fe3c1087..0a6885872f 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -2149,14 +2149,15 @@ msgstr "Ưa thích:" msgid "Recent:" msgstr "Gần đây:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Tìm kiếm:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Phù hợp:" @@ -2216,8 +2217,8 @@ msgstr "Tìm kiếm tài nguyên thay thế:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2796,7 +2797,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "Sao chép đường dẫn nút" #: editor/editor_export.cpp @@ -5506,6 +5507,10 @@ msgid "Drag And Drop Selection" msgstr "Chọn tất cả" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Ngoại hình" @@ -11788,6 +11793,11 @@ msgid "New Animation" msgstr "Hoạt hình mới" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Lọc phương thức" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Tốc độ:" @@ -20564,15 +20574,15 @@ msgstr "Không thể mở bản mẫu để xuất:" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "Tên đuôi không hợp lệ." #: platform/windows/export/export.cpp #, fuzzy @@ -20596,15 +20606,15 @@ msgstr "Tên không hợp lệ." #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "Tên đuôi không hợp lệ." #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index a2183dd550..f25a372128 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -89,7 +89,7 @@ msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2022-07-09 21:12+0000\n" +"PO-Revision-Date: 2022-07-29 01:36+0000\n" "Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" @@ -98,7 +98,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -521,9 +521,8 @@ msgid "Pressure" msgstr "压力" #: core/os/input_event.cpp -#, fuzzy msgid "Pen Inverted" -msgstr "翻转" +msgstr "笔触翻转" #: core/os/input_event.cpp msgid "Relative" @@ -2157,14 +2156,15 @@ msgstr "收藏:" msgid "Recent:" msgstr "最近使用:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "搜索:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "匹配项:" @@ -2224,8 +2224,8 @@ msgstr "查找替换资源:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2791,7 +2791,8 @@ msgid "Project export for platform:" msgstr "针对平台导出项目:" #: editor/editor_export.cpp -msgid "Completed with errors." +#, fuzzy +msgid "Completed with warnings." msgstr "已完成,存在错误。" #: editor/editor_export.cpp @@ -5444,6 +5445,10 @@ msgid "Drag And Drop Selection" msgstr "拖放选中内容" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "选中节点时保持脚本编辑器" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "外观" @@ -10700,7 +10705,7 @@ msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"此着色器已在磁盘上修改。\n" +"这个着色器已在磁盘上修改。\n" "应该采取什么行动?" #: editor/plugins/shader_editor_plugin.cpp scene/resources/material.cpp @@ -11466,6 +11471,10 @@ msgid "New Animation" msgstr "新建动画" #: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Filter animations" +msgstr "筛选动画" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "速度:" @@ -19672,17 +19681,18 @@ msgid "Could not find wine executable at \"%s\"." msgstr "无法在“%s”找到 wine 可执行文件。" #: platform/windows/export/export.cpp +#, fuzzy msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" "无法启动 rcedit 可执行文件,请在编辑器设置中配置 rcedit 路径(导出 > Windows " "> Rcedit)。" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" +#, fuzzy +msgid "rcedit failed to modify executable: %s." msgstr "" "rcedit 修改可执行文件失败:\n" "%s" @@ -19704,17 +19714,18 @@ msgid "Invalid timestamp server." msgstr "时间戳服务器无效。" #: platform/windows/export/export.cpp +#, fuzzy msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" "无法启动 signtool 可执行文件,请在编辑器设置中配置 signtool 路径(导出 > " "Windows > Signtool)。" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" +#, fuzzy +msgid "Signtool failed to sign executable: %s." msgstr "" "Signtool 签名可执行文件失败:\n" "%s" @@ -22562,9 +22573,8 @@ msgstr "" "建议修改子节点的碰撞体形状尺寸。" #: scene/3d/spatial.cpp -#, fuzzy msgid "Global Translation" -msgstr "全局变换" +msgstr "全局平移" #: scene/3d/spatial.cpp msgid "Matrix" diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index dcd0403c6a..79760d0de7 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -2228,14 +2228,15 @@ msgstr "最愛:" msgid "Recent:" msgstr "最近:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "搜尋:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "吻合:" @@ -2291,8 +2292,8 @@ msgstr "" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2890,7 +2891,7 @@ msgstr "" #: editor/editor_export.cpp #, fuzzy -msgid "Completed with errors." +msgid "Completed with warnings." msgstr "複製路徑" #: editor/editor_export.cpp @@ -5677,6 +5678,10 @@ msgid "Drag And Drop Selection" msgstr "刪除選中檔案" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12116,6 +12121,11 @@ msgid "New Animation" msgstr "新的動畫名稱:" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "篩選:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -20857,15 +20867,15 @@ msgstr "無法新增資料夾" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "無效副檔名" #: platform/windows/export/export.cpp #, fuzzy @@ -20889,15 +20899,15 @@ msgstr "無效名稱。" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "無效副檔名" #: platform/windows/export/export.cpp #, fuzzy diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index d56bc9ec23..8ad86d4b2a 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -23,7 +23,7 @@ # binotaliu <binota@protonmail.ch>, 2020. # Allen H. <w84miracle@gmail.com>, 2020. # BinotaLIU <binota@protonmail.ch>, 2020. -# BinotaLIU <me@binota.org>, 2020, 2021. +# BinotaLIU <me@binota.org>, 2020, 2021, 2022. # MintSoda <lionlxh@qq.com>, 2020. # meowmeowmeowcat <meowmeowcat1211@gmail.com>, 2021. # anthonychen <anton1554970211@126.com>, 2021. @@ -41,8 +41,8 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-18 08:11+0000\n" -"Last-Translator: 菘菘 <rrt467778@gmail.com>\n" +"PO-Revision-Date: 2022-07-31 18:34+0000\n" +"Last-Translator: BinotaLIU <me@binota.org>\n" "Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hant/>\n" "Language: zh_TW\n" @@ -474,7 +474,7 @@ msgstr "壓力" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "反轉筆觸" #: core/os/input_event.cpp msgid "Relative" @@ -1171,14 +1171,12 @@ msgid "Type" msgstr "型別" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "輸入把手" +msgstr "進入控點" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out Handle" -msgstr "輸出把手" +msgstr "離開控點" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp @@ -1350,14 +1348,12 @@ msgid "Easing:" msgstr "緩入緩出:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In-Handle:" -msgstr "設定處理程式" +msgstr "進入控點:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out-Handle:" -msgstr "設定處理程式" +msgstr "離開控點:" #: editor/animation_track_editor.cpp msgid "Stream:" @@ -2112,14 +2108,15 @@ msgstr "我的最愛:" msgid "Recent:" msgstr "最近存取:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "搜尋:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "符合條件:" @@ -2179,8 +2176,8 @@ msgstr "搜尋並取代資源:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp -#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2746,7 +2743,8 @@ msgid "Project export for platform:" msgstr "專案匯出平台:" #: editor/editor_export.cpp -msgid "Completed with errors." +#, fuzzy +msgid "Completed with warnings." msgstr "已完成,存在錯誤。" #: editor/editor_export.cpp @@ -5194,9 +5192,8 @@ msgid "Unfocused Low Processor Mode Sleep (µsec)" msgstr "未聚焦低處理器睡眠模式(微秒)" #: editor/editor_settings.cpp -#, fuzzy msgid "Separate Distraction Mode" -msgstr "專注模式" +msgstr "獨立專注模式" #: editor/editor_settings.cpp msgid "Automatically Open Screenshots" @@ -5402,6 +5399,10 @@ msgid "Drag And Drop Selection" msgstr "拖移選擇的檔案" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "選擇節點時保留在腳本編輯器中" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "外觀" @@ -5418,9 +5419,8 @@ msgid "Show Bookmark Gutter" msgstr "顯示書籤欄" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Breakpoint Gutter" -msgstr "跳過中斷點" +msgstr "顯示中斷點欄" #: editor/editor_settings.cpp msgid "Show Info Gutter" @@ -5459,9 +5459,8 @@ msgid "Files" msgstr "檔案" #: editor/editor_settings.cpp -#, fuzzy msgid "Trim Trailing Whitespace On Save" -msgstr "移除後方空白字元" +msgstr "保存時移除後方空白字元" #: editor/editor_settings.cpp msgid "Autosave Interval Secs" @@ -5508,9 +5507,8 @@ msgid "Caret Blink Speed" msgstr "插入符閃爍速度" #: editor/editor_settings.cpp -#, fuzzy msgid "Right Click Moves Caret" -msgstr "右鍵點擊以新增控制點" +msgstr "按一下右鍵來移動遊標" #: editor/editor_settings.cpp modules/gdscript/gdscript.cpp #: modules/gdscript/gdscript_editor.cpp @@ -5539,9 +5537,8 @@ msgid "Callhint Tooltip Offset" msgstr "呼叫提示工具提示框偏移量" #: editor/editor_settings.cpp -#, fuzzy msgid "Complete File Paths" -msgstr "複製節點路徑" +msgstr "補全檔案路徑" #: editor/editor_settings.cpp modules/gdscript/gdscript_editor.cpp msgid "Add Type Hints" @@ -5708,9 +5705,8 @@ msgid "Warped Mouse Panning" msgstr "彎曲滑鼠平移" #: editor/editor_settings.cpp -#, fuzzy msgid "Navigation Feel" -msgstr "導航模式" +msgstr "導航風格" #: editor/editor_settings.cpp msgid "Orbit Sensitivity" @@ -5967,21 +5963,20 @@ msgid "Completion Background Color" msgstr "自動補全背景顏色" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Completion Selected Color" -msgstr "匯入所選" +msgstr "自動補全所選顏色" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Existing Color" -msgstr "完成存在中顏色" +msgstr "自動補全現有顏色" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Scroll Color" -msgstr "完成滾動顏色" +msgstr "自動補全捲軸顏色" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Font Color" -msgstr "完成字型顏色" +msgstr "自動補全字型顏色" #: editor/editor_settings.cpp msgid "Text Color" @@ -6734,7 +6729,7 @@ msgstr "使用環境通道" #: editor/import/resource_importer_bitmask.cpp msgid "Create From" -msgstr "從某處建立" +msgstr "建立自" #: editor/import/resource_importer_bitmask.cpp #: servers/audio/effects/audio_effect_compressor.cpp @@ -6746,9 +6741,8 @@ msgstr "臨界值" #: editor/import/resource_importer_scene.cpp #: editor/import/resource_importer_texture.cpp #: editor/import/resource_importer_wav.cpp scene/3d/gi_probe.cpp -#, fuzzy msgid "Compress" -msgstr "元件" +msgstr "壓縮" #: editor/import/resource_importer_csv_translation.cpp msgid "Delimiter" @@ -6798,9 +6792,8 @@ msgid "sRGB" msgstr "sRGB" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "Slices" -msgstr "自動剪裁" +msgstr "切片" #: editor/import/resource_importer_layered_texture.cpp #: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp @@ -6817,9 +6810,8 @@ msgid "Vertical" msgstr "垂直" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Generate Tangents" -msgstr "產生點" +msgstr "產生切線" #: editor/import/resource_importer_obj.cpp msgid "Scale Mesh" @@ -6831,9 +6823,8 @@ msgstr "Mesh 偏移" #: editor/import/resource_importer_obj.cpp #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Octahedral Compression" -msgstr "設定表示式" +msgstr "八面體壓縮" #: editor/import/resource_importer_obj.cpp msgid "Optimize Mesh Flags" @@ -6921,27 +6912,24 @@ msgid "Meshes" msgstr "網格" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Ensure Tangents" -msgstr "修改曲線切線" +msgstr "確保切線" #: editor/import/resource_importer_scene.cpp msgid "Light Baking" msgstr "光照烘焙" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Lightmap Texel Size" -msgstr "烘焙光照圖" +msgstr "光照圖紋理元素大小" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp msgid "Skins" msgstr "Skin" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Use Named Skins" -msgstr "使用縮放吸附" +msgstr "使用命名 Skin" #: editor/import/resource_importer_scene.cpp msgid "External Files" @@ -6956,9 +6944,8 @@ msgid "Filter Script" msgstr "篩選腳本" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Keep Custom Tracks" -msgstr "變換" +msgstr "保留自定軌道" #: editor/import/resource_importer_scene.cpp msgid "Optimizer" @@ -8764,7 +8751,7 @@ msgstr "縮放模式" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Shift: Scale proportionally." -msgstr "" +msgstr "Shift:按比例縮放。" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -9282,11 +9269,11 @@ msgstr "漸層編輯" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp msgid "Swap GradientTexture2D Fill Points" -msgstr "" +msgstr "交換 GradientTexture2D 的填充點" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp msgid "Swap Gradient Fill Points" -msgstr "" +msgstr "交換 Gradient 填充點" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp msgid "Toggle Grid Snap" @@ -10091,7 +10078,7 @@ msgstr "同步骨骼到多邊形" #: editor/plugins/ray_cast_2d_editor_plugin.cpp msgid "Set cast_to" -msgstr "" +msgstr "設定 cast_to" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ERROR: Couldn't load resource!" @@ -10420,7 +10407,7 @@ msgstr "搜尋結果" #: editor/plugins/script_editor_plugin.cpp msgid "Open Dominant Script On Scene Change" -msgstr "" +msgstr "場景更改時開啟主腳本" #: editor/plugins/script_editor_plugin.cpp msgid "External" @@ -10444,7 +10431,7 @@ msgstr "強調顯示目前的腳本" #: editor/plugins/script_editor_plugin.cpp msgid "Script Temperature History Size" -msgstr "" +msgstr "腳本溫度歷史大小" #: editor/plugins/script_editor_plugin.cpp msgid "Current Script Background Color" @@ -10464,7 +10451,7 @@ msgstr "將腳本名稱列為" #: editor/plugins/script_editor_plugin.cpp msgid "Exec Flags" -msgstr "" +msgstr "執行旗標" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Scripts" @@ -10981,43 +10968,43 @@ msgstr "(不在GLES2中)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" "Debug draw modes are only available when using the GLES3 renderer, not GLES2." -msgstr "除錯繪製模式僅在使用 GLES3 算繪引擎時可用,GLES2 不可用。" +msgstr "除錯繪製模式僅可在 GLES3 算繪引擎下使用,無法在 GLES2 下使用。" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Left" -msgstr "自由視圖 左" +msgstr "自由觀看 左" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Right" -msgstr "自由視圖 右" +msgstr "自由觀看 右" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Forward" -msgstr "自由視圖 前" +msgstr "自由觀看 前" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Backwards" -msgstr "自由視圖 後" +msgstr "自由觀看 後" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Up" -msgstr "自由視圖 上" +msgstr "自由觀看 上" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Down" -msgstr "自由視圖 下" +msgstr "自由觀看 下" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Speed Modifier" -msgstr "加速自由視圖速度" +msgstr "自由觀看速度調整" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Slow Modifier" -msgstr "放慢自由視圖速度" +msgstr "自由觀看減速調整" #: editor/plugins/spatial_editor_plugin.cpp msgid "Toggle Camera Preview" -msgstr "切換相機預覽開關" +msgstr "開啟/關閉相機預覽" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Rotation Locked" @@ -11026,7 +11013,7 @@ msgstr "視圖旋轉已鎖定" #: editor/plugins/spatial_editor_plugin.cpp msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" -msgstr "若要再繼續放大,請至 檢視 -> 設定... 修改攝影機的剪裁平面" +msgstr "若要再繼續放大,請至 [檢視] -> [設定...] 修改攝影機的剪裁平面" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -11273,16 +11260,15 @@ msgstr "後置" #: editor/plugins/spatial_editor_plugin.cpp msgid "Manipulator Gizmo Size" -msgstr "" +msgstr "操縱器控制項大小" #: editor/plugins/spatial_editor_plugin.cpp msgid "Manipulator Gizmo Opacity" -msgstr "" +msgstr "操縱器控制項不透明度" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Show Viewport Rotation Gizmo" -msgstr "鎖定視角旋轉" +msgstr "顯示檢視區的旋轉控制器" #: editor/plugins/spatial_editor_plugin.cpp msgid "Unnamed Gizmo" @@ -11333,9 +11319,8 @@ msgid "Invalid geometry, can't replace by mesh." msgstr "無效的幾何圖形,無法以網格取代。" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to MeshInstance2D" -msgstr "轉換為 Mesh2D" +msgstr "轉換為 MeshInstance2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." @@ -11438,6 +11423,10 @@ msgid "New Animation" msgstr "新增動畫" #: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Filter animations" +msgstr "篩選動畫" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "速度:" @@ -11732,9 +11721,8 @@ msgstr "" "確定要關閉嗎?" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove Type" -msgstr "移除圖塊" +msgstr "移除型別" #: editor/plugins/theme_editor_plugin.cpp msgid "" @@ -11777,14 +11765,12 @@ msgstr "" "手動加入更多項目於其中或從另一個主題匯入。" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Add Theme Type" -msgstr "新增項目類型" +msgstr "新增主題型別" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove Theme Type" -msgstr "移除項目" +msgstr "移除主題型別" #: editor/plugins/theme_editor_plugin.cpp msgid "Add Color Item" @@ -11899,9 +11885,8 @@ msgid "Select Another Theme Resource:" msgstr "選擇其他主題資源:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Theme Resource" -msgstr "重新命名資源" +msgstr "主題資源" #: editor/plugins/theme_editor_plugin.cpp msgid "Another Theme" @@ -11913,21 +11898,19 @@ msgstr "新增類別" #: editor/plugins/theme_editor_plugin.cpp msgid "Filter the list of types or create a new custom type:" -msgstr "" +msgstr "篩選型別列表,或是建立新的自定型別:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Available Node-based types:" -msgstr "可用設定檔:" +msgstr "可用之基於節點的型別:" #: editor/plugins/theme_editor_plugin.cpp msgid "Type name is empty!" msgstr "型別名稱為空!" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Are you sure you want to create an empty type?" -msgstr "確定要打開多個專案嗎?" +msgstr "確定要建立空型別嗎?" #: editor/plugins/theme_editor_plugin.cpp msgid "Confirm Item Rename" @@ -11957,14 +11940,12 @@ msgid "Add Item Type" msgstr "新增項目類型" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Set Variation Base Type" -msgstr "設定變數型別" +msgstr "設定變化基礎型別" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Set Base Type" -msgstr "更改基礎型別" +msgstr "設定基礎型別" #: editor/plugins/theme_editor_plugin.cpp msgid "Show Default" @@ -11984,13 +11965,13 @@ msgstr "複寫所有預設類別項目。" #: editor/plugins/theme_editor_plugin.cpp msgid "Select the variation base type from a list of available types." -msgstr "" +msgstr "從可用的型別列表中選擇基礎型別的變化。" #: editor/plugins/theme_editor_plugin.cpp msgid "" "A type associated with a built-in class cannot be marked as a variation of " "another type." -msgstr "" +msgstr "與內建型別相關聯的型別無法被標記為另一個型別的變化。" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme:" @@ -12225,55 +12206,46 @@ msgid "Clear Transform" msgstr "清除變換" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Tile Map" -msgstr "繪製圖塊地圖" +msgstr "圖塊地圖" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Palette Min Width" -msgstr "" +msgstr "調色盤最小寬度" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Palette Item H Separation" -msgstr "帶名稱的分隔線" +msgstr "調色盤項目的水平分隔線" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Show Tile Names" -msgstr "顯示所有地區" +msgstr "顯示圖塊名稱" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Show Tile Ids" -msgstr "顯示尺規" +msgstr "顯示圖塊 ID" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Sort Tiles By Name" -msgstr "檔案排序" +msgstr "以名稱排序圖塊" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Bucket Fill Preview" -msgstr "油漆桶填滿" +msgstr "油漆桶填充預覽" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Editor Side" -msgstr "編輯器" +msgstr "編輯器側欄" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Display Grid" -msgstr "顯示過度繪圖" +msgstr "顯示柵欄" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Axis Color" -msgstr "選擇顏色" +msgstr "座標軸顏色" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Add Texture(s) to TileSet." @@ -12606,7 +12578,6 @@ msgid "This property can't be changed." msgstr "該屬性無法修改。" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Snap Options" msgstr "吸附選項" @@ -12635,9 +12606,8 @@ msgid "Separation" msgstr "間距" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Tile" -msgstr "選擇" +msgstr "所選圖塊" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/light_2d.cpp scene/2d/line_2d.cpp scene/2d/mesh_instance_2d.cpp @@ -12646,9 +12616,8 @@ msgstr "選擇" #: scene/gui/nine_patch_rect.cpp scene/gui/texture_rect.cpp #: scene/resources/material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Texture" -msgstr "純文字" +msgstr "紋理貼圖" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Tex Offset" @@ -12662,86 +12631,72 @@ msgstr "材質" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/canvas_item.cpp #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Modulate" -msgstr "填充" +msgstr "調變" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tile Mode" -msgstr "切換模式" +msgstr "圖塊模式" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Autotile Bitmask Mode" -msgstr "優先模式" +msgstr "自動圖塊的位元遮罩模式" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Subtile Size" msgstr "子圖塊大小" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Spacing" -msgstr "行間距" +msgstr "自圖塊間距" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occluder Offset" -msgstr "建立遮光多邊形" +msgstr "遮光偏移" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Offset" -msgstr "導航模式" +msgstr "導航偏移" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Shape Offset" msgstr "形狀偏移" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Shape Transform" -msgstr "變換" +msgstr "形狀變換" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision" -msgstr "碰撞" +msgstr "所選碰撞" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision One Way" -msgstr "僅搜尋所選區域" +msgstr "所選碰撞單向" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision One Way Margin" -msgstr "碰撞模式" +msgstr "所選碰撞單向外邊距" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Navigation" -msgstr "顯示導航" +msgstr "所選導航" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Occlusion" -msgstr "選擇" +msgstr "所選遮擋" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tileset Script" -msgstr "篩選腳本" +msgstr "圖塊集腳本" #: editor/plugins/tile_set_editor_plugin.cpp msgid "TileSet" msgstr "圖塊集" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "No VCS plugins are available." -msgstr "無可用的版本控制 (VCS) 擴充功能。" +msgstr "無可用的版本控制 (VCS) 外掛。" #: editor/plugins/version_control_editor_plugin.cpp msgid "" @@ -12749,9 +12704,8 @@ msgid "" msgstr "遠端設定是空的。使用網路的VCS功能恐無法運作。" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "No commit message was provided." -msgstr "未提供名稱。" +msgstr "未提供認可 (Commit) 訊息。" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" @@ -12782,14 +12736,12 @@ msgid "Do you want to remove the %s branch?" msgstr "你確定要移除 %s 分支?" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Do you want to remove the %s remote?" -msgstr "確定要打開多個專案嗎?" +msgstr "確定要移除遠端「%s」?" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Apply" -msgstr "套用重設" +msgstr "套用" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -12800,9 +12752,8 @@ msgid "Initialize" msgstr "初始化" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Remote Login" -msgstr "移除控制點" +msgstr "遠端登入" #: editor/plugins/version_control_editor_plugin.cpp msgid "Select SSH public key path" @@ -12833,55 +12784,48 @@ msgid "Unstage all changes" msgstr "撤銷暫存所有變更" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Commit Message" -msgstr "提交改動" +msgstr "認可 (Commit) 訊息" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit Changes" msgstr "提交改動" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Commit List" -msgstr "提交" +msgstr "認可列表" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit list size" -msgstr "簽入列表大小" +msgstr "認可列表大小" #: editor/plugins/version_control_editor_plugin.cpp msgid "Branches" msgstr "分支" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Create New Branch" -msgstr "建立新專案" +msgstr "建立分支" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Remove Branch" -msgstr "刪除動畫軌" +msgstr "移除分支" #: editor/plugins/version_control_editor_plugin.cpp msgid "Branch Name" msgstr "分支名稱" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Remotes" msgstr "遠端" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Create New Remote" -msgstr "建立新專案" +msgstr "建立遠端" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Remove Remote" -msgstr "移除項目" +msgstr "移除遠端" #: editor/plugins/version_control_editor_plugin.cpp msgid "Remote Name" @@ -12893,15 +12837,15 @@ msgstr "遠端網址" #: editor/plugins/version_control_editor_plugin.cpp msgid "Fetch" -msgstr "提取" +msgstr "截取 (Fetch)" #: editor/plugins/version_control_editor_plugin.cpp msgid "Pull" -msgstr "拉送" +msgstr "提取 (Pull)" #: editor/plugins/version_control_editor_plugin.cpp msgid "Push" -msgstr "推送" +msgstr "推送 (Push)" #: editor/plugins/version_control_editor_plugin.cpp msgid "Force Push" @@ -12909,7 +12853,7 @@ msgstr "強制推送" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" -msgstr "已修改" +msgstr "修改" #: editor/plugins/version_control_editor_plugin.cpp msgid "Renamed" @@ -12917,11 +12861,11 @@ msgstr "重新命名" #: editor/plugins/version_control_editor_plugin.cpp msgid "Deleted" -msgstr "已刪除" +msgstr "刪除" #: editor/plugins/version_control_editor_plugin.cpp msgid "Typechange" -msgstr "格式更改" +msgstr "更改型別" #: editor/plugins/version_control_editor_plugin.cpp msgid "Unmerged" @@ -12932,14 +12876,12 @@ msgid "View:" msgstr "檢視:" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Split" -msgstr "拆分路徑" +msgstr "分割" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Unified" -msgstr "已修改" +msgstr "合併" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -13796,11 +13738,11 @@ msgstr "可執行" #: editor/project_export.cpp msgid "Export the project for all the presets defined." -msgstr "" +msgstr "使用每個已定義的預設設定來匯出該專案。" #: editor/project_export.cpp msgid "All presets must have an export path defined for Export All to work." -msgstr "" +msgstr "所有預設設定都必須定義好匯出路徑,才可使用 [匯出全部] 功能。" #: editor/project_export.cpp msgid "Delete preset '%s'?" @@ -13911,11 +13853,12 @@ msgid "" "Note: Encryption key needs to be stored in the binary,\n" "you need to build the export templates from source." msgstr "" +"注意:加密金鑰必須以二進位形式保存,\n" +"必須從原始碼來編譯匯出樣板。" #: editor/project_export.cpp -#, fuzzy msgid "More Info..." -msgstr "移動至..." +msgstr "更多資訊..." #: editor/project_export.cpp msgid "Export PCK/Zip..." @@ -13942,18 +13885,16 @@ msgid "ZIP File" msgstr "ZIP 檔案" #: editor/project_export.cpp -#, fuzzy msgid "Godot Project Pack" -msgstr "Godot 遊戲包" +msgstr "Godot 專案包" #: editor/project_export.cpp msgid "Export templates for this platform are missing:" msgstr "缺少匯出該平台用的樣板:" #: editor/project_export.cpp -#, fuzzy msgid "Project Export" -msgstr "專案發起人" +msgstr "專案匯出" #: editor/project_export.cpp msgid "Manage Export Templates" @@ -14253,7 +14194,6 @@ msgstr "" #. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp -#, fuzzy msgctxt "Application" msgid "Project Manager" msgstr "專案管理員" @@ -14997,6 +14937,9 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"無法保存分支,該分支是已實體化場景的子項目。\n" +"若要將該分支保存進獨立的場景中,請開啟原始場景,並在該分支上點擊右鍵,然後選" +"擇 [將分支保存為場景]。" #: editor/scene_tree_dock.cpp msgid "" @@ -15004,6 +14947,9 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"無法保存分支,該分支是繼承場景的一部分。\n" +"若要將該分支保存為獨立的場景,請開啟原始場景,並在該分支上點擊右鍵,然後選擇 " +"[將分支保存為場景]。" #: editor/scene_tree_dock.cpp msgid "Save New Scene As..." @@ -15029,7 +14975,7 @@ msgstr "轉為本地" #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp msgid "Another node already uses this unique name in the scene." -msgstr "" +msgstr "另一個節點已在該場景中使用了這個不可重複的名稱。" #: editor/scene_tree_dock.cpp msgid "Enable Scene Unique Name" @@ -15111,7 +15057,7 @@ msgstr "子資源" #: editor/scene_tree_dock.cpp msgid "Access as Scene Unique Name" -msgstr "" +msgstr "以不重複的場景名稱來存取" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance" @@ -15206,18 +15152,16 @@ msgid "Clear Inheritance? (No Undo!)" msgstr "確定要清除繼承嗎?(無法復原!)" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Show Scene Tree Root Selection" -msgstr "置中所選" +msgstr "顯示場景樹的根選擇" #: editor/scene_tree_dock.cpp msgid "Derive Script Globals By Name" -msgstr "" +msgstr "依照名稱來推斷腳本的全域變數" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Use Favorites Root Selection" -msgstr "完整顯示所選" +msgstr "使用我的最愛根選擇" #: editor/scene_tree_editor.cpp msgid "Toggle Visible" @@ -15245,6 +15189,8 @@ msgid "" "with the '%s' prefix in a node path.\n" "Click to disable this." msgstr "" +"該節點可在此場景中的任何地方通過在節點路徑前方加上「%s」前置詞來存取。\n" +"點擊以禁用。" #: editor/scene_tree_editor.cpp msgid "" @@ -15527,21 +15473,20 @@ msgid "Stack Frames" msgstr "堆疊框" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Filter stack variables" -msgstr "篩選圖塊" +msgstr "篩選堆疊變數" #: editor/script_editor_debugger.cpp msgid "Auto Switch To Remote Scene Tree" -msgstr "" +msgstr "自動切換至遠端場景樹" #: editor/script_editor_debugger.cpp msgid "Remote Scene Tree Refresh Interval" -msgstr "" +msgstr "遠端場景樹重新整理間隔" #: editor/script_editor_debugger.cpp msgid "Remote Inspect Refresh Interval" -msgstr "" +msgstr "遠端檢查重新整理間隔" #: editor/script_editor_debugger.cpp msgid "Network Profiler" @@ -15639,7 +15584,7 @@ msgstr "更改光照半徑" #: editor/spatial_editor_gizmos.cpp msgid "Stream Player 3D" -msgstr "" +msgstr "StreamPlayer3D" #: editor/spatial_editor_gizmos.cpp msgid "Change AudioStreamPlayer3D Emission Angle" @@ -15649,7 +15594,7 @@ msgstr "更改 AudioStreamPlayer3D 發射角" #: platform/osx/export/export.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Camera" -msgstr "" +msgstr "相機" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" @@ -15661,7 +15606,7 @@ msgstr "更改相機尺寸" #: editor/spatial_editor_gizmos.cpp msgid "Visibility Notifier" -msgstr "" +msgstr "VisibilityNotifier" #: editor/spatial_editor_gizmos.cpp msgid "Change Notifier AABB" @@ -15672,23 +15617,20 @@ msgid "Change Particles AABB" msgstr "更改粒子 AABB" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Reflection Probe" -msgstr "選擇屬性" +msgstr "反射探查" #: editor/spatial_editor_gizmos.cpp msgid "Change Probe Extents" msgstr "更改探查範圍" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "GI Probe" -msgstr "烘焙 GI 探查" +msgstr "GI 探查" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Baked Indirect Light" -msgstr "非向性光照" +msgstr "烘焙間接光照" #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp msgid "Change Sphere Shape Radius" @@ -15719,14 +15661,12 @@ msgid "Change Ray Shape Length" msgstr "更改射線形長度" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Edge" -msgstr "導航模式" +msgstr "導航邊界" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Edge Disabled" -msgstr "導航模式" +msgstr "已禁用導航邊界" #: editor/spatial_editor_gizmos.cpp #, fuzzy @@ -19974,15 +19914,15 @@ msgstr "找不到金鑰儲存區,無法匯出。" #: platform/windows/export/export.cpp msgid "" -"Could not start rcedit executable, configure rcedit path in the Editor " -"Settings (Export > Windows > Rcedit)." +"Could not start rcedit executable. Configure rcedit path in the Editor " +"Settings (Export > Windows > Rcedit), or disable \"Application > Modify " +"Resources\" in the export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"rcedit failed to modify executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "rcedit failed to modify executable: %s." +msgstr "無效的副檔名。" #: platform/windows/export/export.cpp #, fuzzy @@ -20005,15 +19945,15 @@ msgstr "無效的名稱。" #: platform/windows/export/export.cpp msgid "" -"Could not start signtool executable, configure signtool path in the Editor " -"Settings (Export > Windows > Signtool)." +"Could not start signtool executable. Configure signtool path in the Editor " +"Settings (Export > Windows > Signtool), or disable \"Codesign\" in the " +"export preset." msgstr "" #: platform/windows/export/export.cpp -msgid "" -"Signtool failed to sign executable:\n" -"%s" -msgstr "" +#, fuzzy +msgid "Signtool failed to sign executable: %s." +msgstr "無效的副檔名。" #: platform/windows/export/export.cpp msgid "Failed to remove temporary file \"%s\"." @@ -23144,9 +23084,8 @@ msgstr "" "請改為修改其子節點的碰撞形狀之大小。" #: scene/3d/spatial.cpp -#, fuzzy msgid "Global Translation" -msgstr "保持全域變換" +msgstr "全域變換" #: scene/3d/spatial.cpp msgid "Matrix" @@ -26637,9 +26576,8 @@ msgid "Normal Texture" msgstr "法線紋理貼圖" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Color Texture" -msgstr "編輯器主題" +msgstr "顏色紋理貼圖" #: scene/resources/particles_material.cpp #, fuzzy diff --git a/main/main.cpp b/main/main.cpp index 73950f3471..965fcc66c6 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -31,6 +31,7 @@ #include "main.h" #include "core/config/project_settings.h" +#include "core/core_globals.h" #include "core/core_string_names.h" #include "core/crypto/crypto.h" #include "core/debugger/engine_debugger.h" @@ -181,7 +182,6 @@ static bool debug_navigation = false; static int frame_delay = 0; static bool disable_render_loop = false; static int fixed_fps = -1; -static String write_movie_path; static MovieWriter *movie_writer = nullptr; static bool disable_vsync = false; static bool print_fps = false; @@ -286,6 +286,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print("\n"); OS::get_singleton()->print("Run options:\n"); + OS::get_singleton()->print(" -- Separator for user-provided arguments. Following arguments are not used by the engine, but can be read from `OS.get_cmdline_user_args()`.\n"); #ifdef TOOLS_ENABLED OS::get_singleton()->print(" -e, --editor Start the editor instead of running the scene.\n"); OS::get_singleton()->print(" -p, --project-manager Start the project manager, even if a project is auto-detected.\n"); @@ -344,6 +345,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n"); OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n"); OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n"); + OS::get_singleton()->print(" --xr-mode <mode> Select XR mode (default/off/on).\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Debug options:\n"); @@ -429,6 +431,7 @@ Error Main::test_setup() { /** INITIALIZE SERVERS **/ register_server_types(); + XRServer::set_xr_mode(XRServer::XRMODE_OFF); // Skip in tests. initialize_modules(MODULE_INITIALIZATION_LEVEL_SERVERS); NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SERVERS); @@ -623,6 +626,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph /* argument parsing and main creation */ List<String> args; List<String> main_args; + List<String> user_args; + bool adding_user_args = false; List<String> platform_args = OS::get_singleton()->get_cmdline_platform_args(); // Add command line arguments. @@ -695,9 +700,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph continue; } #endif + List<String>::Element *N = I->next(); - if (I->get() == "-h" || I->get() == "--help" || I->get() == "/?") { // display help + if (adding_user_args) { + user_args.push_back(I->get()); + } else if (I->get() == "-h" || I->get() == "--help" || I->get() == "/?") { // display help show_help = true; exit_code = ERR_HELP; // Hack to force an early exit in `main()` with a success code. @@ -1162,7 +1170,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } else if (I->get() == "--write-movie") { if (I->next()) { - write_movie_path = I->next()->get(); + Engine::get_singleton()->set_write_movie_path(I->next()->get()); N = I->next()->next(); if (fixed_fps == -1) { fixed_fps = 60; @@ -1182,6 +1190,26 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->disable_crash_handler(); } else if (I->get() == "--skip-breakpoints") { skip_breakpoints = true; + } else if (I->get() == "--xr-mode") { + if (I->next()) { + String xr_mode = I->next()->get().to_lower(); + N = I->next()->next(); + if (xr_mode == "default") { + XRServer::set_xr_mode(XRServer::XRMODE_DEFAULT); + } else if (xr_mode == "off") { + XRServer::set_xr_mode(XRServer::XRMODE_OFF); + } else if (xr_mode == "on") { + XRServer::set_xr_mode(XRServer::XRMODE_ON); + } else { + OS::get_singleton()->print("Unknown --xr-mode argument \"%s\", aborting.\n", xr_mode.ascii().get_data()); + goto error; + } + } else { + OS::get_singleton()->print("Missing --xr-mode argument, aborting.\n"); + goto error; + } + } else if (I->get() == "--") { + adding_user_args = true; } else { main_args.push_back(I->get()); } @@ -1349,16 +1377,16 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph quiet_stdout = true; } if (bool(ProjectSettings::get_singleton()->get("application/run/disable_stderr"))) { - _print_error_enabled = false; + CoreGlobals::print_error_enabled = false; }; if (quiet_stdout) { - _print_line_enabled = false; + CoreGlobals::print_line_enabled = false; } Logger::set_flush_stdout_on_print(ProjectSettings::get_singleton()->get("application/run/flush_stdout_on_print")); - OS::get_singleton()->set_cmdline(execpath, main_args); + OS::get_singleton()->set_cmdline(execpath, main_args, user_args); // possibly be worth changing the default from vulkan to something lower spec, // for the project manager, depending on how smooth the fallback is. @@ -1453,7 +1481,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->_allow_layered = false; } - OS::get_singleton()->_keep_screen_on = GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true); if (rtm == -1) { rtm = GLOBAL_DEF("rendering/driver/threads/thread_model", OS::RENDER_THREAD_SAFE); } @@ -1512,7 +1539,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph audio_driver_idx = 0; } - if (write_movie_path != String()) { + if (Engine::get_singleton()->get_write_movie_path() != String()) { // Always use dummy driver for audio driver (which is last), also in no threaded mode. audio_driver_idx = AudioDriverManager::get_driver_count() - 1; AudioDriverDummy::get_dummy_singleton()->set_use_threads(false); @@ -1609,7 +1636,7 @@ error: display_driver = ""; audio_driver = ""; tablet_driver = ""; - write_movie_path = ""; + Engine::get_singleton()->set_write_movie_path(String()); project_path = ""; args.clear(); @@ -1651,6 +1678,7 @@ error: unregister_core_types(); OS::get_singleton()->_cmdline.clear(); + OS::get_singleton()->_user_args.clear(); if (message_queue) { memdelete(message_queue); @@ -1784,11 +1812,11 @@ Error Main::setup2(Thread::ID p_main_tid_override) { rendering_server->set_print_gpu_profile(true); } - if (write_movie_path != String()) { - movie_writer = MovieWriter::find_writer_for_file(write_movie_path); + if (Engine::get_singleton()->get_write_movie_path() != String()) { + movie_writer = MovieWriter::find_writer_for_file(Engine::get_singleton()->get_write_movie_path()); if (movie_writer == nullptr) { - ERR_PRINT("Can't find movie writer for file type, aborting: " + write_movie_path); - write_movie_path = String(); + ERR_PRINT("Can't find movie writer for file type, aborting: " + Engine::get_singleton()->get_write_movie_path()); + Engine::get_singleton()->set_write_movie_path(String()); } } @@ -2079,7 +2107,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { // able to load resources, load the global shader variables. // If running on editor, don't load the textures because the editor // may want to import them first. Editor will reload those later. - rendering_server->global_variables_load_settings(!editor); + rendering_server->global_shader_uniforms_load_settings(!editor); } _start_success = true; @@ -2411,6 +2439,8 @@ bool Main::start() { } if (debug_navigation) { sml->set_debug_navigation_hint(true); + NavigationServer3D::get_singleton()->set_active(true); + NavigationServer3D::get_singleton_mut()->set_debug_enabled(true); } #endif @@ -2576,7 +2606,7 @@ bool Main::start() { PropertyInfo(Variant::FLOAT, "display/window/stretch/scale", PROPERTY_HINT_RANGE, - "1.0,8.0,0.1")); + "0.5,8.0,0.01")); sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true)); sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true)); GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true); @@ -2724,7 +2754,7 @@ bool Main::start() { OS::get_singleton()->set_main_loop(main_loop); if (movie_writer) { - movie_writer->begin(DisplayServer::get_singleton()->window_get_size(), fixed_fps, write_movie_path); + movie_writer->begin(DisplayServer::get_singleton()->window_get_size(), fixed_fps, Engine::get_singleton()->get_write_movie_path()); } if (minimum_time_msec) { @@ -2980,6 +3010,7 @@ void Main::cleanup(bool p_force) { OS::get_singleton()->delete_main_loop(); OS::get_singleton()->_cmdline.clear(); + OS::get_singleton()->_user_args.clear(); OS::get_singleton()->_execpath = ""; OS::get_singleton()->_local_clipboard = ""; @@ -2992,7 +3023,7 @@ void Main::cleanup(bool p_force) { RenderingServer::get_singleton()->sync(); //clear global shader variables before scene and other graphics stuff are deinitialized. - rendering_server->global_variables_clear(); + rendering_server->global_shader_uniforms_clear(); if (xr_server) { // Now that we're unregistering properly in plugins we need to keep access to xr_server for a little longer diff --git a/main/performance.cpp b/main/performance.cpp index 25659b999f..0de525134e 100644 --- a/main/performance.cpp +++ b/main/performance.cpp @@ -283,7 +283,7 @@ Variant Performance::MonitorCall::call(bool &r_error, String &r_error_message) { int argc = _arguments.size(); Variant return_value; Callable::CallError error; - _callable.call(args, argc, return_value, error); + _callable.callp(args, argc, return_value, error); r_error = (error.error != Callable::CallError::CALL_OK); if (r_error) { r_error_message = Variant::get_callable_error_text(_callable, args, argc, error); diff --git a/methods.py b/methods.py index 571b134c8a..82c19f09e3 100644 --- a/methods.py +++ b/methods.py @@ -1,5 +1,6 @@ import os import re +import sys import glob import subprocess from collections import OrderedDict @@ -336,7 +337,20 @@ def disable_module(self): self.disabled_modules.append(self.current_module) -def module_check_dependencies(self, module, dependencies, silent=False): +def module_add_dependencies(self, module, dependencies, optional=False): + """ + Adds dependencies for a given module. + Meant to be used in module `can_build` methods. + """ + if module not in self.module_dependencies: + self.module_dependencies[module] = [[], []] + if optional: + self.module_dependencies[module][1].extend(dependencies) + else: + self.module_dependencies[module][0].extend(dependencies) + + +def module_check_dependencies(self, module): """ Checks if module dependencies are enabled for a given module, and prints a warning if they aren't. @@ -344,23 +358,41 @@ def module_check_dependencies(self, module, dependencies, silent=False): Returns a boolean (True if dependencies are satisfied). """ missing_deps = [] - for dep in dependencies: + required_deps = self.module_dependencies[module][0] if module in self.module_dependencies else [] + for dep in required_deps: opt = "module_{}_enabled".format(dep) if not opt in self or not self[opt]: missing_deps.append(dep) if missing_deps != []: - if not silent: - print( - "Disabling '{}' module as the following dependencies are not satisfied: {}".format( - module, ", ".join(missing_deps) - ) + print( + "Disabling '{}' module as the following dependencies are not satisfied: {}".format( + module, ", ".join(missing_deps) ) + ) return False else: return True +def sort_module_list(env): + out = OrderedDict() + deps = {k: v[0] + list(filter(lambda x: x in env.module_list, v[1])) for k, v in env.module_dependencies.items()} + + frontier = list(env.module_list.keys()) + explored = [] + while len(frontier): + cur = frontier.pop() + deps_list = deps[cur] if cur in deps else [] + if len(deps_list) and any([d not in explored for d in deps_list]): + # Will explore later, after its dependencies + frontier.insert(0, cur) + continue + explored.append(cur) + for k in explored: + env.module_list.move_to_end(k) + + def use_windows_spawn_fix(self, platform=None): if os.name != "nt": @@ -607,8 +639,18 @@ def find_visual_c_batch_file(env): find_batch_file, ) + # Syntax changed in SCons 4.4.0. + from SCons import __version__ as scons_raw_version + + scons_ver = env._get_major_minor_revision(scons_raw_version) + version = get_default_version(env) - (host_platform, target_platform, _) = get_host_target(env) + + if scons_ver >= (4, 4, 0): + (host_platform, target_platform, _) = get_host_target(env, version) + else: + (host_platform, target_platform, _) = get_host_target(env) + return find_batch_file(env, version, host_platform, target_platform)[0] diff --git a/misc/scripts/file_format.sh b/misc/scripts/file_format.sh index c767d3f8a0..731b3ee005 100755 --- a/misc/scripts/file_format.sh +++ b/misc/scripts/file_format.sh @@ -37,6 +37,8 @@ while IFS= read -rd '' f; do continue elif [[ "$f" == *"-so_wrap."* ]]; then continue + elif [[ "$f" == *".test.txt" ]]; then + continue fi # Ensure that files are UTF-8 formatted. recode UTF-8 "$f" 2> /dev/null diff --git a/misc/scripts/install_vulkan_sdk_macos.sh b/misc/scripts/install_vulkan_sdk_macos.sh index 817302d77f..d78659fa9f 100755 --- a/misc/scripts/install_vulkan_sdk_macos.sh +++ b/misc/scripts/install_vulkan_sdk_macos.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh set -euo pipefail IFS=$'\n\t' diff --git a/modules/bmp/SCsub b/modules/bmp/SCsub index 4f3405ff28..9d317887c3 100644 --- a/modules/bmp/SCsub +++ b/modules/bmp/SCsub @@ -5,5 +5,5 @@ Import("env_modules") env_bmp = env_modules.Clone() -# Godot's own source files +# Godot source files env_bmp.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/csg/SCsub b/modules/csg/SCsub index c7307ddefd..55f859db11 100644 --- a/modules/csg/SCsub +++ b/modules/csg/SCsub @@ -3,10 +3,9 @@ Import("env") Import("env_modules") -# Godot's own source files env_csg = env_modules.Clone() -# Godot's own source files +# Godot source files env_csg.add_source_files(env.modules_sources, "*.cpp") if env["tools"]: env_csg.add_source_files(env.modules_sources, "editor/*.cpp") diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 93533e1690..6b05c146e6 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -729,7 +729,7 @@ void CSGBrushOperation::MeshMerge::mark_inside_faces() { } } -void CSGBrushOperation::MeshMerge::add_face(const Vector3 p_points[], const Vector2 p_uvs[], bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b) { +void CSGBrushOperation::MeshMerge::add_face(const Vector3 p_points[3], const Vector2 p_uvs[3], bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b) { int indices[3]; for (int i = 0; i < 3; i++) { VertexKey vk; diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 0f09eb2020..56be4e65f0 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -1858,7 +1858,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { } Transform3D facing = Transform3D().looking_at(direction, current_up); - current_xform = base_xform.translated(current_point) * facing; + current_xform = base_xform.translated_local(current_point) * facing; } // Create the mesh. @@ -1897,7 +1897,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { switch (mode) { case MODE_DEPTH: { - current_xform.translate(Vector3(0, 0, -depth)); + current_xform.translate_local(Vector3(0, 0, -depth)); } break; case MODE_SPIN: { current_xform.rotate(Vector3(0, 1, 0), spin_step); @@ -1945,7 +1945,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { } Transform3D facing = Transform3D().looking_at(direction, current_up); - current_xform = base_xform.translated(current_point) * facing; + current_xform = base_xform.translated_local(current_point) * facing; } break; } diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp index a7cfcaa262..3322ff0a1b 100644 --- a/modules/cvtt/image_compress_cvtt.cpp +++ b/modules/cvtt/image_compress_cvtt.cpp @@ -129,14 +129,6 @@ static void _digest_row_task(const CVTTCompressionJobParams &p_job_params, const } } -static void _digest_job_queue(void *p_job_queue) { - CVTTCompressionJobQueue *job_queue = static_cast<CVTTCompressionJobQueue *>(p_job_queue); - - for (uint32_t next_task = job_queue->current_task.increment(); next_task <= job_queue->num_tasks; next_task = job_queue->current_task.increment()) { - _digest_row_task(job_queue->job_params, job_queue->job_tasks[next_task - 1]); - } -} - void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels) { if (p_image->get_format() >= Image::FORMAT_BPTC_RGBA) { return; //do not compress, already compressed @@ -202,7 +194,6 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann job_queue.job_params.bytes_per_pixel = is_hdr ? 6 : 4; cvtt::Kernels::ConfigureBC7EncodingPlanFromQuality(job_queue.job_params.bc7_plan, 5); - int num_job_threads = 0; // Amdahl's law (Wikipedia) // If a program needs 20 hours to complete using a single thread, but a one-hour portion of the program cannot be parallelized, // therefore only the remaining 19 hours (p = 0.95) of execution time can be parallelized, then regardless of how many threads are devoted @@ -229,11 +220,7 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann row_task.in_mm_bytes = in_bytes; row_task.out_mm_bytes = out_bytes; - if (num_job_threads > 0) { - tasks.push_back(row_task); - } else { - _digest_row_task(job_queue.job_params, row_task); - } + _digest_row_task(job_queue.job_params, row_task); out_bytes += 16 * (bw / 4); } @@ -243,29 +230,6 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann h = MAX(h / 2, 1); } - if (num_job_threads > 0) { - Vector<Thread *> threads; - threads.resize(num_job_threads); - - Thread **threads_wb = threads.ptrw(); - - const CVTTCompressionRowTask *tasks_rb = tasks.ptr(); - - job_queue.job_tasks = &tasks_rb[0]; - job_queue.current_task.set(0); - job_queue.num_tasks = static_cast<uint32_t>(tasks.size()); - - for (int i = 0; i < num_job_threads; i++) { - threads_wb[i] = memnew(Thread); - threads_wb[i]->start(_digest_job_queue, &job_queue); - } - _digest_job_queue(&job_queue); - - for (int i = 0; i < num_job_threads; i++) { - threads_wb[i]->wait_to_finish(); - memdelete(threads_wb[i]); - } - } p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); } diff --git a/modules/enet/enet_multiplayer_peer.cpp b/modules/enet/enet_multiplayer_peer.cpp index cd94cc9425..dfdd08c9f4 100644 --- a/modules/enet/enet_multiplayer_peer.cpp +++ b/modules/enet/enet_multiplayer_peer.cpp @@ -441,15 +441,15 @@ Error ENetMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size channel = SYSCH_MAX + transfer_channel - 1; } else { switch (get_transfer_mode()) { - case Multiplayer::TRANSFER_MODE_UNRELIABLE: { + case TRANSFER_MODE_UNRELIABLE: { packet_flags = ENET_PACKET_FLAG_UNSEQUENCED | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT; channel = SYSCH_UNRELIABLE; } break; - case Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED: { + case TRANSFER_MODE_UNRELIABLE_ORDERED: { packet_flags = ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT; channel = SYSCH_UNRELIABLE; } break; - case Multiplayer::TRANSFER_MODE_RELIABLE: { + case TRANSFER_MODE_RELIABLE: { packet_flags = ENET_PACKET_FLAG_RELIABLE; channel = SYSCH_RELIABLE; } break; diff --git a/modules/enet/enet_multiplayer_peer.h b/modules/enet/enet_multiplayer_peer.h index 131aa04df1..3152068d46 100644 --- a/modules/enet/enet_multiplayer_peer.h +++ b/modules/enet/enet_multiplayer_peer.h @@ -32,7 +32,7 @@ #define ENET_MULTIPLAYER_PEER_H #include "core/crypto/crypto.h" -#include "core/multiplayer/multiplayer_peer.h" +#include "scene/main/multiplayer_peer.h" #include "enet_connection.h" #include <enet/enet.h> diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub index 4b2ea6faa5..8efcd72fb6 100644 --- a/modules/freetype/SCsub +++ b/modules/freetype/SCsub @@ -58,22 +58,23 @@ if env["builtin_freetype"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - thirdparty_brotli_dir = "#thirdparty/brotli/" - thirdparty_brotli_sources = [ - "common/constants.c", - "common/context.c", - "common/dictionary.c", - "common/platform.c", - "common/shared_dictionary.c", - "common/transform.c", - "dec/bit_reader.c", - "dec/decode.c", - "dec/huffman.c", - "dec/state.c", - ] - thirdparty_sources += [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources] - env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) - env_freetype.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) + if env["brotli"]: + thirdparty_brotli_dir = "#thirdparty/brotli/" + thirdparty_brotli_sources = [ + "common/constants.c", + "common/context.c", + "common/dictionary.c", + "common/platform.c", + "common/shared_dictionary.c", + "common/transform.c", + "dec/bit_reader.c", + "dec/decode.c", + "dec/huffman.c", + "dec/state.c", + ] + thirdparty_sources += [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources] + env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) + env_freetype.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) if env.get("use_ubsan") or env.get("use_asan") or env.get("use_tsan") or env.get("use_lsan") or env.get("use_msan"): env_freetype.Append(CPPDEFINES=["BROTLI_BUILD_PORTABLE"]) diff --git a/modules/freetype/config.py b/modules/freetype/config.py index d22f9454ed..c0586d5536 100644 --- a/modules/freetype/config.py +++ b/modules/freetype/config.py @@ -2,5 +2,13 @@ def can_build(env, platform): return True +def get_opts(platform): + from SCons.Variables import BoolVariable + + return [ + BoolVariable("brotli", "Enable Brotli decompressor for WOFF2 fonts support", True), + ] + + def configure(env): pass diff --git a/modules/gdscript/config.py b/modules/gdscript/config.py index 61ce6185a5..a7d5c406e9 100644 --- a/modules/gdscript/config.py +++ b/modules/gdscript/config.py @@ -1,4 +1,5 @@ def can_build(env, platform): + env.module_add_dependencies("gdscript", ["jsonrpc", "websocket"], True) return True diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 4372bb33ba..a23f19de85 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -623,11 +623,11 @@ void GDScriptSyntaxHighlighter::_update_cache() { annotation_color = Color(1.0, 0.7, 0.45); string_name_color = Color(1.0, 0.66, 0.72); } else { - function_definition_color = Color(0.0, 0.65, 0.73); - node_path_color = Color(0.62, 0.67, 0.39); - node_ref_color = Color(0.32, 0.55, 0.29); - annotation_color = Color(0.8, 0.5, 0.25); - string_name_color = Color(0.9, 0.56, 0.62); + function_definition_color = Color(0, 0.6, 0.6); + node_path_color = Color(0.18, 0.55, 0); + node_ref_color = Color(0.0, 0.5, 0); + annotation_color = Color(0.8, 0.37, 0); + string_name_color = Color(0.8, 0.46, 0.52); } EDITOR_DEF("text_editor/theme/highlighting/gdscript/function_definition_color", function_definition_color); diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index a34bf6ef82..dc6bfbb034 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -51,7 +51,7 @@ #endif #ifdef TOOLS_ENABLED -#include "editor/editor_settings.h" +#include "editor/editor_paths.h" #endif /////////////////////////// @@ -325,16 +325,23 @@ void GDScript::_get_script_property_list(List<PropertyInfo> *r_list, bool p_incl for (int i = 0; i < msort.size(); i++) { props.push_front(sptr->member_info[msort[i].name]); } + +#ifdef TOOLS_ENABLED + r_list->push_back(sptr->get_class_category()); +#endif // TOOLS_ENABLED + + for (const PropertyInfo &E : props) { + r_list->push_back(E); + } + + props.clear(); + if (!p_include_base) { break; } sptr = sptr->_base; } - - for (const PropertyInfo &E : props) { - r_list->push_back(E); - } } void GDScript::get_script_property_list(List<PropertyInfo> *r_list) const { @@ -434,10 +441,6 @@ void GDScript::set_source_code(const String &p_code) { #ifdef TOOLS_ENABLED void GDScript::_update_exports_values(HashMap<StringName, Variant> &values, List<PropertyInfo> &propnames) { - if (base_cache.is_valid()) { - base_cache->_update_exports_values(values, propnames); - } - for (const KeyValue<StringName, Variant> &E : member_default_values_cache) { values[E.key] = E.value; } @@ -445,6 +448,10 @@ void GDScript::_update_exports_values(HashMap<StringName, Variant> &values, List for (const PropertyInfo &E : members_cache) { propnames.push_back(E); } + + if (base_cache.is_valid()) { + base_cache->_update_exports_values(values, propnames); + } } void GDScript::_add_doc(const DocData::ClassDoc &p_inner_class) { @@ -703,6 +710,8 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc member_default_values_cache.clear(); _signals.clear(); + members_cache.push_back(get_class_category()); + for (int i = 0; i < c->members.size(); i++) { const GDScriptParser::ClassNode::Member &member = c->members[i]; @@ -728,6 +737,9 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc } _signals[member.signal->identifier->name] = parameters_names; } break; + case GDScriptParser::ClassNode::Member::GROUP: { + members_cache.push_back(member.annotation->export_info); + } break; default: break; // Nothing. } @@ -848,7 +860,7 @@ Error GDScript::reload(bool p_keep_state) { // Loading a template, don't parse. #ifdef TOOLS_ENABLED - if (EditorSettings::get_singleton() && basedir.begins_with(EditorSettings::get_singleton()->get_project_script_templates_dir())) { + if (EditorPaths::get_singleton() && basedir.begins_with(EditorPaths::get_singleton()->get_project_script_templates_dir())) { return OK; } #endif @@ -954,8 +966,8 @@ void GDScript::get_members(HashSet<StringName> *p_members) { } } -const Vector<Multiplayer::RPCConfig> GDScript::get_rpc_methods() const { - return rpc_functions; +const Variant GDScript::get_rpc_config() const { + return rpc_config; } Variant GDScript::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { @@ -1212,9 +1224,9 @@ void GDScript::_save_orphaned_subclasses() { void GDScript::_init_rpc_methods_properties() { // Copy the base rpc methods so we don't mask their IDs. - rpc_functions.clear(); + rpc_config.clear(); if (base.is_valid()) { - rpc_functions = base->rpc_functions; + rpc_config = base->rpc_config.duplicate(); } GDScript *cscript = this; @@ -1222,12 +1234,9 @@ void GDScript::_init_rpc_methods_properties() { while (cscript) { // RPC Methods for (KeyValue<StringName, GDScriptFunction *> &E : cscript->member_functions) { - Multiplayer::RPCConfig config = E.value->get_rpc_config(); - if (config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) { - config.name = E.value->get_name(); - if (rpc_functions.find(config) == -1) { - rpc_functions.push_back(config); - } + Variant config = E.value->get_rpc_config(); + if (config.get_type() != Variant::NIL) { + rpc_config[E.value->get_name()] = config; } } @@ -1241,9 +1250,6 @@ void GDScript::_init_rpc_methods_properties() { cscript = nullptr; } } - - // Sort so we are 100% that they are always the same. - rpc_functions.sort_custom<Multiplayer::SortRPCConfig>(); } GDScript::~GDScript() { @@ -1408,9 +1414,7 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { while (sl) { HashMap<StringName, GDScriptFunction *>::ConstIterator E = sl->member_functions.find(p_name); if (E) { - Multiplayer::RPCConfig config; - config.name = p_name; - if (sptr->rpc_functions.find(config) != -1) { + if (sptr->rpc_config.has(p_name)) { r_ret = Callable(memnew(GDScriptRPCCallable(this->owner, E->key))); } else { r_ret = Callable(this->owner, E->key); @@ -1518,11 +1522,17 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const props.push_front(sptr->member_info[msort[i].name]); } - sptr = sptr->_base; - } +#ifdef TOOLS_ENABLED + p_properties->push_back(sptr->get_class_category()); +#endif // TOOLS_ENABLED + + for (const PropertyInfo &prop : props) { + p_properties->push_back(prop); + } + + props.clear(); - for (const PropertyInfo &E : props) { - p_properties->push_back(E); + sptr = sptr->_base; } } @@ -1629,15 +1639,13 @@ ScriptLanguage *GDScriptInstance::get_language() { return GDScriptLanguage::get_singleton(); } -const Vector<Multiplayer::RPCConfig> GDScriptInstance::get_rpc_methods() const { - return script->get_rpc_methods(); +const Variant GDScriptInstance::get_rpc_config() const { + return script->get_rpc_config(); } void GDScriptInstance::reload_members() { #ifdef DEBUG_ENABLED - members.resize(script->member_indices.size()); //resize - Vector<Variant> new_members; new_members.resize(script->member_indices.size()); @@ -1649,6 +1657,8 @@ void GDScriptInstance::reload_members() { } } + members.resize(new_members.size()); //resize + //apply members = new_members; @@ -2388,7 +2398,7 @@ void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<S } } -Error ResourceFormatSaverGDScript::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverGDScript::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { Ref<GDScript> sqscr = p_resource; ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index e9a206f48b..5123cccddd 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -87,7 +87,7 @@ class GDScript : public Script { HashMap<StringName, MemberInfo> member_indices; //members are just indices to the instantiated script. HashMap<StringName, Ref<GDScript>> subclasses; HashMap<StringName, Vector<StringName>> _signals; - Vector<Multiplayer::RPCConfig> rpc_functions; + Dictionary rpc_config; #ifdef TOOLS_ENABLED @@ -250,7 +250,7 @@ public: virtual void get_constants(HashMap<StringName, Variant> *p_constants) override; virtual void get_members(HashSet<StringName> *p_members) override; - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override; + virtual const Variant get_rpc_config() const override; #ifdef TOOLS_ENABLED virtual bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; } @@ -304,7 +304,7 @@ public: void reload_members(); - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const; + virtual const Variant get_rpc_config() const; GDScriptInstance(); ~GDScriptInstance(); @@ -524,7 +524,7 @@ public: class ResourceFormatSaverGDScript : public ResourceFormatSaver { public: - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; virtual bool recognize(const Ref<Resource> &p_resource) const; }; diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 7ed440929c..a07d4855f3 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -3238,12 +3238,12 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, valid); if (!valid) { push_error(vformat(R"(Cannot get member "%s" from "%s".)", p_subscript->attribute->name, p_subscript->base->reduced_value), p_subscript->index); + result_type.kind = GDScriptParser::DataType::VARIANT; } else { p_subscript->is_constant = true; p_subscript->reduced_value = value; result_type = type_from_variant(value, p_subscript); } - result_type.kind = GDScriptParser::DataType::VARIANT; } else { GDScriptParser::DataType base_type = p_subscript->base->get_datatype(); diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index a1a28e7675..fa158591fd 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -158,7 +158,7 @@ void GDScriptByteCodeGenerator::end_parameters() { function->default_arguments.reverse(); } -void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Multiplayer::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) { +void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Variant p_rpc_config, const GDScriptDataType &p_return_type) { function = memnew(GDScriptFunction); debug_stack = EngineDebugger::is_active(); @@ -1608,7 +1608,7 @@ void GDScriptByteCodeGenerator::write_return(const Address &p_return_value) { // Typed array. const GDScriptDataType &element_type = function->return_type.get_container_element_type(); - Variant script = function->return_type.script_type; + Variant script = element_type.script_type; int script_idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS); append(GDScriptFunction::OPCODE_RETURN_TYPED_ARRAY, 2); diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h index ffc3178c83..7dd51845df 100644 --- a/modules/gdscript/gdscript_byte_codegen.h +++ b/modules/gdscript/gdscript_byte_codegen.h @@ -419,7 +419,7 @@ public: virtual void start_block() override; virtual void end_block() override; - virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Multiplayer::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) override; + virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Variant p_rpc_config, const GDScriptDataType &p_return_type) override; virtual GDScriptFunction *write_end() override; #ifdef DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index 7b5f133ec5..5972481c3a 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/modules/gdscript/gdscript_codegen.h @@ -31,7 +31,6 @@ #ifndef GDSCRIPT_CODEGEN_H #define GDSCRIPT_CODEGEN_H -#include "core/multiplayer/multiplayer.h" #include "core/string/string_name.h" #include "core/variant/variant.h" #include "gdscript_function.h" @@ -80,7 +79,7 @@ public: virtual void start_block() = 0; virtual void end_block() = 0; - virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Multiplayer::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) = 0; + virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Variant p_rpc_config, const GDScriptDataType &p_return_type) = 0; virtual GDScriptFunction *write_end() = 0; #ifdef DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index e36252ada5..00e8223b9a 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1975,7 +1975,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ StringName func_name; bool is_static = false; - Multiplayer::RPCConfig rpc_config; + Variant rpc_config; GDScriptDataType return_type; return_type.has_type = true; return_type.kind = GDScriptDataType::BUILTIN; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 90dcfa307e..d943974ce4 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -1473,11 +1473,16 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, if (callee_type == GDScriptParser::Node::IDENTIFIER || call->is_super) { // Simple call, so base is 'self'. if (p_context.current_class) { - base.type.kind = GDScriptParser::DataType::CLASS; - base.type.type_source = GDScriptParser::DataType::INFERRED; - base.type.is_constant = true; - base.type.class_type = p_context.current_class; - base.value = p_context.base; + if (call->is_super) { + base.type = p_context.current_class->base_type; + base.value = p_context.base; + } else { + base.type.kind = GDScriptParser::DataType::CLASS; + base.type.type_source = GDScriptParser::DataType::INFERRED; + base.type.is_constant = true; + base.type.class_type = p_context.current_class; + base.value = p_context.base; + } } else { break; } diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 53c75648a0..e44038d6da 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -477,7 +477,7 @@ private: int _initial_line = 0; bool _static = false; - Multiplayer::RPCConfig rpc_config; + Variant rpc_config; GDScript *_script = nullptr; @@ -599,7 +599,7 @@ public: void disassemble(const Vector<String> &p_code_lines) const; #endif - _FORCE_INLINE_ Multiplayer::RPCConfig get_rpc_config() const { return rpc_config; } + _FORCE_INLINE_ const Variant get_rpc_config() const { return rpc_config; } GDScriptFunction(); ~GDScriptFunction(); }; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index e8fa2981ba..6f5397e1a3 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -35,6 +35,7 @@ #include "core/io/resource_loader.h" #include "core/math/math_defs.h" #include "gdscript.h" +#include "scene/main/multiplayer_api.h" #ifdef DEBUG_ENABLED #include "core/os/os.h" @@ -145,7 +146,7 @@ GDScriptParser::GDScriptParser() { // Warning annotations. register_annotation(MethodInfo("@warning_ignore", PropertyInfo(Variant::STRING, "warning")), AnnotationInfo::CLASS | AnnotationInfo::VARIABLE | AnnotationInfo::SIGNAL | AnnotationInfo::CONSTANT | AnnotationInfo::FUNCTION | AnnotationInfo::STATEMENT, &GDScriptParser::warning_annotations, varray(), true); // Networking. - register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<Multiplayer::RPC_MODE_AUTHORITY>, varray("", "", "", 0), true); + register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::rpc_annotation, varray("", "", "", 0), true); } GDScriptParser::~GDScriptParser() { @@ -3867,16 +3868,21 @@ bool GDScriptParser::warning_annotations(const AnnotationNode *p_annotation, Nod #endif // DEBUG_ENABLED } -template <Multiplayer::RPCMode t_mode> -bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Node *p_node) { - ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE && p_node->type != Node::FUNCTION, false, vformat(R"("%s" annotation can only be applied to variables and functions.)", p_annotation->name)); +bool GDScriptParser::rpc_annotation(const AnnotationNode *p_annotation, Node *p_node) { + ERR_FAIL_COND_V_MSG(p_node->type != Node::FUNCTION, false, vformat(R"("%s" annotation can only be applied to functions.)", p_annotation->name)); - Multiplayer::RPCConfig rpc_config; - rpc_config.rpc_mode = t_mode; + FunctionNode *function = static_cast<FunctionNode *>(p_node); + if (function->rpc_config.get_type() != Variant::NIL) { + push_error(R"(RPC annotations can only be used once per function.)", p_annotation); + return false; + } + + Dictionary rpc_config; + rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY; if (p_annotation->resolved_arguments.size()) { int last = p_annotation->resolved_arguments.size() - 1; if (p_annotation->resolved_arguments[last].get_type() == Variant::INT) { - rpc_config.channel = p_annotation->resolved_arguments[last].operator int(); + rpc_config["channel"] = p_annotation->resolved_arguments[last].operator int(); last -= 1; } if (last > 3) { @@ -3886,37 +3892,25 @@ bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Nod for (int i = last; i >= 0; i--) { String mode = p_annotation->resolved_arguments[i].operator String(); if (mode == "any_peer") { - rpc_config.rpc_mode = Multiplayer::RPC_MODE_ANY_PEER; + rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_ANY_PEER; } else if (mode == "authority") { - rpc_config.rpc_mode = Multiplayer::RPC_MODE_AUTHORITY; + rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY; } else if (mode == "call_local") { - rpc_config.call_local = true; + rpc_config["call_local"] = true; } else if (mode == "call_remote") { - rpc_config.call_local = false; + rpc_config["call_local"] = false; } else if (mode == "reliable") { - rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; + rpc_config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE; } else if (mode == "unreliable") { - rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_UNRELIABLE; + rpc_config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE; } else if (mode == "unreliable_ordered") { - rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED; + rpc_config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE_ORDERED; } else { push_error(R"(Invalid RPC argument. Must be one of: 'call_local'/'call_remote' (local calls), 'any_peer'/'authority' (permission), 'reliable'/'unreliable'/'unreliable_ordered' (transfer mode).)", p_annotation); } } } - switch (p_node->type) { - case Node::FUNCTION: { - FunctionNode *function = static_cast<FunctionNode *>(p_node); - if (function->rpc_config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) { - push_error(R"(RPC annotations can only be used once per function.)", p_annotation); - return false; - } - function->rpc_config = rpc_config; - break; - } - default: - return false; // Unreachable. - } + function->rpc_config = rpc_config; return true; } diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 9c97f98fbc..d4efab173b 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -32,7 +32,6 @@ #define GDSCRIPT_PARSER_H #include "core/io/resource.h" -#include "core/multiplayer/multiplayer.h" #include "core/object/ref_counted.h" #include "core/object/script_language.h" #include "core/string/string_name.h" @@ -750,7 +749,7 @@ public: SuiteNode *body = nullptr; bool is_static = false; bool is_coroutine = false; - Multiplayer::RPCConfig rpc_config; + Variant rpc_config; MethodInfo info; LambdaNode *source_lambda = nullptr; #ifdef TOOLS_ENABLED @@ -1371,8 +1370,7 @@ private: template <PropertyUsageFlags t_usage> bool export_group_annotations(const AnnotationNode *p_annotation, Node *p_target); bool warning_annotations(const AnnotationNode *p_annotation, Node *p_target); - template <Multiplayer::RPCMode t_mode> - bool network_annotations(const AnnotationNode *p_annotation, Node *p_target); + bool rpc_annotation(const AnnotationNode *p_annotation, Node *p_target); // Statements. Node *parse_statement(); VariableNode *parse_variable(); diff --git a/modules/gdscript/gdscript_rpc_callable.cpp b/modules/gdscript/gdscript_rpc_callable.cpp index 63ebd8acf5..4e12419357 100644 --- a/modules/gdscript/gdscript_rpc_callable.cpp +++ b/modules/gdscript/gdscript_rpc_callable.cpp @@ -76,11 +76,11 @@ GDScriptRPCCallable::GDScriptRPCCallable(Object *p_object, const StringName &p_m ERR_FAIL_COND_MSG(!node, "RPC can only be defined on class that extends Node."); } -void GDScriptRPCCallable::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { +Error GDScriptRPCCallable::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { if (unlikely(!node)) { r_call_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; - return; + return ERR_UNCONFIGURED; } r_call_error.error = Callable::CallError::CALL_OK; - node->rpcp(p_peer_id, method, p_arguments, p_argcount); + return node->rpcp(p_peer_id, method, p_arguments, p_argcount); } diff --git a/modules/gdscript/gdscript_rpc_callable.h b/modules/gdscript/gdscript_rpc_callable.h index c8a91d6259..83b9c7e2df 100644 --- a/modules/gdscript/gdscript_rpc_callable.h +++ b/modules/gdscript/gdscript_rpc_callable.h @@ -52,7 +52,7 @@ public: CompareLessFunc get_compare_less_func() const override; ObjectID get_object() const override; void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; - void rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override; + Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override; GDScriptRPCCallable(Object *p_object, const StringName &p_method); virtual ~GDScriptRPCCallable() = default; diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp index a914374985..4b97486cb3 100644 --- a/modules/gdscript/gdscript_utility_functions.cpp +++ b/modules/gdscript/gdscript_utility_functions.cpp @@ -115,6 +115,7 @@ struct GDScriptUtilityFunctionsDefinitions { if (p_arg_count < 1) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; + r_error.expected = 1; *r_ret = Variant(); return; } diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 10365f8481..61e2c61abc 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -2234,7 +2234,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a retvalue = gdfs; - Error err = sig.connect(callable_bind(Callable(gdfs.ptr(), "_signal_callback"), retvalue), Object::CONNECT_ONESHOT); + Error err = sig.connect(Callable(gdfs.ptr(), "_signal_callback").bind(retvalue), Object::CONNECT_ONESHOT); if (err != OK) { err_text = "Error connecting to signal: " + sig.get_name() + " during await."; OPCODE_BREAK; @@ -3295,6 +3295,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a int globalname_idx = _code_ptr[ip + 2]; GD_ERR_BREAK(globalname_idx < 0 || globalname_idx >= _global_names_count); const StringName *globalname = &_global_names_ptr[globalname_idx]; + GD_ERR_BREAK(!GDScriptLanguage::get_singleton()->get_named_globals_map().has(*globalname)); GET_INSTRUCTION_ARG(dst, 0); *dst = GDScriptLanguage::get_singleton()->get_named_globals_map()[*globalname]; diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index 03e93821c7..46a9b33eb0 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -690,9 +690,7 @@ Dictionary ExtendGDScriptParser::dump_function_api(const GDScriptParser::Functio ERR_FAIL_NULL_V(p_func, func); func["name"] = p_func->identifier->name; func["return_type"] = p_func->get_datatype().to_string(); - func["rpc_mode"] = p_func->rpc_config.rpc_mode; - func["rpc_transfer_mode"] = p_func->rpc_config.transfer_mode; - func["rpc_transfer_channel"] = p_func->rpc_config.channel; + func["rpc_config"] = p_func->rpc_config; Array parameters; for (int i = 0; i < p_func->parameters.size(); i++) { Dictionary arg; diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 7460f8edff..c0d5856be5 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -34,6 +34,7 @@ #include "editor/doc_tools.h" #include "editor/editor_log.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" GDScriptLanguageProtocol *GDScriptLanguageProtocol::singleton = nullptr; diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp index 14337e87da..ead4ef1987 100644 --- a/modules/gdscript/language_server/gdscript_language_server.cpp +++ b/modules/gdscript/language_server/gdscript_language_server.cpp @@ -34,6 +34,7 @@ #include "core/os/os.h" #include "editor/editor_log.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" GDScriptLanguageServer::GDScriptLanguageServer() { _EDITOR_DEF("network/language_server/remote_host", host); diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 8d484a43b3..ded2a7b4d4 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -38,6 +38,7 @@ #include "editor/editor_file_system.h" #include "editor/editor_help.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" #include "gdscript_language_protocol.h" #include "scene/resources/packed_scene.h" @@ -499,7 +500,9 @@ Error GDScriptWorkspace::parse_local_script(const String &p_path) { String GDScriptWorkspace::get_file_path(const String &p_uri) const { String path = p_uri; - path = path.replace(root_uri + "/", "res://"); + path = path.replace("///", "//"); + path = path.replace("%3A", ":"); + path = path.replacen(root_uri + "/", "res://"); path = path.uri_decode(); return path; } diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index b230c6ba36..059ca703ab 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -52,10 +52,10 @@ GDScriptCache *gdscript_cache = nullptr; #ifdef TOOLS_ENABLED -#include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_translation_parser.h" +#include "editor/export/editor_export.h" #include "editor/gdscript_highlighter.h" #include "editor/gdscript_translation_parser_plugin.h" diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp index ff4832bde0..e3b956369d 100644 --- a/modules/gdscript/tests/gdscript_test_runner.cpp +++ b/modules/gdscript/tests/gdscript_test_runner.cpp @@ -36,6 +36,7 @@ #include "../gdscript_parser.h" #include "core/config/project_settings.h" +#include "core/core_globals.h" #include "core/core_string_names.h" #include "core/io/dir_access.h" #include "core/io/file_access_pack.h" @@ -142,8 +143,8 @@ GDScriptTestRunner::GDScriptTestRunner(const String &p_source_dir, bool p_init_l #endif // Enable printing to show results - _print_line_enabled = true; - _print_error_enabled = true; + CoreGlobals::print_line_enabled = true; + CoreGlobals::print_error_enabled = true; } GDScriptTestRunner::~GDScriptTestRunner() { diff --git a/modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.gd b/modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.gd index fb0ace6a90..ea744e3027 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.gd @@ -1,3 +1,5 @@ +const A := 42 + func test(): pass diff --git a/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.gd b/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.gd new file mode 100644 index 0000000000..276875dd5a --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.gd @@ -0,0 +1,6 @@ +const Constants = preload("gdscript_to_preload.gd") + +func test(): + var a := Constants.A + print(a) + diff --git a/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.out b/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.out new file mode 100644 index 0000000000..0982f3718c --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.out @@ -0,0 +1,2 @@ +GDTEST_OK +42 diff --git a/modules/gltf/SCsub b/modules/gltf/SCsub index 6634d5df7b..71f3ba58d9 100644 --- a/modules/gltf/SCsub +++ b/modules/gltf/SCsub @@ -5,7 +5,7 @@ Import("env_modules") env_gltf = env_modules.Clone() -# Godot's own source files +# Godot source files env_gltf.add_source_files(env.modules_sources, "*.cpp") env_gltf.add_source_files(env.modules_sources, "extensions/*.cpp") env_gltf.add_source_files(env.modules_sources, "structures/*.cpp") diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 4ca8482ba3..7e90f198f6 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -4938,7 +4938,8 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> state) { if (d.has("name")) { const String name = d["name"]; - if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) { + const String name_lower = name.to_lower(); + if (name_lower.begins_with("loop") || name_lower.ends_with("loop") || name_lower.begins_with("cycle") || name_lower.ends_with("cycle")) { animation->set_loop(true); } animation->set_name(_gen_unique_animation_name(state, name)); diff --git a/modules/gridmap/SCsub b/modules/gridmap/SCsub index 52777235b8..da3f7d4dd9 100644 --- a/modules/gridmap/SCsub +++ b/modules/gridmap/SCsub @@ -5,7 +5,7 @@ Import("env_modules") env_gridmap = env_modules.Clone() -# Godot's own source files +# Godot source files env_gridmap.add_source_files(env.modules_sources, "*.cpp") if env["tools"]: env_gridmap.add_source_files(env.modules_sources, "editor/*.cpp") diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index f975d95079..09f0ff32f0 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -545,7 +545,7 @@ void GridMapEditor::_update_paste_indicator() { Basis rot; rot.set_orthogonal_index(paste_indicator.orientation); xf.basis = rot * xf.basis; - xf.translate((-center * node->get_cell_size()) / scale); + xf.translate_local((-center * node->get_cell_size()) / scale); RenderingServer::get_singleton()->instance_set_transform(paste_instance, node->get_global_transform() * xf); @@ -553,7 +553,7 @@ void GridMapEditor::_update_paste_indicator() { xf = Transform3D(); xf.origin = (paste_indicator.begin + (paste_indicator.current - paste_indicator.click) + center) * node->get_cell_size(); xf.basis = rot * xf.basis; - xf.translate(item.grid_offset * node->get_cell_size()); + xf.translate_local(item.grid_offset * node->get_cell_size()); Basis item_rot; item_rot.set_orthogonal_index(item.orientation); @@ -1231,14 +1231,14 @@ GridMapEditor::GridMapEditor() { mode_thumbnail->set_toggle_mode(true); mode_thumbnail->set_pressed(true); hb->add_child(mode_thumbnail); - mode_thumbnail->connect("pressed", callable_mp(this, &GridMapEditor::_set_display_mode), varray(DISPLAY_THUMBNAIL)); + mode_thumbnail->connect("pressed", callable_mp(this, &GridMapEditor::_set_display_mode).bind(DISPLAY_THUMBNAIL)); mode_list = memnew(Button); mode_list->set_flat(true); mode_list->set_toggle_mode(true); mode_list->set_pressed(false); hb->add_child(mode_list); - mode_list->connect("pressed", callable_mp(this, &GridMapEditor::_set_display_mode), varray(DISPLAY_LIST)); + mode_list->connect("pressed", callable_mp(this, &GridMapEditor::_set_display_mode).bind(DISPLAY_LIST)); size_slider = memnew(HSlider); size_slider->set_h_size_flags(SIZE_EXPAND_FILL); diff --git a/modules/hdr/SCsub b/modules/hdr/SCsub index a709397c9a..10629bda3c 100644 --- a/modules/hdr/SCsub +++ b/modules/hdr/SCsub @@ -5,5 +5,5 @@ Import("env_modules") env_hdr = env_modules.Clone() -# Godot's own source files +# Godot source files env_hdr.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h index 88860ad0d4..bf6b4399ca 100644 --- a/modules/lightmapper_rd/lightmapper_rd.h +++ b/modules/lightmapper_rd/lightmapper_rd.h @@ -183,7 +183,7 @@ class LightmapperRD : public Lightmapper { } }; - void _plot_triangle_into_triangle_index_list(int p_size, const Vector3i &p_ofs, const AABB &p_bounds, const Vector3 p_points[], uint32_t p_triangle_index, LocalVector<TriangleSort> &triangles, uint32_t p_grid_size); + void _plot_triangle_into_triangle_index_list(int p_size, const Vector3i &p_ofs, const AABB &p_bounds, const Vector3 p_points[3], uint32_t p_triangle_index, LocalVector<TriangleSort> &triangles, uint32_t p_grid_size); struct RasterPushConstant { float atlas_size[2] = {}; diff --git a/modules/minimp3/SCsub b/modules/minimp3/SCsub index f4d1605d55..20e3165f38 100644 --- a/modules/minimp3/SCsub +++ b/modules/minimp3/SCsub @@ -13,5 +13,5 @@ if not env.msvc: else: env_minimp3.Prepend(CPPPATH=[thirdparty_dir]) -# Godot's own source files +# Godot source files env_minimp3.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/minimp3/resource_importer_mp3.cpp b/modules/minimp3/resource_importer_mp3.cpp index 8526aeef38..7492533094 100644 --- a/modules/minimp3/resource_importer_mp3.cpp +++ b/modules/minimp3/resource_importer_mp3.cpp @@ -128,7 +128,7 @@ Error ResourceImporterMP3::import(const String &p_source_file, const String &p_s mp3_stream->set_beat_count(beat_count); mp3_stream->set_bar_beats(bar_beats); - return ResourceSaver::save(p_save_path + ".mp3str", mp3_stream); + return ResourceSaver::save(mp3_stream, p_save_path + ".mp3str"); } ResourceImporterMP3::ResourceImporterMP3() { diff --git a/modules/mono/config.py b/modules/mono/config.py index 3e6584590c..d895d2d92d 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -5,52 +5,44 @@ def can_build(env, platform): return not env["arch"].startswith("rv") -def configure(env): - platform = env["platform"] - - if platform not in supported_platforms: - raise RuntimeError("This module does not currently support building for this platform") - - env.add_module_version_string("mono") - - from SCons.Script import BoolVariable, PathVariable, Variables, Help +def get_opts(platform): + from SCons.Variables import BoolVariable, PathVariable default_mono_static = platform in ["ios", "javascript"] default_mono_bundles_zlib = platform in ["javascript"] - envvars = Variables() - envvars.Add( + return [ PathVariable( "mono_prefix", "Path to the Mono installation directory for the target platform and architecture", "", PathVariable.PathAccept, - ) - ) - envvars.Add( + ), PathVariable( "mono_bcl", "Path to a custom Mono BCL (Base Class Library) directory for the target platform", "", PathVariable.PathAccept, - ) - ) - envvars.Add(BoolVariable("mono_static", "Statically link Mono", default_mono_static)) - envvars.Add(BoolVariable("mono_glue", "Build with the Mono glue sources", True)) - envvars.Add(BoolVariable("build_cil", "Build C# solutions", True)) - envvars.Add( - BoolVariable("copy_mono_root", "Make a copy of the Mono installation directory to bundle with the editor", True) - ) - - # TODO: It would be great if this could be detected automatically instead - envvars.Add( + ), + BoolVariable("mono_static", "Statically link Mono", default_mono_static), + BoolVariable("mono_glue", "Build with the Mono glue sources", True), + BoolVariable("build_cil", "Build C# solutions", True), + BoolVariable( + "copy_mono_root", "Make a copy of the Mono installation directory to bundle with the editor", True + ), BoolVariable( "mono_bundles_zlib", "Specify if the Mono runtime was built with bundled zlib", default_mono_bundles_zlib - ) - ) + ), + ] + + +def configure(env): + platform = env["platform"] - envvars.Update(env) - Help(envvars.GenerateHelpText(env)) + if platform not in supported_platforms: + raise RuntimeError("This module does not currently support building for this platform") + + env.add_module_version_string("mono") if env["mono_bundles_zlib"]: # Mono may come with zlib bundled for WASM or on newer version when built with MinGW. diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 1e4d82ca30..475b483d6c 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1801,9 +1801,7 @@ void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName, void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const { List<PropertyInfo> props; - for (const KeyValue<StringName, PropertyInfo> &E : script->member_info) { - props.push_front(E.value); - } + script->get_script_property_list(&props); // Call _get_property_list @@ -2141,8 +2139,8 @@ bool CSharpInstance::refcount_decremented() { return ref_dying; } -const Vector<Multiplayer::RPCConfig> CSharpInstance::get_rpc_methods() const { - return script->get_rpc_methods(); +const Variant CSharpInstance::get_rpc_config() const { + return script->get_rpc_config(); } void CSharpInstance::notification(int p_notification) { @@ -2335,10 +2333,6 @@ void CSharpScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) #ifdef TOOLS_ENABLED void CSharpScript::_update_exports_values(HashMap<StringName, Variant> &values, List<PropertyInfo> &propnames) { - if (base_cache.is_valid()) { - base_cache->_update_exports_values(values, propnames); - } - for (const KeyValue<StringName, Variant> &E : exported_members_defval_cache) { values[E.key] = E.value; } @@ -2346,6 +2340,10 @@ void CSharpScript::_update_exports_values(HashMap<StringName, Variant> &values, for (const PropertyInfo &prop_info : exported_members_cache) { propnames.push_back(prop_info); } + + if (base_cache.is_valid()) { + base_cache->_update_exports_values(values, propnames); + } } void CSharpScript::_update_member_info_no_exports() { @@ -2357,6 +2355,7 @@ void CSharpScript::_update_member_info_no_exports() { member_info.clear(); GDMonoClass *top = script_class; + List<PropertyInfo> props; while (top && top != native) { PropertyInfo prop_info; @@ -2371,7 +2370,7 @@ void CSharpScript::_update_member_info_no_exports() { StringName member_name = field->get_name(); member_info[member_name] = prop_info; - exported_members_cache.push_front(prop_info); + props.push_front(prop_info); exported_members_defval_cache[member_name] = Variant(); } } @@ -2385,11 +2384,18 @@ void CSharpScript::_update_member_info_no_exports() { StringName member_name = property->get_name(); member_info[member_name] = prop_info; - exported_members_cache.push_front(prop_info); + props.push_front(prop_info); exported_members_defval_cache[member_name] = Variant(); } } + exported_members_cache.push_back(PropertyInfo(Variant::NIL, top->get_name(), PROPERTY_HINT_NONE, get_path(), PROPERTY_USAGE_CATEGORY)); + for (const PropertyInfo &E : props) { + exported_members_cache.push_back(E); + } + + props.clear(); + top = top->get_parent_class(); } } @@ -2464,6 +2470,7 @@ bool CSharpScript::_update_exports(PlaceHolderScriptInstance *p_instance_to_upda #endif GDMonoClass *top = script_class; + List<PropertyInfo> props; while (top && top != native) { PropertyInfo prop_info; @@ -2482,7 +2489,7 @@ bool CSharpScript::_update_exports(PlaceHolderScriptInstance *p_instance_to_upda if (exported) { #ifdef TOOLS_ENABLED if (is_editor) { - exported_members_cache.push_front(prop_info); + props.push_front(prop_info); if (tmp_object) { exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(field->get_value(tmp_object)); @@ -2510,7 +2517,7 @@ bool CSharpScript::_update_exports(PlaceHolderScriptInstance *p_instance_to_upda if (exported) { #ifdef TOOLS_ENABLED if (is_editor) { - exported_members_cache.push_front(prop_info); + props.push_front(prop_info); if (tmp_object) { MonoException *exc = nullptr; MonoObject *ret = property->get_value(tmp_object, &exc); @@ -2531,6 +2538,16 @@ bool CSharpScript::_update_exports(PlaceHolderScriptInstance *p_instance_to_upda } } +#ifdef TOOLS_ENABLED + exported_members_cache.push_back(PropertyInfo(Variant::NIL, top->get_name(), PROPERTY_HINT_NONE, get_path(), PROPERTY_USAGE_CATEGORY)); + + for (const PropertyInfo &E : props) { + exported_members_cache.push_back(E); + } + + props.clear(); +#endif // TOOLS_ENABLED + top = top->get_parent_class(); } @@ -3060,7 +3077,7 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { p_script->script_class->fetch_methods_with_godot_api_checks(p_script->native); - p_script->rpc_functions.clear(); + p_script->rpc_config.clear(); GDMonoClass *top = p_script->script_class; while (top && top != p_script->native) { @@ -3072,12 +3089,9 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { Vector<GDMonoMethod *> methods = top->get_all_methods(); for (int i = 0; i < methods.size(); i++) { if (!methods[i]->is_static()) { - Multiplayer::RPCConfig rpc_config = p_script->_member_get_rpc_config(methods[i]); - if (rpc_config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) { - // RPC annotations can only be used once per method - if (p_script->rpc_functions.find(rpc_config) == -1) { - p_script->rpc_functions.push_back(rpc_config); - } + const Variant rpc_config = p_script->_member_get_rpc_config(methods[i]); + if (rpc_config.get_type() != Variant::NIL) { + p_script->rpc_config[methods[i]->get_name()] = rpc_config; } } } @@ -3086,9 +3100,6 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { top = top->get_parent_class(); } - // Sort so we are 100% that they are always the same. - p_script->rpc_functions.sort_custom<Multiplayer::SortRPCConfig>(); - p_script->load_script_signals(p_script->script_class, p_script->native); } @@ -3497,9 +3508,15 @@ Ref<Script> CSharpScript::get_base_script() const { void CSharpScript::get_script_property_list(List<PropertyInfo> *r_list) const { List<PropertyInfo> props; +#ifdef TOOLS_ENABLED + for (const PropertyInfo &E : exported_members_cache) { + props.push_back(E); + } +#else for (const KeyValue<StringName, PropertyInfo> &E : member_info) { props.push_front(E.value); } +#endif // TOOLS_ENABLED for (const PropertyInfo &prop : props) { r_list->push_back(prop); @@ -3511,23 +3528,24 @@ int CSharpScript::get_member_line(const StringName &p_member) const { return -1; } -Multiplayer::RPCConfig CSharpScript::_member_get_rpc_config(IMonoClassMember *p_member) const { - Multiplayer::RPCConfig rpc_config; +Variant CSharpScript::_member_get_rpc_config(IMonoClassMember *p_member) const { + Variant out; MonoObject *rpc_attribute = p_member->get_attribute(CACHED_CLASS(RPCAttribute)); if (rpc_attribute != nullptr) { - rpc_config.name = p_member->get_name(); - rpc_config.rpc_mode = (Multiplayer::RPCMode)CACHED_PROPERTY(RPCAttribute, Mode)->get_int_value(rpc_attribute); - rpc_config.call_local = CACHED_PROPERTY(RPCAttribute, CallLocal)->get_bool_value(rpc_attribute); - rpc_config.transfer_mode = (Multiplayer::TransferMode)CACHED_PROPERTY(RPCAttribute, TransferMode)->get_int_value(rpc_attribute); - rpc_config.channel = CACHED_PROPERTY(RPCAttribute, TransferChannel)->get_int_value(rpc_attribute); + Dictionary rpc_config; + rpc_config["rpc_mode"] = CACHED_PROPERTY(RPCAttribute, Mode)->get_int_value(rpc_attribute); + rpc_config["call_local"] = CACHED_PROPERTY(RPCAttribute, CallLocal)->get_bool_value(rpc_attribute); + rpc_config["transfer_mode"] = CACHED_PROPERTY(RPCAttribute, TransferMode)->get_int_value(rpc_attribute); + rpc_config["channel"] = CACHED_PROPERTY(RPCAttribute, TransferChannel)->get_int_value(rpc_attribute); + out = rpc_config; } - return rpc_config; + return out; } -const Vector<Multiplayer::RPCConfig> CSharpScript::get_rpc_methods() const { - return rpc_functions; +const Variant CSharpScript::get_rpc_config() const { + return rpc_config; } Error CSharpScript::load_source_code(const String &p_path) { @@ -3635,7 +3653,7 @@ String ResourceFormatLoaderCSharpScript::get_resource_type(const String &p_path) return p_path.get_extension().to_lower() == "cs" ? CSharpLanguage::get_singleton()->get_type() : ""; } -Error ResourceFormatSaverCSharpScript::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverCSharpScript::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { Ref<CSharpScript> sqscr = p_resource; ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER); diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index b17473470f..48129e69cb 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -136,7 +136,7 @@ private: HashMap<StringName, EventSignal> event_signals; bool signals_invalidated = true; - Vector<Multiplayer::RPCConfig> rpc_functions; + Dictionary rpc_config; #ifdef TOOLS_ENABLED List<PropertyInfo> exported_members_cache; // members_cache @@ -179,7 +179,7 @@ private: static void update_script_class_info(Ref<CSharpScript> p_script); static void initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native); - Multiplayer::RPCConfig _member_get_rpc_config(IMonoClassMember *p_member) const; + Variant _member_get_rpc_config(IMonoClassMember *p_member) const; protected: static void _bind_methods(); @@ -234,7 +234,7 @@ public: int get_member_line(const StringName &p_member) const override; - const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override; + const Variant get_rpc_config() const override; #ifdef TOOLS_ENABLED bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; } @@ -311,7 +311,7 @@ public: void refcount_incremented() override; bool refcount_decremented() override; - const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override; + const Variant get_rpc_config() const override; void notification(int p_notification) override; void _call_notification(int p_notification); @@ -543,7 +543,7 @@ public: class ResourceFormatSaverCSharpScript : public ResourceFormatSaver { public: - Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0) override; + Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0) override; void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const override; bool recognize(const Ref<Resource> &p_resource) const override; }; diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs index ac29efb716..3440eb701c 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs @@ -66,6 +66,9 @@ namespace GodotTools.Ides.Rider if (string.IsNullOrEmpty(path)) return false; + if (path.IndexOfAny(Path.GetInvalidPathChars()) != -1) + return false; + var fileInfo = new FileInfo(path); string filename = fileInfo.Name.ToLowerInvariant(); return filename.StartsWith("rider", StringComparison.Ordinal); diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp index a1789412f4..7bce6f2c21 100644 --- a/modules/mono/editor/code_completion.cpp +++ b/modules/mono/editor/code_completion.cpp @@ -172,7 +172,7 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr } } break; case CompletionKind::SHADER_PARAMS: { - print_verbose("Shared params completion for C# not implemented."); + print_verbose("Shader uniforms completion for C# is not implemented yet."); } break; case CompletionKind::SIGNALS: { Ref<Script> script = ResourceLoader::load(p_script_file.simplify_path()); diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index 5e4fe90553..f830c7ffe1 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -39,7 +39,9 @@ #include "core/version.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/plugins/script_editor_plugin.h" #include "main/main.h" @@ -189,7 +191,7 @@ MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_c } MonoString *godot_icall_Internal_FullExportTemplatesDir() { - String full_templates_dir = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG); + String full_templates_dir = EditorPaths::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG); return GDMonoMarshal::mono_string_from_godot(full_templates_dir); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs index 0a1c8322d7..fb37838ffa 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs @@ -5,8 +5,8 @@ namespace Godot /// <summary> /// Attribute that changes the RPC mode for the annotated <c>method</c> to the given <see cref="Mode"/>, /// optionally specifying the <see cref="TransferMode"/> and <see cref="TransferChannel"/> (on supported peers). - /// See <see cref="RPCMode"/> and <see cref="TransferMode"/>. By default, methods are not exposed to networking - /// (and RPCs). + /// See <see cref="MultiplayerAPI.RPCMode"/> and <see cref="MultiplayerPeer.TransferModeEnum"/>. + /// By default, methods are not exposed to networking (and RPCs). /// </summary> [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class RPCAttribute : Attribute @@ -14,7 +14,7 @@ namespace Godot /// <summary> /// RPC mode for the annotated method. /// </summary> - public RPCMode Mode { get; } = RPCMode.Disabled; + public MultiplayerAPI.RPCMode Mode { get; } = MultiplayerAPI.RPCMode.Disabled; /// <summary> /// If the method will also be called locally; otherwise, it is only called remotely. @@ -24,7 +24,7 @@ namespace Godot /// <summary> /// Transfer mode for the annotated method. /// </summary> - public TransferMode TransferMode { get; set; } = TransferMode.Reliable; + public MultiplayerPeer.TransferModeEnum TransferMode { get; set; } = MultiplayerPeer.TransferModeEnum.Reliable; /// <summary> /// Transfer channel for the annotated mode. @@ -35,7 +35,7 @@ namespace Godot /// Constructs a <see cref="RPCAttribute"/> instance. /// </summary> /// <param name="mode">The RPC mode to use.</param> - public RPCAttribute(RPCMode mode = RPCMode.Authority) + public RPCAttribute(MultiplayerAPI.RPCMode mode = MultiplayerAPI.RPCMode.Authority) { Mode = mode; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index 37bdc42c2d..437878818c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -531,9 +531,9 @@ namespace Godot /// <param name="axis">The axis to rotate around. Must be normalized.</param> /// <param name="angle">The angle to rotate, in radians.</param> /// <returns>The rotated basis matrix.</returns> - public Basis Rotated(Vector3 axis, real_t phi) + public Basis Rotated(Vector3 axis, real_t angle) { - return new Basis(axis, phi) * this; + return new Basis(axis, angle) * this; } /// <summary> @@ -774,15 +774,15 @@ namespace Godot /// </summary> /// <param name="axis">The axis to rotate around. Must be normalized.</param> /// <param name="angle">The angle to rotate, in radians.</param> - public Basis(Vector3 axis, real_t phi) + public Basis(Vector3 axis, real_t angle) { Vector3 axisSq = new Vector3(axis.x * axis.x, axis.y * axis.y, axis.z * axis.z); - real_t cosine = Mathf.Cos(phi); + real_t cosine = Mathf.Cos(angle); Row0.x = axisSq.x + cosine * (1.0f - axisSq.x); Row1.y = axisSq.y + cosine * (1.0f - axisSq.y); Row2.z = axisSq.z + cosine * (1.0f - axisSq.z); - real_t sine = Mathf.Sin(phi); + real_t sine = Mathf.Sin(angle); real_t t = 1.0f - cosine; real_t xyzt = axis.x * axis.y * t; @@ -828,6 +828,22 @@ namespace Godot } /// <summary> + /// Constructs a pure scale basis matrix with no rotation or shearing. + /// The scale values are set as the main diagonal of the matrix, + /// and all of the other parts of the matrix are zero. + /// </summary> + /// <param name="scale">The scale Vector3.</param> + /// <returns>A pure scale Basis matrix.</returns> + public static Basis FromScale(Vector3 scale) + { + return new Basis( + scale.x, 0, 0, + 0, scale.y, 0, + 0, 0, scale.z + ); + } + + /// <summary> /// Composes these two basis matrices by multiplying them /// together. This has the effect of transforming the second basis /// (the child) by the first basis (the parent). diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index fc9d40ca48..a6324504fc 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -916,7 +916,7 @@ namespace Godot /// <c>new Color(1 - c.r, 1 - c.g, 1 - c.b, 1 - c.a)</c>. /// </summary> /// <param name="color">The color to invert.</param> - /// <returns>The inverted color</returns> + /// <returns>The inverted color.</returns> public static Color operator -(Color color) { return Colors.White - color; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs index bb076a9633..236d0666bc 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs @@ -239,11 +239,20 @@ namespace Godot } /// <summary> - /// Converts one or more arguments of any type to string in the best way possible and prints them to the console. The following BBCode tags are supported: b, i, u, s, indent, code, url, center, right, color, bgcolor, fgcolor. Color tags only support named colors such as [code]red[/code], [i]not[/i] hexadecimal color codes. Unsupported tags will be left as-is in standard output. - /// When printing to standard output, the supported subset of BBCode is converted to ANSI escape codes for the terminal emulator to display. Displaying ANSI escape codes is currently only supported on Linux and macOS. Support for ANSI escape codes may vary across terminal emulators, especially for italic and strikethrough. + /// Converts one or more arguments of any type to string in the best way possible + /// and prints them to the console. + /// The following BBCode tags are supported: b, i, u, s, indent, code, url, center, + /// right, color, bgcolor, fgcolor. + /// Color tags only support named colors such as <c>red</c>, not hexadecimal color codes. + /// Unsupported tags will be left as-is in standard output. + /// When printing to standard output, the supported subset of BBCode is converted to + /// ANSI escape codes for the terminal emulator to display. Displaying ANSI escape codes + /// is currently only supported on Linux and macOS. Support for ANSI escape codes may vary + /// across terminal emulators, especially for italic and strikethrough. /// /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/> - /// to print error and warning messages instead of <see cref="Print(object[])"/> or <see cref="PrintRich(object[])"/>. + /// to print error and warning messages instead of <see cref="Print(object[])"/> or + /// <see cref="PrintRich(object[])"/>. /// This distinguishes them from print messages used for debugging purposes, /// while also displaying a stack trace when an error or warning is printed. /// </summary> @@ -253,7 +262,6 @@ namespace Godot /// </code> /// </example> /// <param name="what">Arguments that will be printed.</param> - /// </summary> public static void PrintRich(params object[] what) { godot_icall_GD_print_rich(GetPrintParams(what)); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs new file mode 100644 index 0000000000..d774021131 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs @@ -0,0 +1,820 @@ +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif +using System; +using System.Runtime.InteropServices; + +namespace Godot +{ + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Projection : IEquatable<Projection> + { + /// <summary> + /// Enumerated index values for the planes. + /// </summary> + public enum Planes + { + /// <summary> + /// The projection's near plane. + /// </summary> + Near, + /// <summary> + /// The projection's far plane. + /// </summary> + Far, + /// <summary> + /// The projection's left plane. + /// </summary> + Left, + /// <summary> + /// The projection's top plane. + /// </summary> + Top, + /// <summary> + /// The projection's right plane. + /// </summary> + Right, + /// <summary> + /// The projection's bottom plane. + /// </summary> + Bottom, + } + + /// <summary> + /// The projections's X column. Also accessible by using the index position <c>[0]</c>. + /// </summary> + public Vector4 x; + + /// <summary> + /// The projections's Y column. Also accessible by using the index position <c>[1]</c>. + /// </summary> + public Vector4 y; + + /// <summary> + /// The projections's Z column. Also accessible by using the index position <c>[2]</c>. + /// </summary> + public Vector4 z; + + /// <summary> + /// The projections's W column. Also accessible by using the index position <c>[3]</c>. + /// </summary> + public Vector4 w; + + /// <summary> + /// Constructs a projection from 4 vectors (matrix columns). + /// </summary> + /// <param name="x">The X column, or column index 0.</param> + /// <param name="y">The Y column, or column index 1.</param> + /// <param name="z">The Z column, or column index 2.</param> + /// <param name="w">The W column, or column index 3.</param> + public Projection(Vector4 x, Vector4 y, Vector4 z, Vector4 w) + { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /// <summary> + /// Constructs a new <see cref="Projection"/> from an existing <see cref="Projection"/>. + /// </summary> + /// <param name="proj">The existing <see cref="Projection"/>.</param> + public Projection(Projection proj) + { + x = proj.x; + y = proj.y; + z = proj.z; + w = proj.w; + } + + /// <summary> + /// Constructs a new <see cref="Projection"/> from a <see cref="Transform3D"/>. + /// </summary> + /// <param name="transform">The <see cref="Transform3D"/>.</param> + public Projection(Transform3D transform) + { + x = new Vector4(transform.basis.Row0.x, transform.basis.Row1.x, transform.basis.Row2.x, 0); + y = new Vector4(transform.basis.Row0.y, transform.basis.Row1.y, transform.basis.Row2.y, 0); + z = new Vector4(transform.basis.Row0.z, transform.basis.Row1.z, transform.basis.Row2.z, 0); + w = new Vector4(transform.origin.x, transform.origin.y, transform.origin.z, 1); + } + + /// <summary> + /// Constructs a new <see cref="Transform3D"/> from the <see cref="Projection"/>. + /// </summary> + /// <param name="proj">The <see cref="Projection"/>.</param> + public static explicit operator Transform3D(Projection proj) + { + return new Transform3D( + new Basis( + new Vector3(proj.x.x, proj.x.y, proj.x.z), + new Vector3(proj.y.x, proj.y.y, proj.y.z), + new Vector3(proj.z.x, proj.z.y, proj.z.z) + ), + new Vector3(proj.w.x, proj.w.y, proj.w.z) + ); + } + + public static Projection CreateDepthCorrection(bool flipY) + { + return new Projection( + new Vector4(1, 0, 0, 0), + new Vector4(0, flipY ? -1 : 1, 0, 0), + new Vector4(0, 0, (real_t)0.5, 0), + new Vector4(0, 0, (real_t)0.5, 1) + ); + } + + public static Projection CreateFitAabb(AABB aabb) + { + Vector3 min = aabb.Position; + Vector3 max = aabb.Position + aabb.Size; + + return new Projection( + new Vector4(2 / (max.x - min.x), 0, 0, 0), + new Vector4(0, 2 / (max.y - min.y), 0, 0), + new Vector4(0, 0, 2 / (max.z - min.z), 0), + new Vector4(-(max.x + min.x) / (max.x - min.x), -(max.y + min.y) / (max.y - min.y), -(max.z + min.z) / (max.z - min.z), 1) + ); + } + + public static Projection CreateForHmd(int eye, real_t aspect, real_t intraocularDist, real_t displayWidth, real_t displayToLens, real_t oversample, real_t zNear, real_t zFar) + { + real_t f1 = (intraocularDist * (real_t)0.5) / displayToLens; + real_t f2 = ((displayWidth - intraocularDist) * (real_t)0.5) / displayToLens; + real_t f3 = (displayWidth / (real_t)4.0) / displayToLens; + + real_t add = ((f1 + f2) * (oversample - (real_t)1.0)) / (real_t)2.0; + f1 += add; + f2 += add; + f3 *= oversample; + + f3 /= aspect; + + switch (eye) + { + case 1: + return CreateFrustum(-f2 * zNear, f1 * zNear, -f3 * zNear, f3 * zNear, zNear, zFar); + case 2: + return CreateFrustum(-f1 * zNear, f2 * zNear, -f3 * zNear, f3 * zNear, zNear, zFar); + default: + return Zero; + } + } + + public static Projection CreateFrustum(real_t left, real_t right, real_t bottom, real_t top, real_t near, real_t far) + { + if (right <= left) + { + throw new ArgumentException("right is less or equal to left."); + } + if (top <= bottom) + { + throw new ArgumentException("top is less or equal to bottom."); + } + if (far <= near) + { + throw new ArgumentException("far is less or equal to near."); + } + + real_t x = 2 * near / (right - left); + real_t y = 2 * near / (top - bottom); + + real_t a = (right + left) / (right - left); + real_t b = (top + bottom) / (top - bottom); + real_t c = -(far + near) / (far - near); + real_t d = -2 * far * near / (far - near); + + return new Projection( + new Vector4(x, 0, 0, 0), + new Vector4(0, y, 0, 0), + new Vector4(a, b, c, -1), + new Vector4(0, 0, d, 0) + ); + } + + public static Projection CreateFrustumAspect(real_t size, real_t aspect, Vector2 offset, real_t near, real_t far, bool flipFov) + { + if (!flipFov) + { + size *= aspect; + } + return CreateFrustum(-size / 2 + offset.x, +size / 2 + offset.x, -size / aspect / 2 + offset.y, +size / aspect / 2 + offset.y, near, far); + } + + public static Projection CreateLightAtlasRect(Rect2 rect) + { + return new Projection( + new Vector4(rect.Size.x, 0, 0, 0), + new Vector4(0, rect.Size.y, 0, 0), + new Vector4(0, 0, 1, 0), + new Vector4(rect.Position.x, rect.Position.y, 0, 1) + ); + } + + public static Projection CreateOrthogonal(real_t left, real_t right, real_t bottom, real_t top, real_t zNear, real_t zFar) + { + Projection proj = Projection.Identity; + proj.x.x = (real_t)2.0 / (right - left); + proj.w.x = -((right + left) / (right - left)); + proj.y.y = (real_t)2.0 / (top - bottom); + proj.w.y = -((top + bottom) / (top - bottom)); + proj.z.z = (real_t)(-2.0) / (zFar - zNear); + proj.w.z = -((zFar + zNear) / (zFar - zNear)); + proj.w.w = (real_t)1.0; + return proj; + } + + public static Projection CreateOrthogonalAspect(real_t size, real_t aspect, real_t zNear, real_t zFar, bool flipFov) + { + if (!flipFov) + { + size *= aspect; + } + return CreateOrthogonal(-size / 2, +size / 2, -size / aspect / 2, +size / aspect / 2, zNear, zFar); + } + + public static Projection CreatePerspective(real_t fovyDegrees, real_t aspect, real_t zNear, real_t zFar, bool flipFov) + { + if (flipFov) + { + fovyDegrees = GetFovy(fovyDegrees, (real_t)1.0 / aspect); + } + real_t radians = Mathf.Deg2Rad(fovyDegrees / (real_t)2.0); + real_t deltaZ = zFar - zNear; + real_t sine = Mathf.Sin(radians); + + if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) + { + return Zero; + } + + real_t cotangent = Mathf.Cos(radians) / sine; + + Projection proj = Projection.Identity; + + proj.x.x = cotangent / aspect; + proj.y.y = cotangent; + proj.z.z = -(zFar + zNear) / deltaZ; + proj.z.w = -1; + proj.w.z = -2 * zNear * zFar / deltaZ; + proj.w.w = 0; + + return proj; + } + + public static Projection CreatePerspectiveHmd(real_t fovyDegrees, real_t aspect, real_t zNear, real_t zFar, bool flipFov, int eye, real_t intraocularDist, real_t convergenceDist) + { + if (flipFov) + { + fovyDegrees = GetFovy(fovyDegrees, (real_t)1.0 / aspect); + } + + real_t ymax = zNear * Mathf.Tan(Mathf.Deg2Rad(fovyDegrees / (real_t)2.0)); + real_t xmax = ymax * aspect; + real_t frustumshift = (intraocularDist / (real_t)2.0) * zNear / convergenceDist; + real_t left; + real_t right; + real_t modeltranslation; + switch (eye) + { + case 1: + left = -xmax + frustumshift; + right = xmax + frustumshift; + modeltranslation = intraocularDist / (real_t)2.0; + break; + case 2: + left = -xmax - frustumshift; + right = xmax - frustumshift; + modeltranslation = -intraocularDist / (real_t)2.0; + break; + default: + left = -xmax; + right = xmax; + modeltranslation = (real_t)0.0; + break; + } + Projection proj = CreateFrustum(left, right, -ymax, ymax, zNear, zFar); + Projection cm = Projection.Identity; + cm.w.x = modeltranslation; + return proj * cm; + } + + public real_t Determinant() + { + return x.w * y.z * z.y * w.x - x.z * y.w * z.y * w.x - + x.w * y.y * z.z * w.x + x.y * y.w * z.z * w.x + + x.z * y.y * z.w * w.x - x.y * y.z * z.w * w.x - + x.w * y.z * z.x * w.y + x.z * y.w * z.x * w.y + + x.w * y.x * z.z * w.y - x.x * y.w * z.z * w.y - + x.z * y.x * z.w * w.y + x.x * y.z * z.w * w.y + + x.w * y.y * z.x * w.z - x.y * y.w * z.x * w.z - + x.w * y.x * z.y * w.z + x.x * y.w * z.y * w.z + + x.y * y.x * z.w * w.z - x.x * y.y * z.w * w.z - + x.z * y.y * z.x * w.w + x.y * y.z * z.x * w.w + + x.z * y.x * z.y * w.w - x.x * y.z * z.y * w.w - + x.y * y.x * z.z * w.w + x.x * y.y * z.z * w.w; + } + + public real_t GetAspect() + { + Vector2 vpHe = GetViewportHalfExtents(); + return vpHe.x / vpHe.y; + } + + public real_t GetFov() + { + Plane rightPlane = new Plane(x.w - x.x, y.w - y.x, z.w - z.x, -w.w + w.x).Normalized(); + if (z.x == 0 && z.y == 0) + { + return Mathf.Rad2Deg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.x))) * (real_t)2.0; + } + else + { + Plane leftPlane = new Plane(x.w + x.x, y.w + y.x, z.w + z.x, w.w + w.x).Normalized(); + return Mathf.Rad2Deg(Mathf.Acos(Mathf.Abs(leftPlane.Normal.x))) + Mathf.Rad2Deg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.x))); + } + } + + public static real_t GetFovy(real_t fovx, real_t aspect) + { + return Mathf.Rad2Deg(Mathf.Atan(aspect * Mathf.Tan(Mathf.Deg2Rad(fovx) * (real_t)0.5)) * (real_t)2.0); + } + + public real_t GetLodMultiplier() + { + if (IsOrthogonal()) + { + return GetViewportHalfExtents().x; + } + else + { + real_t zn = GetZNear(); + real_t width = GetViewportHalfExtents().x * (real_t)2.0; + return (real_t)1.0 / (zn / width); + } + } + + public int GetPixelsPerMeter(int forPixelWidth) + { + Vector3 result = Xform(new Vector3(1, 0, -1)); + + return (int)((result.x * (real_t)0.5 + (real_t)0.5) * forPixelWidth); + } + + public Plane GetProjectionPlane(Planes plane) + { + Plane newPlane = plane switch + { + Planes.Near => new Plane(x.w + x.z, y.w + y.z, z.w + z.z, w.w + w.z), + Planes.Far => new Plane(x.w - x.z, y.w - y.z, z.w - z.z, w.w - w.z), + Planes.Left => new Plane(x.w + x.x, y.w + y.x, z.w + z.x, w.w + w.x), + Planes.Top => new Plane(x.w - x.y, y.w - y.y, z.w - z.y, w.w - w.y), + Planes.Right => new Plane(x.w - x.x, y.w - y.x, z.w - z.x, w.w - w.x), + Planes.Bottom => new Plane(x.w + x.y, y.w + y.y, z.w + z.y, w.w + w.y), + _ => new Plane(), + }; + newPlane.Normal = -newPlane.Normal; + return newPlane.Normalized(); + } + + public Vector2 GetFarPlaneHalfExtents() + { + var res = GetProjectionPlane(Planes.Far).Intersect3(GetProjectionPlane(Planes.Right), GetProjectionPlane(Planes.Top)); + return new Vector2(res.Value.x, res.Value.y); + } + + public Vector2 GetViewportHalfExtents() + { + var res = GetProjectionPlane(Planes.Near).Intersect3(GetProjectionPlane(Planes.Right), GetProjectionPlane(Planes.Top)); + return new Vector2(res.Value.x, res.Value.y); + } + + public real_t GetZFar() + { + return GetProjectionPlane(Planes.Far).D; + } + + public real_t GetZNear() + { + return -GetProjectionPlane(Planes.Near).D; + } + + public Projection FlippedY() + { + Projection proj = this; + proj.y = -proj.y; + return proj; + } + + public Projection PerspectiveZNearAdjusted(real_t newZNear) + { + Projection proj = this; + real_t zFar = GetZFar(); + real_t zNear = newZNear; + real_t deltaZ = zFar - zNear; + proj.z.z = -(zFar + zNear) / deltaZ; + proj.w.z = -2 * zNear * zFar / deltaZ; + return proj; + } + + public Projection JitterOffseted(Vector2 offset) + { + Projection proj = this; + proj.w.x += offset.x; + proj.w.y += offset.y; + return proj; + } + + public Projection Inverse() + { + Projection proj = this; + int i, j, k; + int[] pvt_i = new int[4]; + int[] pvt_j = new int[4]; /* Locations of pivot matrix */ + real_t pvt_val; /* Value of current pivot element */ + real_t hold; /* Temporary storage */ + real_t determinant = 1.0f; + for (k = 0; k < 4; k++) + { + /* Locate k'th pivot element */ + pvt_val = proj[k][k]; /* Initialize for search */ + pvt_i[k] = k; + pvt_j[k] = k; + for (i = k; i < 4; i++) + { + for (j = k; j < 4; j++) + { + if (Mathf.Abs(proj[i][j]) > Mathf.Abs(pvt_val)) + { + pvt_i[k] = i; + pvt_j[k] = j; + pvt_val = proj[i][j]; + } + } + } + + /* Product of pivots, gives determinant when finished */ + determinant *= pvt_val; + if (Mathf.IsZeroApprox(determinant)) + { + return Zero; + } + + /* "Interchange" rows (with sign change stuff) */ + i = pvt_i[k]; + if (i != k) + { /* If rows are different */ + for (j = 0; j < 4; j++) + { + hold = -proj[k][j]; + proj[k, j] = proj[i][j]; + proj[i, j] = hold; + } + } + + /* "Interchange" columns */ + j = pvt_j[k]; + if (j != k) + { /* If columns are different */ + for (i = 0; i < 4; i++) + { + hold = -proj[i][k]; + proj[i, k] = proj[i][j]; + proj[i, j] = hold; + } + } + + /* Divide column by minus pivot value */ + for (i = 0; i < 4; i++) + { + if (i != k) + { + proj[i, k] /= (-pvt_val); + } + } + + /* Reduce the matrix */ + for (i = 0; i < 4; i++) + { + hold = proj[i][k]; + for (j = 0; j < 4; j++) + { + if (i != k && j != k) + { + proj[i, j] += hold * proj[k][j]; + } + } + } + + /* Divide row by pivot */ + for (j = 0; j < 4; j++) + { + if (j != k) + { + proj[k, j] /= pvt_val; + } + } + + /* Replace pivot by reciprocal (at last we can touch it). */ + proj[k, k] = (real_t)1.0 / pvt_val; + } + + /* That was most of the work, one final pass of row/column interchange */ + /* to finish */ + for (k = 4 - 2; k >= 0; k--) + { /* Don't need to work with 1 by 1 corner*/ + i = pvt_j[k]; /* Rows to swap correspond to pivot COLUMN */ + if (i != k) + { /* If rows are different */ + for (j = 0; j < 4; j++) + { + hold = proj[k][j]; + proj[k, j] = -proj[i][j]; + proj[i, j] = hold; + } + } + + j = pvt_i[k]; /* Columns to swap correspond to pivot ROW */ + if (j != k) + { /* If columns are different */ + for (i = 0; i < 4; i++) + { + hold = proj[i][k]; + proj[i, k] = -proj[i][j]; + proj[i, j] = hold; + } + } + } + return proj; + } + + public bool IsOrthogonal() + { + return w.w == (real_t)1.0; + } + + /// <summary> + /// Composes these two projections by multiplying them + /// together. This has the effect of applying the right + /// and then the left projection. + /// </summary> + /// <param name="left">The parent transform.</param> + /// <param name="right">The child transform.</param> + /// <returns>The composed projection.</returns> + public static Projection operator *(Projection left, Projection right) + { + return new Projection( + new Vector4( + left.x.x * right.x.x + left.y.x * right.x.y + left.z.x * right.x.z + left.w.x * right.x.w, + left.x.y * right.x.x + left.y.y * right.x.y + left.z.y * right.x.z + left.w.y * right.x.w, + left.x.z * right.x.x + left.y.z * right.x.y + left.z.z * right.x.z + left.w.z * right.x.w, + left.x.w * right.x.x + left.y.w * right.x.y + left.z.w * right.x.z + left.w.w * right.x.w + ), new Vector4( + left.x.x * right.y.x + left.y.x * right.y.y + left.z.x * right.y.z + left.w.x * right.y.w, + left.x.y * right.y.x + left.y.y * right.y.y + left.z.y * right.y.z + left.w.y * right.y.w, + left.x.z * right.y.x + left.y.z * right.y.y + left.z.z * right.y.z + left.w.z * right.y.w, + left.x.w * right.y.x + left.y.w * right.y.y + left.z.w * right.y.z + left.w.w * right.y.w + ), new Vector4( + left.x.x * right.z.x + left.y.x * right.z.y + left.z.x * right.z.z + left.w.x * right.z.w, + left.x.y * right.z.x + left.y.y * right.z.y + left.z.y * right.z.z + left.w.y * right.z.w, + left.x.z * right.z.x + left.y.z * right.z.y + left.z.z * right.z.z + left.w.z * right.z.w, + left.x.w * right.z.x + left.y.w * right.z.y + left.z.w * right.z.z + left.w.w * right.z.w + ), new Vector4( + left.x.x * right.w.x + left.y.x * right.w.y + left.z.x * right.w.z + left.w.x * right.w.w, + left.x.y * right.w.x + left.y.y * right.w.y + left.z.y * right.w.z + left.w.y * right.w.w, + left.x.z * right.w.x + left.y.z * right.w.y + left.z.z * right.w.z + left.w.z * right.w.w, + left.x.w * right.w.x + left.y.w * right.w.y + left.z.w * right.w.z + left.w.w * right.w.w + ) + ); + } + + /// <summary> + /// Returns a vector transformed (multiplied) by this projection. + /// </summary> + /// <param name="proj">The projection to apply.</param> + /// <param name="v">A vector to transform.</param> + /// <returns>The transformed vector.</returns> + public static Vector4 operator *(Projection proj, Vector4 v) + { + return new Vector4( + proj.x.x * v.x + proj.y.x * v.y + proj.z.x * v.z + proj.w.x * v.w, + proj.x.y * v.x + proj.y.y * v.y + proj.z.y * v.z + proj.w.y * v.w, + proj.x.z * v.x + proj.y.z * v.y + proj.z.z * v.z + proj.w.z * v.w, + proj.x.w * v.x + proj.y.w * v.y + proj.z.w * v.z + proj.w.w * v.w + ); + } + + /// <summary> + /// Returns <see langword="true"/> if the projections are exactly equal. + /// </summary> + /// <param name="left">The left projection.</param> + /// <param name="right">The right projection.</param> + /// <returns>Whether or not the projections are exactly equal.</returns> + public static bool operator ==(Projection left, Projection right) + { + return left.Equals(right); + } + + /// <summary> + /// Returns <see langword="true"/> if the projections are not exactly equal. + /// </summary> + /// <param name="left">The left projection.</param> + /// <param name="right">The right projection.</param> + /// <returns>Whether or not the projections are not exactly equal.</returns> + public static bool operator !=(Projection left, Projection right) + { + return !left.Equals(right); + } + + /// <summary> + /// Access whole columns in the form of <see cref="Vector4"/>. + /// </summary> + /// <param name="column">Which column vector.</param> + public Vector4 this[int column] + { + get + { + switch (column) + { + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + default: + throw new IndexOutOfRangeException(); + } + } + set + { + switch (column) + { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + case 3: + w = value; + return; + default: + throw new IndexOutOfRangeException(); + } + } + } + + /// <summary> + /// Access single values. + /// </summary> + /// <param name="column">Which column vector.</param> + /// <param name="row">Which row of the column.</param> + public real_t this[int column, int row] + { + get + { + switch (column) + { + case 0: + return x[row]; + case 1: + return y[row]; + case 2: + return z[row]; + case 3: + return w[row]; + default: + throw new IndexOutOfRangeException(); + } + } + set + { + switch (column) + { + case 0: + x[row] = value; + return; + case 1: + y[row] = value; + return; + case 2: + z[row] = value; + return; + case 3: + w[row] = value; + return; + default: + throw new IndexOutOfRangeException(); + } + } + } + + /// <summary> + /// Returns a vector transformed (multiplied) by this projection. + /// </summary> + /// <param name="v">A vector to transform.</param> + /// <returns>The transformed vector.</returns> + private Vector3 Xform(Vector3 v) + { + Vector3 ret = new Vector3( + x.x * v.x + y.x * v.y + z.x * v.z + w.x, + x.y * v.x + y.y * v.y + z.y * v.z + w.y, + x.z * v.x + y.z * v.y + z.z * v.z + w.z + ); + return ret / (x.w * v.x + y.w * v.y + z.w * v.z + w.w); + } + + // Constants + private static readonly Projection _zero = new Projection( + new Vector4(0, 0, 0, 0), + new Vector4(0, 0, 0, 0), + new Vector4(0, 0, 0, 0), + new Vector4(0, 0, 0, 0) + ); + private static readonly Projection _identity = new Projection( + new Vector4(1, 0, 0, 0), + new Vector4(0, 1, 0, 0), + new Vector4(0, 0, 1, 0), + new Vector4(0, 0, 0, 1) + ); + + /// <summary> + /// Zero projection, a projection with all components set to <c>0</c>. + /// </summary> + /// <value>Equivalent to <c>new Projection(Vector4.Zero, Vector4.Zero, Vector4.Zero, Vector4.Zero)</c>.</value> + public static Projection Zero { get { return _zero; } } + + /// <summary> + /// The identity projection, with no distortion applied. + /// This is used as a replacement for <c>Projection()</c> in GDScript. + /// Do not use <c>new Projection()</c> with no arguments in C#, because it sets all values to zero. + /// </summary> + /// <value>Equivalent to <c>new Projection(new Vector4(1, 0, 0, 0), new Vector4(0, 1, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(0, 0, 0, 1))</c>.</value> + public static Projection Identity { get { return _identity; } } + + /// <summary> + /// Serves as the hash function for <see cref="Projection"/>. + /// </summary> + /// <returns>A hash code for this projection.</returns> + public override int GetHashCode() + { + return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode(); + } + + /// <summary> + /// Converts this <see cref="Projection"/> to a string. + /// </summary> + /// <returns>A string representation of this projection.</returns> + public override string ToString() + { + return $"{x.x}, {x.y}, {x.z}, {x.w}\n{y.x}, {y.y}, {y.z}, {y.w}\n{z.x}, {z.y}, {z.z}, {z.w}\n{w.x}, {w.y}, {w.z}, {w.w}\n"; + } + + /// <summary> + /// Converts this <see cref="Projection"/> to a string with the given <paramref name="format"/>. + /// </summary> + /// <returns>A string representation of this projection.</returns> + public string ToString(string format) + { + return $"{x.x.ToString(format)}, {x.y.ToString(format)}, {x.z.ToString(format)}, {x.w.ToString(format)}\n" + + $"{y.x.ToString(format)}, {y.y.ToString(format)}, {y.z.ToString(format)}, {y.w.ToString(format)}\n" + + $"{z.x.ToString(format)}, {z.y.ToString(format)}, {z.z.ToString(format)}, {z.w.ToString(format)}\n" + + $"{w.x.ToString(format)}, {w.y.ToString(format)}, {w.z.ToString(format)}, {w.w.ToString(format)}\n"; + } + + /// <summary> + /// Returns <see langword="true"/> if the projection is exactly equal + /// to the given object (<see paramref="obj"/>). + /// </summary> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the vector and the object are equal.</returns> + public override bool Equals(object obj) + { + if (obj is Projection) + { + return Equals((Projection)obj); + } + return false; + } + + /// <summary> + /// Returns <see langword="true"/> if the projections are exactly equal. + /// </summary> + /// <param name="other">The other projection.</param> + /// <returns>Whether or not the projections are exactly equal.</returns> + public bool Equals(Projection other) + { + return x == other.x && y == other.y && z == other.z && w == other.w; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs index 5680c9d55a..da01300586 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs @@ -18,7 +18,7 @@ namespace Godot public StringName Name => _signalName; /// <summary> - /// Creates a new <see cref="Signal"/> with the name <paramref name="name"/> + /// Creates a new <see cref="SignalInfo"/> with the name <paramref name="name"/> /// in the specified <paramref name="owner"/>. /// </summary> /// <param name="owner">Object that contains the signal.</param> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index 89947899cb..68d097eb4e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -297,17 +297,33 @@ namespace Godot } /// <summary> - /// Rotates the transform by <paramref name="angle"/> (in radians), using matrix multiplication. + /// Rotates the transform by <paramref name="angle"/> (in radians). + /// The operation is done in the parent/global frame, equivalent to + /// multiplying the matrix from the left. /// </summary> /// <param name="angle">The angle to rotate, in radians.</param> /// <returns>The rotated transformation matrix.</returns> - public Transform2D Rotated(real_t phi) + public Transform2D Rotated(real_t angle) { - return this * new Transform2D(phi, new Vector2()); + return this * new Transform2D(angle, new Vector2()); } /// <summary> - /// Scales the transform by the given scaling factor, using matrix multiplication. + /// Rotates the transform by <paramref name="angle"/> (in radians). + /// The operation is done in the local frame, equivalent to + /// multiplying the matrix from the right. + /// </summary> + /// <param name="angle">The angle to rotate, in radians.</param> + /// <returns>The rotated transformation matrix.</returns> + public Transform2D RotatedLocal(real_t angle) + { + return new Transform2D(angle, new Vector2()) * this; + } + + /// <summary> + /// Scales the transform by the given scaling factor. + /// The operation is done in the parent/global frame, equivalent to + /// multiplying the matrix from the left. /// </summary> /// <param name="scale">The scale to introduce.</param> /// <returns>The scaled transformation matrix.</returns> @@ -320,12 +336,19 @@ namespace Godot return copy; } - private void ScaleBasis(Vector2 scale) + /// <summary> + /// Scales the transform by the given scaling factor. + /// The operation is done in the local frame, equivalent to + /// multiplying the matrix from the right. + /// </summary> + /// <param name="scale">The scale to introduce.</param> + /// <returns>The scaled transformation matrix.</returns> + public Transform2D ScaledLocal(Vector2 scale) { - x.x *= scale.x; - x.y *= scale.y; - y.x *= scale.x; - y.y *= scale.y; + Transform2D copy = this; + copy.x *= scale; + copy.y *= scale; + return copy; } private real_t Tdotx(Vector2 with) @@ -339,17 +362,29 @@ namespace Godot } /// <summary> - /// Translates the transform by the given <paramref name="offset"/>, - /// relative to the transform's basis vectors. - /// - /// Unlike <see cref="Rotated"/> and <see cref="Scaled"/>, - /// this does not use matrix multiplication. + /// Translates the transform by the given <paramref name="offset"/>. + /// The operation is done in the parent/global frame, equivalent to + /// multiplying the matrix from the left. /// </summary> /// <param name="offset">The offset to translate by.</param> /// <returns>The translated matrix.</returns> public Transform2D Translated(Vector2 offset) { Transform2D copy = this; + copy.origin += offset; + return copy; + } + + /// <summary> + /// Translates the transform by the given <paramref name="offset"/>. + /// The operation is done in the local frame, equivalent to + /// multiplying the matrix from the right. + /// </summary> + /// <param name="offset">The offset to translate by.</param> + /// <returns>The translated matrix.</returns> + public Transform2D TranslatedLocal(Vector2 offset) + { + Transform2D copy = this; copy.origin += copy.BasisXform(offset); return copy; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs index 7b211b6577..9eaf4f3252 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs @@ -186,19 +186,38 @@ namespace Godot } /// <summary> - /// Rotates the transform around the given <paramref name="axis"/> by <paramref name="angle"/> (in radians), - /// using matrix multiplication. The axis must be a normalized vector. + /// Rotates the transform around the given <paramref name="axis"/> by <paramref name="angle"/> (in radians). + /// The axis must be a normalized vector. + /// The operation is done in the parent/global frame, equivalent to + /// multiplying the matrix from the left. /// </summary> /// <param name="axis">The axis to rotate around. Must be normalized.</param> /// <param name="angle">The angle to rotate, in radians.</param> /// <returns>The rotated transformation matrix.</returns> - public Transform3D Rotated(Vector3 axis, real_t phi) + public Transform3D Rotated(Vector3 axis, real_t angle) { - return new Transform3D(new Basis(axis, phi), new Vector3()) * this; + return new Transform3D(new Basis(axis, angle), new Vector3()) * this; } /// <summary> - /// Scales the transform by the given 3D scaling factor, using matrix multiplication. + /// Rotates the transform around the given <paramref name="axis"/> by <paramref name="angle"/> (in radians). + /// The axis must be a normalized vector. + /// The operation is done in the local frame, equivalent to + /// multiplying the matrix from the right. + /// </summary> + /// <param name="axis">The axis to rotate around. Must be normalized.</param> + /// <param name="angle">The angle to rotate, in radians.</param> + /// <returns>The rotated transformation matrix.</returns> + public Transform3D RotatedLocal(Vector3 axis, real_t angle) + { + Basis tmpBasis = new Basis(axis, angle); + return new Transform3D(basis * tmpBasis, origin); + } + + /// <summary> + /// Scales the transform by the given 3D <paramref name="scale"/> factor. + /// The operation is done in the parent/global frame, equivalent to + /// multiplying the matrix from the left. /// </summary> /// <param name="scale">The scale to introduce.</param> /// <returns>The scaled transformation matrix.</returns> @@ -207,6 +226,19 @@ namespace Godot return new Transform3D(basis.Scaled(scale), origin * scale); } + /// <summary> + /// Scales the transform by the given 3D <paramref name="scale"/> factor. + /// The operation is done in the local frame, equivalent to + /// multiplying the matrix from the right. + /// </summary> + /// <param name="scale">The scale to introduce.</param> + /// <returns>The scaled transformation matrix.</returns> + public Transform3D ScaledLocal(Vector3 scale) + { + Basis tmpBasis = Basis.FromScale(scale); + return new Transform3D(basis * tmpBasis, origin); + } + private void SetLookAt(Vector3 eye, Vector3 target, Vector3 up) { // Make rotation matrix @@ -231,21 +263,31 @@ namespace Godot } /// <summary> - /// Translates the transform by the given <paramref name="offset"/>, - /// relative to the transform's basis vectors. - /// - /// Unlike <see cref="Rotated"/> and <see cref="Scaled"/>, - /// this does not use matrix multiplication. + /// Translates the transform by the given <paramref name="offset"/>. + /// The operation is done in the parent/global frame, equivalent to + /// multiplying the matrix from the left. /// </summary> /// <param name="offset">The offset to translate by.</param> /// <returns>The translated matrix.</returns> public Transform3D Translated(Vector3 offset) { + return new Transform3D(basis, origin + offset); + } + + /// <summary> + /// Translates the transform by the given <paramref name="offset"/>. + /// The operation is done in the local frame, equivalent to + /// multiplying the matrix from the right. + /// </summary> + /// <param name="offset">The offset to translate by.</param> + /// <returns>The translated matrix.</returns> + public Transform3D TranslatedLocal(Vector3 offset) + { return new Transform3D(basis, new Vector3 ( - origin[0] += basis.Row0.Dot(offset), - origin[1] += basis.Row1.Dot(offset), - origin[2] += basis.Row2.Dot(offset) + origin[0] + basis.Row0.Dot(offset), + origin[1] + basis.Row1.Dot(offset), + origin[2] + basis.Row2.Dot(offset) )); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index 7bdbe1c28b..67f70390dd 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -495,10 +495,10 @@ namespace Godot /// </summary> /// <param name="angle">The angle to rotate by, in radians.</param> /// <returns>The rotated vector.</returns> - public Vector2 Rotated(real_t phi) + public Vector2 Rotated(real_t angle) { - real_t sine = Mathf.Sin(phi); - real_t cosi = Mathf.Cos(phi); + real_t sine = Mathf.Sin(angle); + real_t cosi = Mathf.Cos(angle); return new Vector2( x * cosi - y * sine, x * sine + y * cosi); @@ -534,7 +534,7 @@ namespace Godot /// /// This method also handles interpolating the lengths if the input vectors /// have different lengths. For the special case of one or both input vectors - /// having zero length, this method behaves like <see cref="Lerp"/>. + /// having zero length, this method behaves like <see cref="Lerp(Vector2, real_t)"/>. /// </summary> /// <param name="to">The destination vector for interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 480165d44a..67a98efc2d 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -515,7 +515,7 @@ namespace Godot /// <param name="axis">The vector to rotate around. Must be normalized.</param> /// <param name="angle">The angle to rotate by, in radians.</param> /// <returns>The rotated vector.</returns> - public Vector3 Rotated(Vector3 axis, real_t phi) + public Vector3 Rotated(Vector3 axis, real_t angle) { #if DEBUG if (!axis.IsNormalized()) @@ -523,7 +523,7 @@ namespace Godot throw new ArgumentException("Argument is not normalized", nameof(axis)); } #endif - return new Basis(axis, phi).Xform(this); + return new Basis(axis, angle).Xform(this); } /// <summary> @@ -574,7 +574,7 @@ namespace Godot /// /// This method also handles interpolating the lengths if the input vectors /// have different lengths. For the special case of one or both input vectors - /// having zero length, this method behaves like <see cref="Lerp"/>. + /// having zero length, this method behaves like <see cref="Lerp(Vector3, real_t)"/>. /// </summary> /// <param name="to">The destination vector for interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> @@ -620,22 +620,6 @@ namespace Godot ); } - /// <summary> - /// Returns a diagonal matrix with the vector as main diagonal. - /// - /// This is equivalent to a <see cref="Basis"/> with no rotation or shearing and - /// this vector's components set as the scale. - /// </summary> - /// <returns>A <see cref="Basis"/> with the vector as its main diagonal.</returns> - public Basis ToDiagonalMatrix() - { - return new Basis( - x, 0, 0, - 0, y, 0, - 0, 0, z - ); - } - // Constants private static readonly Vector3 _zero = new Vector3(0, 0, 0); private static readonly Vector3 _one = new Vector3(1, 1, 1); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs new file mode 100644 index 0000000000..72fe9cb16f --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs @@ -0,0 +1,730 @@ +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif +using System; +using System.Runtime.InteropServices; + +namespace Godot +{ + /// <summary> + /// 4-element structure that can be used to represent positions in 4D space or any other pair of numeric values. + /// </summary> + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Vector4 : IEquatable<Vector4> + { + /// <summary> + /// Enumerated index values for the axes. + /// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>. + /// </summary> + public enum Axis + { + /// <summary> + /// The vector's X axis. + /// </summary> + X = 0, + /// <summary> + /// The vector's Y axis. + /// </summary> + Y, + /// <summary> + /// The vector's Z axis. + /// </summary> + Z, + /// <summary> + /// The vector's W axis. + /// </summary> + W + } + + /// <summary> + /// The vector's X component. Also accessible by using the index position <c>[0]</c>. + /// </summary> + public real_t x; + + /// <summary> + /// The vector's Y component. Also accessible by using the index position <c>[1]</c>. + /// </summary> + public real_t y; + + /// <summary> + /// The vector's Z component. Also accessible by using the index position <c>[2]</c>. + /// </summary> + public real_t z; + + /// <summary> + /// The vector's W component. Also accessible by using the index position <c>[3]</c>. + /// </summary> + public real_t w; + + /// <summary> + /// Access vector components using their index. + /// </summary> + /// <exception cref="IndexOutOfRangeException"> + /// Thrown when the given the <paramref name="index"/> is not 0, 1, 2 or 3. + /// </exception> + /// <value> + /// <c>[0]</c> is equivalent to <see cref="x"/>, + /// <c>[1]</c> is equivalent to <see cref="y"/>, + /// <c>[2]</c> is equivalent to <see cref="z"/>. + /// <c>[3]</c> is equivalent to <see cref="w"/>. + /// </value> + public real_t this[int index] + { + get + { + switch (index) + { + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + default: + throw new IndexOutOfRangeException(); + } + } + set + { + switch (index) + { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + case 3: + w = value; + return; + default: + throw new IndexOutOfRangeException(); + } + } + } + + /// <summary> + /// Helper method for deconstruction into a tuple. + /// </summary> + public void Deconstruct(out real_t x, out real_t y, out real_t z, out real_t w) + { + x = this.x; + y = this.y; + z = this.z; + w = this.w; + } + + internal void Normalize() + { + real_t lengthsq = LengthSquared(); + + if (lengthsq == 0) + { + x = y = z = w = 0f; + } + else + { + real_t length = Mathf.Sqrt(lengthsq); + x /= length; + y /= length; + z /= length; + w /= length; + } + } + + + /// <summary> + /// Returns a new vector with all components in absolute values (i.e. positive). + /// </summary> + /// <returns>A vector with <see cref="Mathf.Abs(real_t)"/> called on each component.</returns> + public Vector4 Abs() + { + return new Vector4(Mathf.Abs(x), Mathf.Abs(y), Mathf.Abs(z), Mathf.Abs(w)); + } + + /// <summary> + /// Returns a new vector with all components rounded up (towards positive infinity). + /// </summary> + /// <returns>A vector with <see cref="Mathf.Ceil"/> called on each component.</returns> + public Vector4 Ceil() + { + return new Vector4(Mathf.Ceil(x), Mathf.Ceil(y), Mathf.Ceil(z), Mathf.Ceil(w)); + } + + /// <summary> + /// Returns a new vector with all components clamped between the + /// components of <paramref name="min"/> and <paramref name="max"/> using + /// <see cref="Mathf.Clamp(real_t, real_t, real_t)"/>. + /// </summary> + /// <param name="min">The vector with minimum allowed values.</param> + /// <param name="max">The vector with maximum allowed values.</param> + /// <returns>The vector with all components clamped.</returns> + public Vector4 Clamp(Vector4 min, Vector4 max) + { + return new Vector4 + ( + Mathf.Clamp(x, min.x, max.x), + Mathf.Clamp(y, min.y, max.y), + Mathf.Clamp(z, min.z, max.z), + Mathf.Clamp(w, min.w, max.w) + ); + } + + + /// <summary> + /// Returns a new vector with all components rounded down (towards negative infinity). + /// </summary> + /// <returns>A vector with <see cref="Mathf.Floor"/> called on each component.</returns> + public Vector4 Floor() + { + return new Vector4(Mathf.Floor(x), Mathf.Floor(y), Mathf.Floor(z), Mathf.Floor(w)); + } + + + /// <summary> + /// Returns the dot product of this vector and <paramref name="with"/>. + /// </summary> + /// <param name="with">The other vector to use.</param> + /// <returns>The dot product of the two vectors.</returns> + public real_t Dot(Vector4 with) + { + return (x * with.x) + (y * with.y) + (z * with.z) + (w + with.w); + } + + /// <summary> + /// Returns the inverse of this vector. This is the same as <c>new Vector4(1 / v.x, 1 / v.y, 1 / v.z, 1 / v.w)</c>. + /// </summary> + /// <returns>The inverse of this vector.</returns> + public Vector4 Inverse() + { + return new Vector4(1 / x, 1 / y, 1 / z, 1 / w); + } + + /// <summary> + /// Returns <see langword="true"/> if the vector is normalized, and <see langword="false"/> otherwise. + /// </summary> + /// <returns>A <see langword="bool"/> indicating whether or not the vector is normalized.</returns> + public bool IsNormalized() + { + return Mathf.Abs(LengthSquared() - 1.0f) < Mathf.Epsilon; + } + + /// <summary> + /// Returns the length (magnitude) of this vector. + /// </summary> + /// <seealso cref="LengthSquared"/> + /// <returns>The length of this vector.</returns> + public real_t Length() + { + real_t x2 = x * x; + real_t y2 = y * y; + real_t z2 = z * z; + real_t w2 = w * w; + + return Mathf.Sqrt(x2 + y2 + z2 + w2); + } + + /// <summary> + /// Returns the squared length (squared magnitude) of this vector. + /// This method runs faster than <see cref="Length"/>, so prefer it if + /// you need to compare vectors or need the squared length for some formula. + /// </summary> + /// <returns>The squared length of this vector.</returns> + public real_t LengthSquared() + { + real_t x2 = x * x; + real_t y2 = y * y; + real_t z2 = z * z; + real_t w2 = w * w; + + return x2 + y2 + z2 + w2; + } + + /// <summary> + /// Returns the result of the linear interpolation between + /// this vector and <paramref name="to"/> by amount <paramref name="weight"/>. + /// </summary> + /// <param name="to">The destination vector for interpolation.</param> + /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <returns>The resulting vector of the interpolation.</returns> + public Vector4 Lerp(Vector4 to, real_t weight) + { + return new Vector4 + ( + Mathf.Lerp(x, to.x, weight), + Mathf.Lerp(y, to.y, weight), + Mathf.Lerp(z, to.z, weight), + Mathf.Lerp(w, to.w, weight) + ); + } + + /// <summary> + /// Returns the axis of the vector's highest value. See <see cref="Axis"/>. + /// If all components are equal, this method returns <see cref="Axis.X"/>. + /// </summary> + /// <returns>The index of the highest axis.</returns> + public Axis MaxAxisIndex() + { + int max_index = 0; + real_t max_value = x; + for (int i = 1; i < 4; i++) + { + if (this[i] > max_value) + { + max_index = i; + max_value = this[i]; + } + } + return (Axis)max_index; + } + + /// <summary> + /// Returns the axis of the vector's lowest value. See <see cref="Axis"/>. + /// If all components are equal, this method returns <see cref="Axis.W"/>. + /// </summary> + /// <returns>The index of the lowest axis.</returns> + public Axis MinAxisIndex() + { + int min_index = 0; + real_t min_value = x; + for (int i = 1; i < 4; i++) + { + if (this[i] <= min_value) + { + min_index = i; + min_value = this[i]; + } + } + return (Axis)min_index; + } + + /// <summary> + /// Returns the vector scaled to unit length. Equivalent to <c>v / v.Length()</c>. + /// </summary> + /// <returns>A normalized version of the vector.</returns> + public Vector4 Normalized() + { + Vector4 v = this; + v.Normalize(); + return v; + } + + /// <summary> + /// Returns this vector with all components rounded to the nearest integer, + /// with halfway cases rounded towards the nearest multiple of two. + /// </summary> + /// <returns>The rounded vector.</returns> + public Vector4 Round() + { + return new Vector4(Mathf.Round(x), Mathf.Round(y), Mathf.Round(z), Mathf.Round(w)); + } + + /// <summary> + /// Returns a vector with each component set to one or negative one, depending + /// on the signs of this vector's components, or zero if the component is zero, + /// by calling <see cref="Mathf.Sign(real_t)"/> on each component. + /// </summary> + /// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns> + public Vector4 Sign() + { + Vector4 v; + v.x = Mathf.Sign(x); + v.y = Mathf.Sign(y); + v.z = Mathf.Sign(z); + v.w = Mathf.Sign(w); + return v; + } + + // Constants + private static readonly Vector4 _zero = new Vector4(0, 0, 0, 0); + private static readonly Vector4 _one = new Vector4(1, 1, 1, 1); + private static readonly Vector4 _inf = new Vector4(Mathf.Inf, Mathf.Inf, Mathf.Inf, Mathf.Inf); + + /// <summary> + /// Zero vector, a vector with all components set to <c>0</c>. + /// </summary> + /// <value>Equivalent to <c>new Vector4(0, 0, 0, 0)</c>.</value> + public static Vector4 Zero { get { return _zero; } } + /// <summary> + /// One vector, a vector with all components set to <c>1</c>. + /// </summary> + /// <value>Equivalent to <c>new Vector4(1, 1, 1, 1)</c>.</value> + public static Vector4 One { get { return _one; } } + /// <summary> + /// Infinity vector, a vector with all components set to <see cref="Mathf.Inf"/>. + /// </summary> + /// <value>Equivalent to <c>new Vector4(Mathf.Inf, Mathf.Inf, Mathf.Inf, Mathf.Inf)</c>.</value> + public static Vector4 Inf { get { return _inf; } } + + /// <summary> + /// Constructs a new <see cref="Vector4"/> with the given components. + /// </summary> + /// <param name="x">The vector's X component.</param> + /// <param name="y">The vector's Y component.</param> + /// <param name="z">The vector's Z component.</param> + /// <param name="w">The vector's W component.</param> + public Vector4(real_t x, real_t y, real_t z, real_t w) + { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /// <summary> + /// Constructs a new <see cref="Vector4"/> from an existing <see cref="Vector4"/>. + /// </summary> + /// <param name="v">The existing <see cref="Vector4"/>.</param> + public Vector4(Vector4 v) + { + x = v.x; + y = v.y; + z = v.z; + w = v.w; + } + + /// <summary> + /// Adds each component of the <see cref="Vector4"/> + /// with the components of the given <see cref="Vector4"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The added vector.</returns> + public static Vector4 operator +(Vector4 left, Vector4 right) + { + left.x += right.x; + left.y += right.y; + left.z += right.z; + left.w += right.w; + return left; + } + + /// <summary> + /// Subtracts each component of the <see cref="Vector4"/> + /// by the components of the given <see cref="Vector4"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The subtracted vector.</returns> + public static Vector4 operator -(Vector4 left, Vector4 right) + { + left.x -= right.x; + left.y -= right.y; + left.z -= right.z; + left.w -= right.w; + return left; + } + + /// <summary> + /// Returns the negative value of the <see cref="Vector4"/>. + /// This is the same as writing <c>new Vector4(-v.x, -v.y, -v.z, -v.w)</c>. + /// This operation flips the direction of the vector while + /// keeping the same magnitude. + /// With floats, the number zero can be either positive or negative. + /// </summary> + /// <param name="vec">The vector to negate/flip.</param> + /// <returns>The negated/flipped vector.</returns> + public static Vector4 operator -(Vector4 vec) + { + vec.x = -vec.x; + vec.y = -vec.y; + vec.z = -vec.z; + vec.w = -vec.w; + return vec; + } + + /// <summary> + /// Multiplies each component of the <see cref="Vector4"/> + /// by the given <see cref="real_t"/>. + /// </summary> + /// <param name="vec">The vector to multiply.</param> + /// <param name="scale">The scale to multiply by.</param> + /// <returns>The multiplied vector.</returns> + public static Vector4 operator *(Vector4 vec, real_t scale) + { + vec.x *= scale; + vec.y *= scale; + vec.z *= scale; + vec.w *= scale; + return vec; + } + + /// <summary> + /// Multiplies each component of the <see cref="Vector4"/> + /// by the given <see cref="real_t"/>. + /// </summary> + /// <param name="scale">The scale to multiply by.</param> + /// <param name="vec">The vector to multiply.</param> + /// <returns>The multiplied vector.</returns> + public static Vector4 operator *(real_t scale, Vector4 vec) + { + vec.x *= scale; + vec.y *= scale; + vec.z *= scale; + vec.w *= scale; + return vec; + } + + /// <summary> + /// Multiplies each component of the <see cref="Vector4"/> + /// by the components of the given <see cref="Vector4"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The multiplied vector.</returns> + public static Vector4 operator *(Vector4 left, Vector4 right) + { + left.x *= right.x; + left.y *= right.y; + left.z *= right.z; + left.w *= right.w; + return left; + } + + /// <summary> + /// Divides each component of the <see cref="Vector4"/> + /// by the given <see cref="real_t"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The divided vector.</returns> + public static Vector4 operator /(Vector4 vec, real_t divisor) + { + vec.x /= divisor; + vec.y /= divisor; + vec.z /= divisor; + vec.w /= divisor; + return vec; + } + + /// <summary> + /// Divides each component of the <see cref="Vector4"/> + /// by the components of the given <see cref="Vector4"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The divided vector.</returns> + public static Vector4 operator /(Vector4 vec, Vector4 divisorv) + { + vec.x /= divisorv.x; + vec.y /= divisorv.y; + vec.z /= divisorv.z; + vec.w /= divisorv.w; + return vec; + } + + /// <summary> + /// Returns <see langword="true"/> if the vectors are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are exactly equal.</returns> + public static bool operator ==(Vector4 left, Vector4 right) + { + return left.Equals(right); + } + + /// <summary> + /// Returns <see langword="true"/> if the vectors are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are not equal.</returns> + public static bool operator !=(Vector4 left, Vector4 right) + { + return !left.Equals(right); + } + + /// <summary> + /// Compares two <see cref="Vector4"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y, Z and finally W values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than the right.</returns> + public static bool operator <(Vector4 left, Vector4 right) + { + if (left.x == right.x) + { + if (left.y == right.y) + { + if (left.z == right.z) + { + return left.w < right.w; + } + return left.z < right.z; + } + return left.y < right.y; + } + return left.x < right.x; + } + + /// <summary> + /// Compares two <see cref="Vector4"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y, Z and finally W values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than the right.</returns> + public static bool operator >(Vector4 left, Vector4 right) + { + if (left.x == right.x) + { + if (left.y == right.y) + { + if (left.z == right.z) + { + return left.w > right.w; + } + return left.z > right.z; + } + return left.y > right.y; + } + return left.x > right.x; + } + + /// <summary> + /// Compares two <see cref="Vector4"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y, Z and finally W values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than or equal to the right.</returns> + public static bool operator <=(Vector4 left, Vector4 right) + { + if (left.x == right.x) + { + if (left.y == right.y) + { + if (left.z == right.z) + { + return left.w <= right.w; + } + return left.z < right.z; + } + return left.y < right.y; + } + return left.x < right.x; + } + + /// <summary> + /// Compares two <see cref="Vector4"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y, Z and finally W values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than or equal to the right.</returns> + public static bool operator >=(Vector4 left, Vector4 right) + { + if (left.x == right.x) + { + if (left.y == right.y) + { + if (left.z == right.z) + { + return left.w >= right.w; + } + return left.z > right.z; + } + return left.y > right.y; + } + return left.x > right.x; + } + + /// <summary> + /// Returns <see langword="true"/> if the vector is exactly equal + /// to the given object (<see paramref="obj"/>). + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the vector and the object are equal.</returns> + public override bool Equals(object obj) + { + if (obj is Vector4) + { + return Equals((Vector4)obj); + } + + return false; + } + + /// <summary> + /// Returns <see langword="true"/> if the vectors are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="other">The other vector.</param> + /// <returns>Whether or not the vectors are exactly equal.</returns> + public bool Equals(Vector4 other) + { + return x == other.x && y == other.y && z == other.z && w == other.w; + } + + /// <summary> + /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are approximately equal, + /// by running <see cref="Mathf.IsEqualApprox(real_t, real_t)"/> on each component. + /// </summary> + /// <param name="other">The other vector to compare.</param> + /// <returns>Whether or not the vectors are approximately equal.</returns> + public bool IsEqualApprox(Vector4 other) + { + return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z) && Mathf.IsEqualApprox(w, other.w); + } + + /// <summary> + /// Serves as the hash function for <see cref="Vector4"/>. + /// </summary> + /// <returns>A hash code for this vector.</returns> + public override int GetHashCode() + { + return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode(); + } + + /// <summary> + /// Converts this <see cref="Vector4"/> to a string. + /// </summary> + /// <returns>A string representation of this vector.</returns> + public override string ToString() + { + return $"({x}, {y}, {z}, {w})"; + } + + /// <summary> + /// Converts this <see cref="Vector4"/> to a string with the given <paramref name="format"/>. + /// </summary> + /// <returns>A string representation of this vector.</returns> + public string ToString(string format) + { + return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)}, {w.ToString(format)})"; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs new file mode 100644 index 0000000000..365dcef486 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs @@ -0,0 +1,702 @@ +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif +using System; +using System.Runtime.InteropServices; + +namespace Godot +{ + /// <summary> + /// 4-element structure that can be used to represent 4D grid coordinates or sets of integers. + /// </summary> + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Vector4i : IEquatable<Vector4i> + { + /// <summary> + /// Enumerated index values for the axes. + /// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>. + /// </summary> + public enum Axis + { + /// <summary> + /// The vector's X axis. + /// </summary> + X = 0, + /// <summary> + /// The vector's Y axis. + /// </summary> + Y, + /// <summary> + /// The vector's Z axis. + /// </summary> + Z, + /// <summary> + /// The vector's W axis. + /// </summary> + W + } + + /// <summary> + /// The vector's X component. Also accessible by using the index position <c>[0]</c>. + /// </summary> + public int x; + + /// <summary> + /// The vector's Y component. Also accessible by using the index position <c>[1]</c>. + /// </summary> + public int y; + + /// <summary> + /// The vector's Z component. Also accessible by using the index position <c>[2]</c>. + /// </summary> + public int z; + + /// <summary> + /// The vector's W component. Also accessible by using the index position <c>[3]</c>. + /// </summary> + public int w; + + /// <summary> + /// Access vector components using their <paramref name="index"/>. + /// </summary> + /// <exception cref="IndexOutOfRangeException"> + /// Thrown when the given the <paramref name="index"/> is not 0, 1, 2 or 3. + /// </exception> + /// <value> + /// <c>[0]</c> is equivalent to <see cref="x"/>, + /// <c>[1]</c> is equivalent to <see cref="y"/>, + /// <c>[2]</c> is equivalent to <see cref="z"/>. + /// <c>[3]</c> is equivalent to <see cref="w"/>. + /// </value> + public int this[int index] + { + get + { + switch (index) + { + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + default: + throw new IndexOutOfRangeException(); + } + } + set + { + switch (index) + { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + case 3: + w = value; + return; + default: + throw new IndexOutOfRangeException(); + } + } + } + + /// <summary> + /// Helper method for deconstruction into a tuple. + /// </summary> + public void Deconstruct(out int x, out int y, out int z, out int w) + { + x = this.x; + y = this.y; + z = this.z; + w = this.w; + } + + /// <summary> + /// Returns a new vector with all components in absolute values (i.e. positive). + /// </summary> + /// <returns>A vector with <see cref="Mathf.Abs(int)"/> called on each component.</returns> + public Vector4i Abs() + { + return new Vector4i(Mathf.Abs(x), Mathf.Abs(y), Mathf.Abs(z), Mathf.Abs(w)); + } + + /// <summary> + /// Returns a new vector with all components clamped between the + /// components of <paramref name="min"/> and <paramref name="max"/> using + /// <see cref="Mathf.Clamp(int, int, int)"/>. + /// </summary> + /// <param name="min">The vector with minimum allowed values.</param> + /// <param name="max">The vector with maximum allowed values.</param> + /// <returns>The vector with all components clamped.</returns> + public Vector4i Clamp(Vector4i min, Vector4i max) + { + return new Vector4i + ( + Mathf.Clamp(x, min.x, max.x), + Mathf.Clamp(y, min.y, max.y), + Mathf.Clamp(z, min.z, max.z), + Mathf.Clamp(w, min.w, max.w) + ); + } + + /// <summary> + /// Returns the length (magnitude) of this vector. + /// </summary> + /// <seealso cref="LengthSquared"/> + /// <returns>The length of this vector.</returns> + public real_t Length() + { + int x2 = x * x; + int y2 = y * y; + int z2 = z * z; + int w2 = w * w; + + return Mathf.Sqrt(x2 + y2 + z2 + w2); + } + + /// <summary> + /// Returns the squared length (squared magnitude) of this vector. + /// This method runs faster than <see cref="Length"/>, so prefer it if + /// you need to compare vectors or need the squared length for some formula. + /// </summary> + /// <returns>The squared length of this vector.</returns> + public int LengthSquared() + { + int x2 = x * x; + int y2 = y * y; + int z2 = z * z; + int w2 = w * w; + + return x2 + y2 + z2 + w2; + } + + /// <summary> + /// Returns the axis of the vector's highest value. See <see cref="Axis"/>. + /// If all components are equal, this method returns <see cref="Axis.X"/>. + /// </summary> + /// <returns>The index of the highest axis.</returns> + public Axis MaxAxisIndex() + { + int max_index = 0; + int max_value = x; + for (int i = 1; i < 4; i++) + { + if (this[i] > max_value) + { + max_index = i; + max_value = this[i]; + } + } + return (Axis)max_index; + } + + /// <summary> + /// Returns the axis of the vector's lowest value. See <see cref="Axis"/>. + /// If all components are equal, this method returns <see cref="Axis.W"/>. + /// </summary> + /// <returns>The index of the lowest axis.</returns> + public Axis MinAxisIndex() + { + int min_index = 0; + int min_value = x; + for (int i = 1; i < 4; i++) + { + if (this[i] <= min_value) + { + min_index = i; + min_value = this[i]; + } + } + return (Axis)min_index; + } + + /// <summary> + /// Returns a vector with each component set to one or negative one, depending + /// on the signs of this vector's components, or zero if the component is zero, + /// by calling <see cref="Mathf.Sign(int)"/> on each component. + /// </summary> + /// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns> + public Vector4i Sign() + { + return new Vector4i(Mathf.Sign(x), Mathf.Sign(y), Mathf.Sign(z), Mathf.Sign(w)); + } + + // Constants + private static readonly Vector4i _zero = new Vector4i(0, 0, 0, 0); + private static readonly Vector4i _one = new Vector4i(1, 1, 1, 1); + + /// <summary> + /// Zero vector, a vector with all components set to <c>0</c>. + /// </summary> + /// <value>Equivalent to <c>new Vector4i(0, 0, 0, 0)</c>.</value> + public static Vector4i Zero { get { return _zero; } } + /// <summary> + /// One vector, a vector with all components set to <c>1</c>. + /// </summary> + /// <value>Equivalent to <c>new Vector4i(1, 1, 1, 1)</c>.</value> + public static Vector4i One { get { return _one; } } + + /// <summary> + /// Constructs a new <see cref="Vector4i"/> with the given components. + /// </summary> + /// <param name="x">The vector's X component.</param> + /// <param name="y">The vector's Y component.</param> + /// <param name="z">The vector's Z component.</param> + /// <param name="w">The vector's W component.</param> + public Vector4i(int x, int y, int z, int w) + { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /// <summary> + /// Constructs a new <see cref="Vector4i"/> from an existing <see cref="Vector4i"/>. + /// </summary> + /// <param name="vi">The existing <see cref="Vector4i"/>.</param> + public Vector4i(Vector4i vi) + { + this.x = vi.x; + this.y = vi.y; + this.z = vi.z; + this.w = vi.w; + } + + /// <summary> + /// Constructs a new <see cref="Vector4i"/> from an existing <see cref="Vector4"/> + /// by rounding the components via <see cref="Mathf.RoundToInt(real_t)"/>. + /// </summary> + /// <param name="v">The <see cref="Vector4"/> to convert.</param> + public Vector4i(Vector4 v) + { + this.x = Mathf.RoundToInt(v.x); + this.y = Mathf.RoundToInt(v.y); + this.z = Mathf.RoundToInt(v.z); + this.w = Mathf.RoundToInt(v.w); + } + + /// <summary> + /// Adds each component of the <see cref="Vector4i"/> + /// with the components of the given <see cref="Vector4i"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The added vector.</returns> + public static Vector4i operator +(Vector4i left, Vector4i right) + { + left.x += right.x; + left.y += right.y; + left.z += right.z; + left.w += right.w; + return left; + } + + /// <summary> + /// Subtracts each component of the <see cref="Vector4i"/> + /// by the components of the given <see cref="Vector4i"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The subtracted vector.</returns> + public static Vector4i operator -(Vector4i left, Vector4i right) + { + left.x -= right.x; + left.y -= right.y; + left.z -= right.z; + left.w -= right.w; + return left; + } + + /// <summary> + /// Returns the negative value of the <see cref="Vector4i"/>. + /// This is the same as writing <c>new Vector4i(-v.x, -v.y, -v.z, -v.w)</c>. + /// This operation flips the direction of the vector while + /// keeping the same magnitude. + /// </summary> + /// <param name="vec">The vector to negate/flip.</param> + /// <returns>The negated/flipped vector.</returns> + public static Vector4i operator -(Vector4i vec) + { + vec.x = -vec.x; + vec.y = -vec.y; + vec.z = -vec.z; + vec.w = -vec.w; + return vec; + } + + /// <summary> + /// Multiplies each component of the <see cref="Vector4i"/> + /// by the given <see langword="int"/>. + /// </summary> + /// <param name="vec">The vector to multiply.</param> + /// <param name="scale">The scale to multiply by.</param> + /// <returns>The multiplied vector.</returns> + public static Vector4i operator *(Vector4i vec, int scale) + { + vec.x *= scale; + vec.y *= scale; + vec.z *= scale; + vec.w *= scale; + return vec; + } + + /// <summary> + /// Multiplies each component of the <see cref="Vector4i"/> + /// by the given <see langword="int"/>. + /// </summary> + /// <param name="scale">The scale to multiply by.</param> + /// <param name="vec">The vector to multiply.</param> + /// <returns>The multiplied vector.</returns> + public static Vector4i operator *(int scale, Vector4i vec) + { + vec.x *= scale; + vec.y *= scale; + vec.z *= scale; + vec.w *= scale; + return vec; + } + + /// <summary> + /// Multiplies each component of the <see cref="Vector4i"/> + /// by the components of the given <see cref="Vector4i"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The multiplied vector.</returns> + public static Vector4i operator *(Vector4i left, Vector4i right) + { + left.x *= right.x; + left.y *= right.y; + left.z *= right.z; + left.w *= right.w; + return left; + } + + /// <summary> + /// Divides each component of the <see cref="Vector4i"/> + /// by the given <see langword="int"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The divided vector.</returns> + public static Vector4i operator /(Vector4i vec, int divisor) + { + vec.x /= divisor; + vec.y /= divisor; + vec.z /= divisor; + vec.w /= divisor; + return vec; + } + + /// <summary> + /// Divides each component of the <see cref="Vector4i"/> + /// by the components of the given <see cref="Vector4i"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The divided vector.</returns> + public static Vector4i operator /(Vector4i vec, Vector4i divisorv) + { + vec.x /= divisorv.x; + vec.y /= divisorv.y; + vec.z /= divisorv.z; + vec.w /= divisorv.w; + return vec; + } + + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector4i"/> + /// with the components of the given <see langword="int"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vecto43i(10, -20, 30, -40) % 7); // Prints "(3, -6, 2, -5)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The remainder vector.</returns> + public static Vector4i operator %(Vector4i vec, int divisor) + { + vec.x %= divisor; + vec.y %= divisor; + vec.z %= divisor; + vec.w %= divisor; + return vec; + } + + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector4i"/> + /// with the components of the given <see cref="Vector4i"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector4i(10, -20, 30, -40) % new Vector4i(6, 7, 8, 9)); // Prints "(4, -6, 6, -4)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The remainder vector.</returns> + public static Vector4i operator %(Vector4i vec, Vector4i divisorv) + { + vec.x %= divisorv.x; + vec.y %= divisorv.y; + vec.z %= divisorv.z; + vec.w %= divisorv.w; + return vec; + } + + /// <summary> + /// Performs a bitwise AND operation with this <see cref="Vector4i"/> + /// and the given <see langword="int"/>. + /// </summary> + /// <param name="vec">The vector to AND with.</param> + /// <param name="and">The integer to AND with.</param> + /// <returns>The result of the bitwise AND.</returns> + public static Vector4i operator &(Vector4i vec, int and) + { + vec.x &= and; + vec.y &= and; + vec.z &= and; + vec.w &= and; + return vec; + } + + /// <summary> + /// Performs a bitwise AND operation with this <see cref="Vector4i"/> + /// and the given <see cref="Vector4i"/>. + /// </summary> + /// <param name="vec">The left vector to AND with.</param> + /// <param name="andv">The right vector to AND with.</param> + /// <returns>The result of the bitwise AND.</returns> + public static Vector4i operator &(Vector4i vec, Vector4i andv) + { + vec.x &= andv.x; + vec.y &= andv.y; + vec.z &= andv.z; + vec.w &= andv.w; + return vec; + } + + /// <summary> + /// Returns <see langword="true"/> if the vectors are equal. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are equal.</returns> + public static bool operator ==(Vector4i left, Vector4i right) + { + return left.Equals(right); + } + + /// <summary> + /// Returns <see langword="true"/> if the vectors are not equal. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are not equal.</returns> + public static bool operator !=(Vector4i left, Vector4i right) + { + return !left.Equals(right); + } + + /// <summary> + /// Compares two <see cref="Vector4i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y, Z and finally W values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than the right.</returns> + public static bool operator <(Vector4i left, Vector4i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + { + if (left.z == right.z) + { + return left.w < right.w; + } + return left.z < right.z; + } + return left.y < right.y; + } + return left.x < right.x; + } + + /// <summary> + /// Compares two <see cref="Vector4i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y, Z and finally W values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than the right.</returns> + public static bool operator >(Vector4i left, Vector4i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + { + if (left.z == right.z) + { + return left.w > right.w; + } + return left.z > right.z; + } + return left.y > right.y; + } + return left.x > right.x; + } + + /// <summary> + /// Compares two <see cref="Vector4i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y, Z and finally W values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than or equal to the right.</returns> + public static bool operator <=(Vector4i left, Vector4i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + { + if (left.z == right.z) + { + return left.w <= right.w; + } + return left.z < right.z; + } + return left.y < right.y; + } + return left.x < right.x; + } + + /// <summary> + /// Compares two <see cref="Vector4i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y, Z and finally W values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than or equal to the right.</returns> + public static bool operator >=(Vector4i left, Vector4i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + { + if (left.z == right.z) + { + return left.w >= right.w; + } + return left.z > right.z; + } + return left.y > right.y; + } + return left.x > right.x; + } + + /// <summary> + /// Converts this <see cref="Vector4i"/> to a <see cref="Vector4"/>. + /// </summary> + /// <param name="value">The vector to convert.</param> + public static implicit operator Vector4(Vector4i value) + { + return new Vector4(value.x, value.y, value.z, value.w); + } + + /// <summary> + /// Converts a <see cref="Vector4"/> to a <see cref="Vector4i"/>. + /// </summary> + /// <param name="value">The vector to convert.</param> + public static explicit operator Vector4i(Vector4 value) + { + return new Vector4i(value); + } + + /// <summary> + /// Returns <see langword="true"/> if the vector is equal + /// to the given object (<see paramref="obj"/>). + /// </summary> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the vector and the object are equal.</returns> + public override bool Equals(object obj) + { + if (obj is Vector4i) + { + return Equals((Vector4i)obj); + } + + return false; + } + + /// <summary> + /// Returns <see langword="true"/> if the vectors are equal. + /// </summary> + /// <param name="other">The other vector.</param> + /// <returns>Whether or not the vectors are equal.</returns> + public bool Equals(Vector4i other) + { + return x == other.x && y == other.y && z == other.z && w == other.w; + } + + /// <summary> + /// Serves as the hash function for <see cref="Vector4i"/>. + /// </summary> + /// <returns>A hash code for this vector.</returns> + public override int GetHashCode() + { + return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode(); + } + + /// <summary> + /// Converts this <see cref="Vector4i"/> to a string. + /// </summary> + /// <returns>A string representation of this vector.</returns> + public override string ToString() + { + return $"({x}, {y}, {z}, {w})"; + } + + /// <summary> + /// Converts this <see cref="Vector4i"/> to a string with the given <paramref name="format"/>. + /// </summary> + /// <returns>A string representation of this vector.</returns> + public string ToString(string format) + { + return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)}), {w.ToString(format)})"; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index e59f45bbf6..4f55ce47e8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -50,6 +50,7 @@ <Compile Include="Core\NodePath.cs" /> <Compile Include="Core\Object.base.cs" /> <Compile Include="Core\Plane.cs" /> + <Compile Include="Core\Projection.cs" /> <Compile Include="Core\Quaternion.cs" /> <Compile Include="Core\Rect2.cs" /> <Compile Include="Core\Rect2i.cs" /> @@ -65,6 +66,8 @@ <Compile Include="Core\Vector2i.cs" /> <Compile Include="Core\Vector3.cs" /> <Compile Include="Core\Vector3i.cs" /> + <Compile Include="Core\Vector4.cs" /> + <Compile Include="Core\Vector4i.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> </ItemGroup> <!-- diff --git a/modules/mono/glue/callable_glue.cpp b/modules/mono/glue/callable_glue.cpp index e59b34313c..521dc3dff7 100644 --- a/modules/mono/glue/callable_glue.cpp +++ b/modules/mono/glue/callable_glue.cpp @@ -49,7 +49,7 @@ MonoObject *godot_icall_Callable_Call(GDMonoMarshal::M_Callable *p_callable, Mon Variant result; Callable::CallError error; - callable.call(args.ptr(), argc, result, error); + callable.callp(args.ptr(), argc, result, error); return GDMonoMarshal::variant_to_mono_object(result); } @@ -68,7 +68,7 @@ void godot_icall_Callable_CallDeferred(GDMonoMarshal::M_Callable *p_callable, Mo args.set(i, &arg_store.get(i)); } - callable.call_deferred(args.ptr(), argc); + callable.call_deferredp(args.ptr(), argc); } void godot_register_callable_icalls() { diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 3b6fd25d71..51f11ab18a 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -262,7 +262,7 @@ enum { offsetof(Vector4, z) == (sizeof(real_t) * 2) && offsetof(Vector4, w) == (sizeof(real_t) * 3)), - MATCHES_Vector4i = (MATCHES_int && (sizeof(Vector4i) == (sizeof(int32_t) * 4i)) && + MATCHES_Vector4i = (MATCHES_int && (sizeof(Vector4i) == (sizeof(int32_t) * 4)) && offsetof(Vector4i, x) == (sizeof(int32_t) * 0) && offsetof(Vector4i, y) == (sizeof(int32_t) * 1) && offsetof(Vector4i, z) == (sizeof(int32_t) * 2) && diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp index 618e1b58e0..437c4ca54a 100644 --- a/modules/mono/signal_awaiter_utils.cpp +++ b/modules/mono/signal_awaiter_utils.cpp @@ -44,7 +44,7 @@ Error gd_mono_connect_signal_awaiter(Object *p_source, const StringName &p_signa SignalAwaiterCallable *awaiter_callable = memnew(SignalAwaiterCallable(p_target, p_awaiter, p_signal)); Callable callable = Callable(awaiter_callable); - return p_source->connect(p_signal, callable, Vector<Variant>(), Object::CONNECT_ONESHOT); + return p_source->connect(p_signal, callable, Object::CONNECT_ONESHOT); } bool SignalAwaiterCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) { diff --git a/modules/msdfgen/SCsub b/modules/msdfgen/SCsub index 227369f4bd..0c269bc7f4 100644 --- a/modules/msdfgen/SCsub +++ b/modules/msdfgen/SCsub @@ -36,7 +36,7 @@ if env["builtin_msdfgen"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_msdfgen.Append(CPPPATH=["#thirdparty/freetype/include", "#thirdparty/msdfgen", "#thirdparty/nanosvg"]) + env_msdfgen.Prepend(CPPPATH=["#thirdparty/freetype/include", "#thirdparty/msdfgen", "#thirdparty/nanosvg"]) lib = env_msdfgen.add_library("msdfgen_builtin", thirdparty_sources) thirdparty_obj += lib diff --git a/modules/msdfgen/config.py b/modules/msdfgen/config.py index 653e466a74..631894400d 100644 --- a/modules/msdfgen/config.py +++ b/modules/msdfgen/config.py @@ -1,5 +1,6 @@ def can_build(env, platform): - return env.module_check_dependencies("msdfgen", ["freetype"]) + env.module_add_dependencies("msdfgen", ["freetype"]) + return True def configure(env): diff --git a/modules/multiplayer/SCsub b/modules/multiplayer/SCsub new file mode 100644 index 0000000000..ff33655537 --- /dev/null +++ b/modules/multiplayer/SCsub @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_mp = env_modules.Clone() + +module_obj = [] +env_mp.add_source_files(module_obj, "*.cpp") + +if env["tools"]: + env_mp.add_source_files(module_obj, "editor/*.cpp") + +env.modules_sources += module_obj diff --git a/modules/multiplayer/config.py b/modules/multiplayer/config.py new file mode 100644 index 0000000000..414bf0afcf --- /dev/null +++ b/modules/multiplayer/config.py @@ -0,0 +1,19 @@ +def can_build(env, platform): + return True + + +def configure(env): + pass + + +def get_doc_classes(): + return [ + "SceneReplicationConfig", + "SceneMultiplayer", + "MultiplayerSpawner", + "MultiplayerSynchronizer", + ] + + +def get_doc_path(): + return "doc_classes" diff --git a/modules/multiplayer/doc_classes/MultiplayerSpawner.xml b/modules/multiplayer/doc_classes/MultiplayerSpawner.xml new file mode 100644 index 0000000000..881796ed26 --- /dev/null +++ b/modules/multiplayer/doc_classes/MultiplayerSpawner.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="MultiplayerSpawner" inherits="Node" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> + <brief_description> + Automatically replicates spawnable nodes from the authority to other multiplayer peers. + </brief_description> + <description> + Spawnable scenes can be configured in the editor or through code (see [method add_spawnable_scene]). + Also supports custom node spawns through [method spawn], calling [method _spawn_custom] on all peers. + + Internally, [MultiplayerSpawner] uses [method MultiplayerAPI.object_configuration_add] to notify spawns passing the spawned node as the [code]object[/code] and itself as the [code]configuration[/code], and [method MultiplayerAPI.object_configuration_remove] to notify despawns in a similar way. + </description> + <tutorials> + </tutorials> + <methods> + <method name="_spawn_custom" qualifiers="virtual"> + <return type="Node" /> + <argument index="0" name="data" type="Variant" /> + <description> + Method called on all peers when a custom spawn was requested by the authority using [method spawn]. Should return a [Node] that is not in the scene tree. + + [b]Note:[/b] Spawned nodes should [b]not[/b] be added to the scene with `add_child`. This is done automatically. + </description> + </method> + <method name="add_spawnable_scene"> + <return type="void" /> + <argument index="0" name="path" type="String" /> + <description> + Adds a scene path to spawnable scenes, making it automatically replicated from the multiplayer authority to other peers when added as children of the node pointed by [member spawn_path]. + </description> + </method> + <method name="clear_spawnable_scenes"> + <return type="void" /> + <description> + Clears all spawnable scenes. Does not despawn existing instances on remote peers. + </description> + </method> + <method name="get_spawnable_scene" qualifiers="const"> + <return type="String" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the spawnable scene path by index. + </description> + </method> + <method name="get_spawnable_scene_count" qualifiers="const"> + <return type="int" /> + <description> + Returns the count of spawnable scene paths. + </description> + </method> + <method name="spawn"> + <return type="Node" /> + <argument index="0" name="data" type="Variant" default="null" /> + <description> + Requests a custom spawn, with [code]data[/code] passed to [method _spawn_custom] on all peers. Returns the locally spawned node instance already inside the scene tree, and added as a child of the node pointed by [member spawn_path]. + + [b]Note:[/b] Spawnable scenes are spawned automatically. [method spawn] is only needed for custom spawns. + </description> + </method> + </methods> + <members> + <member name="spawn_limit" type="int" setter="set_spawn_limit" getter="get_spawn_limit" default="0"> + Maximum nodes that is allowed to be spawned by this spawner. Includes both spawnable scenes and custom spawns. + + When set to [code]0[/code] (the default), there is no limit. + </member> + <member name="spawn_path" type="NodePath" setter="set_spawn_path" getter="get_spawn_path" default="NodePath("")"> + Path to the spawn root. Spawnable scenes that are added as direct children are replicated to other peers. + </member> + </members> + <signals> + <signal name="despawned"> + <argument index="0" name="node" type="Node" /> + <description> + Emitted when a spawnable scene or custom spawn was despawned by the multiplayer authority. Only called on puppets. + </description> + </signal> + <signal name="spawned"> + <argument index="0" name="node" type="Node" /> + <description> + Emitted when a spawnable scene or custom spawn was spawned by the multiplayer authority. Only called on puppets. + </description> + </signal> + </signals> +</class> diff --git a/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml b/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml new file mode 100644 index 0000000000..a2ea64061c --- /dev/null +++ b/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="MultiplayerSynchronizer" inherits="Node" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> + <brief_description> + Synchronizes properties from the multiplayer authority to the remote peers. + </brief_description> + <description> + By default, [MultiplayerSynchronizer] synchronizes configured properties to all peers. + Visiblity can be handled directly with [method set_visibility_for] or as-needed with [method add_visibility_filter] and [method update_visibility]. + + [MultiplayerSpawner]s will handle nodes according to visibility of synchronizers as long as the node at [member root_path] was spawned by one. + + Internally, [MultiplayerSynchronizer] uses [method MultiplayerAPI.object_configuration_add] to notify synchronization start passing the [Node] at [member root_path] as the [code]object[/code] and itself as the [code]configuration[/code], and uses [method MultiplayerAPI.object_configuration_remove] to notify synchronization end in a similar way. + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_visibility_filter"> + <return type="void" /> + <argument index="0" name="filter" type="Callable" /> + <description> + Adds a peer visibility filter for this synchronizer. + + [code]filter[/code] should take a peer id [int] and return a [bool]. + </description> + </method> + <method name="get_visibility_for" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="peer" type="int" /> + <description> + Queries the current visibility for peer [code]peer[/code]. + </description> + </method> + <method name="remove_visibility_filter"> + <return type="void" /> + <argument index="0" name="filter" type="Callable" /> + <description> + Removes a peer visiblity filter from this synchronizer. + </description> + </method> + <method name="set_visibility_for"> + <return type="void" /> + <argument index="0" name="peer" type="int" /> + <argument index="1" name="visible" type="bool" /> + <description> + Sets the visibility of [code]peer[/code] to [code]visible[/code]. If [code]peer[/code] is [code]0[/code], the value of [member public_visibility] will be updated instead. + </description> + </method> + <method name="update_visibility"> + <return type="void" /> + <argument index="0" name="for_peer" type="int" default="0" /> + <description> + Updates the visibility of [code]peer[/code] according to visibility filters. If [code]peer[/code] is [code]0[/code] (the default), all peers' visibilties are updated. + </description> + </method> + </methods> + <members> + <member name="public_visibility" type="bool" setter="set_visibility_public" getter="is_visibility_public" default="true"> + Whether synchronization should be visible to all peers by default. See [method set_visibility_for] and [method add_visibility_filter] for ways of configuring fine-grained visibility options. + </member> + <member name="replication_config" type="SceneReplicationConfig" setter="set_replication_config" getter="get_replication_config"> + Resource containing which properties to synchronize. + </member> + <member name="replication_interval" type="float" setter="set_replication_interval" getter="get_replication_interval" default="0.0"> + Time interval between synchronizes. When set to [code]0.0[/code] (the default), synchronizes happen every network process frame. + </member> + <member name="root_path" type="NodePath" setter="set_root_path" getter="get_root_path" default="NodePath("..")"> + Node path that replicated properties are relative to. + If [member root_path] was spawned by a [MultiplayerSpawner], the node will be also be spawned and despawned based on this synchronizer visibility options. + </member> + <member name="visibility_update_mode" type="int" setter="set_visibility_update_mode" getter="get_visibility_update_mode" enum="MultiplayerSynchronizer.VisibilityUpdateMode" default="0"> + Specifies when visibility filters are updated (see [enum VisibilityUpdateMode] for options). + </member> + </members> + <signals> + <signal name="visibility_changed"> + <argument index="0" name="for_peer" type="int" /> + <description> + Emitted when visibility of [code]for_peer[/code] is updated. See [method update_visibility]. + </description> + </signal> + </signals> + <constants> + <constant name="VISIBILITY_PROCESS_IDLE" value="0" enum="VisibilityUpdateMode"> + Visibility filters are updated every idle process frame. + </constant> + <constant name="VISIBILITY_PROCESS_PHYSICS" value="1" enum="VisibilityUpdateMode"> + Visibility filters are updated every physics process frame. + </constant> + <constant name="VISIBILITY_PROCESS_NONE" value="2" enum="VisibilityUpdateMode"> + Visibility filters are not updated automatically, and must be updated manually by calling [method update_visibility]. + </constant> + </constants> +</class> diff --git a/modules/multiplayer/doc_classes/SceneMultiplayer.xml b/modules/multiplayer/doc_classes/SceneMultiplayer.xml new file mode 100644 index 0000000000..0c3ed2d784 --- /dev/null +++ b/modules/multiplayer/doc_classes/SceneMultiplayer.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SceneMultiplayer" inherits="MultiplayerAPI" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> + <brief_description> + High-level multiplayer API implementation. + </brief_description> + <description> + This class is the default implementation of [MultiplayerAPI], used to provide multiplayer functionalities in Godot Engine. + This implementation supports RPCs via [method Node.rpc] and [method Node.rpc_id] and requires [method MultiplayerAPI.rpc] to be passed a [Node] (it will fail for other object types). + This implementation additionally provide [SceneTree] replication via the [MultiplayerSpawner] and [MultiplayerSynchronizer] nodes, and the [SceneReplicationConfig] resource. + [b]Note:[/b] The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice. + [b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android. + </description> + <tutorials> + </tutorials> + <methods> + <method name="clear"> + <return type="void" /> + <description> + Clears the current SceneMultiplayer network state (you shouldn't call this unless you know what you are doing). + </description> + </method> + <method name="send_bytes"> + <return type="int" enum="Error" /> + <argument index="0" name="bytes" type="PackedByteArray" /> + <argument index="1" name="id" type="int" default="0" /> + <argument index="2" name="mode" type="int" enum="MultiplayerPeer.TransferMode" default="2" /> + <argument index="3" name="channel" type="int" default="0" /> + <description> + Sends the given raw [code]bytes[/code] to a specific peer identified by [code]id[/code] (see [method MultiplayerPeer.set_target_peer]). Default ID is [code]0[/code], i.e. broadcast to all peers. + </description> + </method> + </methods> + <members> + <member name="allow_object_decoding" type="bool" setter="set_allow_object_decoding" getter="is_object_decoding_allowed" default="false"> + If [code]true[/code], the MultiplayerAPI will allow encoding and decoding of object during RPCs. + [b]Warning:[/b] Deserialized objects can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threat such as remote code execution. + </member> + <member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" default="false"> + If [code]true[/code], the MultiplayerAPI's [member MultiplayerAPI.multiplayer_peer] refuses new incoming connections. + </member> + <member name="root_path" type="NodePath" setter="set_root_path" getter="get_root_path" default="NodePath("")"> + The root path to use for RPCs and replication. Instead of an absolute path, a relative path will be used to find the node upon which the RPC should be executed. + This effectively allows to have different branches of the scene tree to be managed by different MultiplayerAPI, allowing for example to run both client and server in the same scene. + </member> + </members> + <signals> + <signal name="peer_packet"> + <argument index="0" name="id" type="int" /> + <argument index="1" name="packet" type="PackedByteArray" /> + <description> + Emitted when this MultiplayerAPI's [member MultiplayerAPI.multiplayer_peer] receives a [code]packet[/code] with custom data (see [method send_bytes]). ID is the peer ID of the peer that sent the packet. + </description> + </signal> + </signals> +</class> diff --git a/doc/classes/SceneReplicationConfig.xml b/modules/multiplayer/doc_classes/SceneReplicationConfig.xml index 62c108a477..fc91592c7a 100644 --- a/doc/classes/SceneReplicationConfig.xml +++ b/modules/multiplayer/doc_classes/SceneReplicationConfig.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SceneReplicationConfig" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="SceneReplicationConfig" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> + Configuration for properties to synchronize with a [MultiplayerSynchronizer]. </brief_description> <description> </description> @@ -12,35 +13,41 @@ <argument index="0" name="path" type="NodePath" /> <argument index="1" name="index" type="int" default="-1" /> <description> + Adds the property identified by the given [code]path[/code] to the list of the properties being synchronized, optionally passing an [code]index[/code]. </description> </method> <method name="get_properties" qualifiers="const"> <return type="NodePath[]" /> <description> + Returns a list of synchronized property [NodePath]s. </description> </method> <method name="has_property" qualifiers="const"> <return type="bool" /> <argument index="0" name="path" type="NodePath" /> <description> + Returns whether the given [code]path[/code] is configured for synchronization. </description> </method> <method name="property_get_index" qualifiers="const"> <return type="int" /> <argument index="0" name="path" type="NodePath" /> <description> + Finds the index of the given [code]path[/code]. </description> </method> <method name="property_get_spawn"> <return type="bool" /> <argument index="0" name="path" type="NodePath" /> <description> + Returns whether the property identified by the given [code]path[/code] is configured to be synchronized on spawn. </description> </method> <method name="property_get_sync"> <return type="bool" /> <argument index="0" name="path" type="NodePath" /> <description> + Returns whether the property identified by the given [code]path[/code] is configured to be synchronized on process. </description> </method> <method name="property_set_spawn"> @@ -48,6 +55,7 @@ <argument index="0" name="path" type="NodePath" /> <argument index="1" name="enabled" type="bool" /> <description> + Sets whether the property identified by the given [code]path[/code] is configured to be synchronized on spawn. </description> </method> <method name="property_set_sync"> @@ -55,12 +63,14 @@ <argument index="0" name="path" type="NodePath" /> <argument index="1" name="enabled" type="bool" /> <description> + Sets whether the property identified by the given [code]path[/code] is configured to be synchronized on process. </description> </method> <method name="remove_property"> <return type="void" /> <argument index="0" name="path" type="NodePath" /> <description> + Removes the property identified by the given [code]path[/code] from the configuration. </description> </method> </methods> diff --git a/editor/plugins/replication_editor_plugin.cpp b/modules/multiplayer/editor/replication_editor_plugin.cpp index 3e06a6739f..50f1434ad8 100644 --- a/editor/plugins/replication_editor_plugin.cpp +++ b/modules/multiplayer/editor/replication_editor_plugin.cpp @@ -32,10 +32,13 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/inspector_dock.h" +#include "editor/scene_tree_editor.h" +#include "modules/multiplayer/multiplayer_synchronizer.h" #include "scene/gui/dialogs.h" +#include "scene/gui/separator.h" #include "scene/gui/tree.h" -#include "scene/multiplayer/multiplayer_synchronizer.h" void ReplicationEditor::_pick_node_filter_text_changed(const String &p_newtext) { TreeItem *root_item = pick_node->get_scene_tree()->get_scene_tree()->get_root(); @@ -166,8 +169,8 @@ ReplicationEditor::ReplicationEditor() { set_custom_minimum_size(Size2(0, 200) * EDSCALE); delete_dialog = memnew(ConfirmationDialog); - delete_dialog->connect("cancelled", callable_mp(this, &ReplicationEditor::_dialog_closed), varray(false)); - delete_dialog->connect("confirmed", callable_mp(this, &ReplicationEditor::_dialog_closed), varray(true)); + delete_dialog->connect("cancelled", callable_mp(this, &ReplicationEditor::_dialog_closed).bind(false)); + delete_dialog->connect("confirmed", callable_mp(this, &ReplicationEditor::_dialog_closed).bind(true)); add_child(delete_dialog); error_dialog = memnew(AcceptDialog); @@ -252,8 +255,6 @@ void ReplicationEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_checked", "property", "column", "checked"), &ReplicationEditor::_update_checked); ClassDB::bind_method("_can_drop_data_fw", &ReplicationEditor::_can_drop_data_fw); ClassDB::bind_method("_drop_data_fw", &ReplicationEditor::_drop_data_fw); - - ADD_SIGNAL(MethodInfo("keying_changed")); } bool ReplicationEditor::_can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { @@ -319,10 +320,6 @@ void ReplicationEditor::_notification(int p_what) { add_pick_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); pin->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons"))); } break; - - case NOTIFICATION_VISIBILITY_CHANGED: { - update_keying(); - } break; } } @@ -338,28 +335,15 @@ void ReplicationEditor::_add_pressed() { return; } String np_text = np_line_edit->get_text(); - if (np_text.find(":") == -1) { - np_text = ":" + np_text; - } - NodePath prop = NodePath(np_text); - if (prop.is_empty()) { - return; - } - UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); - undo_redo->create_action(TTR("Add property")); - config = current->get_replication_config(); - if (config.is_null()) { - config.instantiate(); - current->set_replication_config(config); - undo_redo->add_do_method(current, "set_replication_config", config); - undo_redo->add_undo_method(current, "set_replication_config", Ref<SceneReplicationConfig>()); - _update_config(); + int idx = np_text.find(":"); + if (idx == -1) { + np_text = ".:" + np_text; + } else if (idx == 0) { + np_text = "." + np_text; } - undo_redo->add_do_method(config.ptr(), "add_property", prop); - undo_redo->add_undo_method(config.ptr(), "remove_property", prop); - undo_redo->add_do_method(this, "_update_config"); - undo_redo->add_undo_method(this, "_update_config"); - undo_redo->commit_action(); + NodePath path = NodePath(np_text); + + _add_sync_property(path); } void ReplicationEditor::_tree_item_edited() { @@ -437,32 +421,12 @@ void ReplicationEditor::_update_checked(const NodePath &p_prop, int p_column, bo } } -void ReplicationEditor::update_keying() { - /// TODO make keying usable. -#if 0 - bool keying_enabled = false; - EditorSelectionHistory *editor_history = EditorNode::get_singleton()->get_editor_selection_history(); - if (is_visible_in_tree() && config.is_valid() && editor_history->get_path_size() > 0) { - Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0)); - keying_enabled = Object::cast_to<Node>(obj) != nullptr; - } - - if (keying_enabled == keying) { - return; - } - - keying = keying_enabled; - emit_signal(SNAME("keying_changed")); -#endif -} - void ReplicationEditor::_update_config() { deleting = NodePath(); tree->clear(); tree->create_item(); drop_label->set_visible(true); if (!config.is_valid()) { - update_keying(); return; } TypedArray<NodePath> props = config->get_properties(); @@ -473,7 +437,6 @@ void ReplicationEditor::_update_config() { const NodePath path = props[i]; _add_property(path, config->property_get_spawn(path), config->property_get_sync(path)); } - update_keying(); } void ReplicationEditor::edit(MultiplayerSynchronizer *p_sync) { @@ -529,43 +492,6 @@ void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn, item->set_editable(2, true); } -void ReplicationEditor::property_keyed(const String &p_property) { - ERR_FAIL_COND(!current || config.is_null()); - Node *root = current->get_node(current->get_root_path()); - ERR_FAIL_COND(!root); - EditorSelectionHistory *history = EditorNode::get_singleton()->get_editor_selection_history(); - ERR_FAIL_COND(history->get_path_size() == 0); - Node *node = Object::cast_to<Node>(ObjectDB::get_instance(history->get_path_object(0))); - ERR_FAIL_COND(!node); - if (node->is_class("MultiplayerSynchronizer")) { - error_dialog->set_text(TTR("Properties of 'MultiplayerSynchronizer' cannot be configured for replication.")); - error_dialog->popup_centered(); - return; - } - if (history->get_path_size() > 1 || p_property.get_slice_count(":") > 1) { - error_dialog->set_text(TTR("Subresources cannot yet be configured for replication.")); - error_dialog->popup_centered(); - return; - } - - String path = root->get_path_to(node); - for (int i = 1; i < history->get_path_size(); i++) { - String prop = history->get_path_property(i); - ERR_FAIL_COND(prop == ""); - path += ":" + prop; - } - path += ":" + p_property; - - NodePath prop = path; - UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); - undo_redo->create_action(TTR("Add property")); - undo_redo->add_do_method(config.ptr(), "add_property", prop); - undo_redo->add_undo_method(config.ptr(), "remove_property", prop); - undo_redo->add_do_method(this, "_update_config"); - undo_redo->add_undo_method(this, "_update_config"); - undo_redo->commit_action(); -} - /// ReplicationEditorPlugin ReplicationEditorPlugin::ReplicationEditorPlugin() { repl_editor = memnew(ReplicationEditor); @@ -577,26 +503,9 @@ ReplicationEditorPlugin::ReplicationEditorPlugin() { ReplicationEditorPlugin::~ReplicationEditorPlugin() { } -void ReplicationEditorPlugin::_keying_changed() { - // TODO make lock usable. - //InspectorDock::get_inspector_singleton()->set_keying(repl_editor->has_keying(), this); -} - -void ReplicationEditorPlugin::_property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance) { - if (!repl_editor->has_keying()) { - return; - } - repl_editor->property_keyed(p_keyed); -} - void ReplicationEditorPlugin::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - //Node3DEditor::get_singleton()->connect("transform_key_request", callable_mp(this, &AnimationPlayerEditorPlugin::_transform_key_request)); - InspectorDock::get_inspector_singleton()->connect("property_keyed", callable_mp(this, &ReplicationEditorPlugin::_property_keyed)); - repl_editor->connect("keying_changed", callable_mp(this, &ReplicationEditorPlugin::_keying_changed)); - // TODO make lock usable. - //InspectorDock::get_inspector_singleton()->connect("object_inspected", callable_mp(repl_editor, &ReplicationEditor::update_keying)); get_tree()->connect("node_removed", callable_mp(this, &ReplicationEditorPlugin::_node_removed)); } break; } @@ -632,8 +541,6 @@ bool ReplicationEditorPlugin::handles(Object *p_object) const { void ReplicationEditorPlugin::make_visible(bool p_visible) { if (p_visible) { - //editor->hide_animation_player_editors(); - //editor->animation_panel_make_visible(true); button->show(); EditorNode::get_singleton()->make_bottom_panel_item_visible(repl_editor); } else if (!repl_editor->get_pin()->is_pressed()) { diff --git a/editor/plugins/replication_editor_plugin.h b/modules/multiplayer/editor/replication_editor_plugin.h index df3d97f884..e60e49cc25 100644 --- a/editor/plugins/replication_editor_plugin.h +++ b/modules/multiplayer/editor/replication_editor_plugin.h @@ -32,15 +32,17 @@ #define REPLICATION_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" -#include "scene/resources/scene_replication_config.h" #include "editor/editor_spin_slider.h" -#include "editor/property_editor.h" #include "editor/property_selector.h" +#include "../scene_replication_config.h" + class ConfirmationDialog; class MultiplayerSynchronizer; +class SceneTreeDialog; class Tree; +class TreeItem; class ReplicationEditor : public VBoxContainer { GDCLASS(ReplicationEditor, VBoxContainer); @@ -59,7 +61,6 @@ private: Ref<SceneReplicationConfig> config; NodePath deleting; Tree *tree = nullptr; - bool keying = false; PropertySelector *prop_selector = nullptr; SceneTreeDialog *pick_node = nullptr; @@ -96,11 +97,8 @@ protected: void _notification(int p_what); public: - void update_keying(); void edit(MultiplayerSynchronizer *p_object); - bool has_keying() const { return keying; } MultiplayerSynchronizer *get_current() const { return current; } - void property_keyed(const String &p_property); Button *get_pin() { return pin; } ReplicationEditor(); @@ -115,8 +113,6 @@ private: ReplicationEditor *repl_editor = nullptr; void _node_removed(Node *p_node); - void _keying_changed(); - void _property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance); void _pinned(); diff --git a/scene/multiplayer/multiplayer_spawner.cpp b/modules/multiplayer/multiplayer_spawner.cpp index 8363d05e54..e8f3aecc69 100644 --- a/scene/multiplayer/multiplayer_spawner.cpp +++ b/modules/multiplayer/multiplayer_spawner.cpp @@ -31,7 +31,7 @@ #include "multiplayer_spawner.h" #include "core/io/marshalls.h" -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" @@ -126,7 +126,7 @@ void MultiplayerSpawner::_set_spawnable_scenes(const Vector<String> &p_scenes) { void MultiplayerSpawner::_bind_methods() { ClassDB::bind_method(D_METHOD("add_spawnable_scene", "path"), &MultiplayerSpawner::add_spawnable_scene); ClassDB::bind_method(D_METHOD("get_spawnable_scene_count"), &MultiplayerSpawner::get_spawnable_scene_count); - ClassDB::bind_method(D_METHOD("get_spawnable_scene", "path"), &MultiplayerSpawner::get_spawnable_scene); + ClassDB::bind_method(D_METHOD("get_spawnable_scene", "index"), &MultiplayerSpawner::get_spawnable_scene); ClassDB::bind_method(D_METHOD("clear_spawnable_scenes"), &MultiplayerSpawner::clear_spawnable_scenes); ClassDB::bind_method(D_METHOD("_get_spawnable_scenes"), &MultiplayerSpawner::_get_spawnable_scenes); @@ -146,8 +146,8 @@ void MultiplayerSpawner::_bind_methods() { GDVIRTUAL_BIND(_spawn_custom, "data"); - ADD_SIGNAL(MethodInfo("despawned", PropertyInfo(Variant::INT, "scene_id"), PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); - ADD_SIGNAL(MethodInfo("spawned", PropertyInfo(Variant::INT, "scene_id"), PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); + ADD_SIGNAL(MethodInfo("despawned", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); + ADD_SIGNAL(MethodInfo("spawned", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); } void MultiplayerSpawner::_update_spawn_node() { @@ -190,7 +190,7 @@ void MultiplayerSpawner::_notification(int p_what) { if (node->is_connected(SceneStringNames::get_singleton()->ready, callable_mp(this, &MultiplayerSpawner::_node_ready))) { node->disconnect(SceneStringNames::get_singleton()->ready, callable_mp(this, &MultiplayerSpawner::_node_ready)); } - get_multiplayer()->despawn(node, this); + get_multiplayer()->object_configuration_remove(node, this); } tracked_nodes.clear(); } break; @@ -230,13 +230,13 @@ void MultiplayerSpawner::_track(Node *p_node, const Variant &p_argument, int p_s ObjectID oid = p_node->get_instance_id(); if (!tracked_nodes.has(oid)) { tracked_nodes[oid] = SpawnInfo(p_argument.duplicate(true), p_scene_id); - p_node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &MultiplayerSpawner::_node_exit), varray(p_node->get_instance_id()), CONNECT_ONESHOT); - p_node->connect(SceneStringNames::get_singleton()->ready, callable_mp(this, &MultiplayerSpawner::_node_ready), varray(p_node->get_instance_id()), CONNECT_ONESHOT); + p_node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &MultiplayerSpawner::_node_exit).bind(p_node->get_instance_id()), CONNECT_ONESHOT); + p_node->connect(SceneStringNames::get_singleton()->ready, callable_mp(this, &MultiplayerSpawner::_node_ready).bind(p_node->get_instance_id()), CONNECT_ONESHOT); } } void MultiplayerSpawner::_node_ready(ObjectID p_id) { - get_multiplayer()->spawn(ObjectDB::get_instance(p_id), this); + get_multiplayer()->object_configuration_add(ObjectDB::get_instance(p_id), this); } void MultiplayerSpawner::_node_exit(ObjectID p_id) { @@ -244,7 +244,7 @@ void MultiplayerSpawner::_node_exit(ObjectID p_id) { ERR_FAIL_COND(!node); if (tracked_nodes.has(p_id)) { tracked_nodes.erase(p_id); - get_multiplayer()->despawn(node, this); + get_multiplayer()->object_configuration_remove(node, this); } } @@ -277,12 +277,11 @@ Node *MultiplayerSpawner::instantiate_scene(int p_id) { Node *MultiplayerSpawner::instantiate_custom(const Variant &p_data) { ERR_FAIL_COND_V_MSG(spawn_limit && spawn_limit <= tracked_nodes.size(), nullptr, "Spawn limit reached!"); - Object *obj = nullptr; Node *node = nullptr; - if (GDVIRTUAL_CALL(_spawn_custom, p_data, obj)) { - node = Object::cast_to<Node>(obj); + if (GDVIRTUAL_CALL(_spawn_custom, p_data, node)) { + return node; } - return node; + ERR_FAIL_V_MSG(nullptr, "Method '_spawn_custom' is not implemented on this peer."); } Node *MultiplayerSpawner::spawn(const Variant &p_data) { diff --git a/scene/multiplayer/multiplayer_spawner.h b/modules/multiplayer/multiplayer_spawner.h index 2c0eb9a2f0..fc3befc2d4 100644 --- a/scene/multiplayer/multiplayer_spawner.h +++ b/modules/multiplayer/multiplayer_spawner.h @@ -36,7 +36,8 @@ #include "core/templates/local_vector.h" #include "core/variant/typed_array.h" #include "scene/resources/packed_scene.h" -#include "scene/resources/scene_replication_config.h" + +#include "scene_replication_config.h" class MultiplayerSpawner : public Node { GDCLASS(MultiplayerSpawner, Node); @@ -90,7 +91,9 @@ protected: void _get_property_list(List<PropertyInfo> *p_list) const; #endif public: - Node *get_spawn_node() const { return spawn_node.is_valid() ? Object::cast_to<Node>(ObjectDB::get_instance(spawn_node)) : nullptr; } + Node *get_spawn_node() const { + return spawn_node.is_valid() ? Object::cast_to<Node>(ObjectDB::get_instance(spawn_node)) : nullptr; + } void add_spawnable_scene(const String &p_path); int get_spawnable_scene_count() const; @@ -109,7 +112,7 @@ public: Node *instantiate_custom(const Variant &p_data); Node *instantiate_scene(int p_idx); - GDVIRTUAL1R(Object *, _spawn_custom, const Variant &); + GDVIRTUAL1R(Node *, _spawn_custom, const Variant &); MultiplayerSpawner() {} }; diff --git a/scene/multiplayer/multiplayer_synchronizer.cpp b/modules/multiplayer/multiplayer_synchronizer.cpp index e1b7433968..eee1495c14 100644 --- a/scene/multiplayer/multiplayer_synchronizer.cpp +++ b/modules/multiplayer/multiplayer_synchronizer.cpp @@ -31,7 +31,7 @@ #include "multiplayer_synchronizer.h" #include "core/config/engine.h" -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" Object *MultiplayerSynchronizer::_get_prop_target(Object *p_obj, const NodePath &p_path) { if (p_path.get_name_count() == 0) { @@ -50,7 +50,7 @@ void MultiplayerSynchronizer::_stop() { #endif Node *node = is_inside_tree() ? get_node_or_null(root_path) : nullptr; if (node) { - get_multiplayer()->replication_stop(node, this); + get_multiplayer()->object_configuration_remove(node, this); } } @@ -62,7 +62,7 @@ void MultiplayerSynchronizer::_start() { #endif Node *node = is_inside_tree() ? get_node_or_null(root_path) : nullptr; if (node) { - get_multiplayer()->replication_start(node, this); + get_multiplayer()->object_configuration_add(node, this); _update_process(); } } @@ -138,7 +138,7 @@ bool MultiplayerSynchronizer::is_visible_to(int p_peer) { for (Callable filter : visibility_filters) { Variant ret; Callable::CallError err; - filter.call(argv, 1, ret, err); + filter.callp(argv, 1, ret, err); ERR_FAIL_COND_V(err.error != Callable::CallError::CALL_OK || ret.get_type() != Variant::BOOL, false); if (!ret.operator bool()) { return false; @@ -293,9 +293,9 @@ void MultiplayerSynchronizer::set_multiplayer_authority(int p_peer_id, bool p_re Node::set_multiplayer_authority(p_peer_id, p_recursive); return; } - get_multiplayer()->replication_stop(node, this); + get_multiplayer()->object_configuration_remove(node, this); Node::set_multiplayer_authority(p_peer_id, p_recursive); - get_multiplayer()->replication_start(node, this); + get_multiplayer()->object_configuration_add(node, this); } MultiplayerSynchronizer::MultiplayerSynchronizer() { diff --git a/scene/multiplayer/multiplayer_synchronizer.h b/modules/multiplayer/multiplayer_synchronizer.h index 77c23b336d..e84d41db86 100644 --- a/scene/multiplayer/multiplayer_synchronizer.h +++ b/modules/multiplayer/multiplayer_synchronizer.h @@ -33,7 +33,7 @@ #include "scene/main/node.h" -#include "scene/resources/scene_replication_config.h" +#include "scene_replication_config.h" class MultiplayerSynchronizer : public Node { GDCLASS(MultiplayerSynchronizer, Node); diff --git a/modules/multiplayer/register_types.cpp b/modules/multiplayer/register_types.cpp new file mode 100644 index 0000000000..a2c524da80 --- /dev/null +++ b/modules/multiplayer/register_types.cpp @@ -0,0 +1,60 @@ +/*************************************************************************/ +/* register_types.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "register_types.h" + +#include "multiplayer_spawner.h" +#include "multiplayer_synchronizer.h" +#include "scene_multiplayer.h" +#include "scene_replication_interface.h" +#include "scene_rpc_interface.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_plugin.h" +#include "editor/replication_editor_plugin.h" +#endif + +void initialize_multiplayer_module(ModuleInitializationLevel p_level) { + if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { + GDREGISTER_CLASS(SceneReplicationConfig); + GDREGISTER_CLASS(MultiplayerSpawner); + GDREGISTER_CLASS(MultiplayerSynchronizer); + GDREGISTER_CLASS(SceneMultiplayer); + MultiplayerAPI::set_default_interface("SceneMultiplayer"); + } +#ifdef TOOLS_ENABLED + if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) { + EditorPlugins::add_by_type<ReplicationEditorPlugin>(); + } +#endif +} + +void uninitialize_multiplayer_module(ModuleInitializationLevel p_level) { +} diff --git a/modules/multiplayer/register_types.h b/modules/multiplayer/register_types.h new file mode 100644 index 0000000000..aca6cf46ed --- /dev/null +++ b/modules/multiplayer/register_types.h @@ -0,0 +1,39 @@ +/*************************************************************************/ +/* register_types.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef MULTIPLAYER_REGISTER_TYPES_H +#define MULTIPLAYER_REGISTER_TYPES_H + +#include "modules/register_module_types.h" + +void initialize_multiplayer_module(ModuleInitializationLevel p_level); +void uninitialize_multiplayer_module(ModuleInitializationLevel p_level); + +#endif // MULTIPLAYER_REGISTER_TYPES_H diff --git a/scene/multiplayer/scene_cache_interface.cpp b/modules/multiplayer/scene_cache_interface.cpp index 79a7dc2d5a..b3b642f815 100644 --- a/scene/multiplayer/scene_cache_interface.cpp +++ b/modules/multiplayer/scene_cache_interface.cpp @@ -34,13 +34,7 @@ #include "scene/main/node.h" #include "scene/main/window.h" -MultiplayerCacheInterface *SceneCacheInterface::_create(MultiplayerAPI *p_multiplayer) { - return memnew(SceneCacheInterface(p_multiplayer)); -} - -void SceneCacheInterface::make_default() { - MultiplayerAPI::create_default_cache_interface = _create; -} +#include "scene_multiplayer.h" void SceneCacheInterface::on_peer_change(int p_id, bool p_connected) { if (p_connected) { @@ -98,7 +92,7 @@ void SceneCacheInterface::process_simplify_path(int p_from, const uint8_t *p_pac Vector<uint8_t> packet; packet.resize(1 + 1 + len); - packet.write[0] = MultiplayerAPI::NETWORK_COMMAND_CONFIRM_PATH; + packet.write[0] = SceneMultiplayer::NETWORK_COMMAND_CONFIRM_PATH; packet.write[1] = valid_rpc_checksum; encode_cstring(pname.get_data(), &packet.write[2]); @@ -110,7 +104,7 @@ void SceneCacheInterface::process_simplify_path(int p_from, const uint8_t *p_pac #endif multiplayer_peer->set_transfer_channel(0); - multiplayer_peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_RELIABLE); + multiplayer_peer->set_transfer_mode(MultiplayerPeer::TRANSFER_MODE_RELIABLE); multiplayer_peer->set_target_peer(p_from); multiplayer_peer->put_packet(packet.ptr(), packet.size()); } @@ -150,7 +144,7 @@ Error SceneCacheInterface::_send_confirm_path(Node *p_node, NodePath p_path, Pat packet.resize(1 + 4 + path_len + methods_md5_len); int ofs = 0; - packet.write[ofs] = MultiplayerAPI::NETWORK_COMMAND_SIMPLIFY_PATH; + packet.write[ofs] = SceneMultiplayer::NETWORK_COMMAND_SIMPLIFY_PATH; ofs += 1; ofs += encode_cstring(methods_md5.utf8().get_data(), &packet.write[ofs]); @@ -170,7 +164,7 @@ Error SceneCacheInterface::_send_confirm_path(Node *p_node, NodePath p_path, Pat for (int peer_id : p_peers) { multiplayer_peer->set_target_peer(peer_id); multiplayer_peer->set_transfer_channel(0); - multiplayer_peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_RELIABLE); + multiplayer_peer->set_transfer_mode(MultiplayerPeer::TRANSFER_MODE_RELIABLE); err = multiplayer_peer->put_packet(packet.ptr(), packet.size()); ERR_FAIL_COND_V(err != OK, err); // Insert into confirmed, but as false since it was not confirmed. @@ -229,9 +223,6 @@ bool SceneCacheInterface::send_object_cache(Object *p_obj, int p_peer_id, int &r if (p_peer_id < 0 && E == -p_peer_id) { continue; // Continue, excluded. } - if (p_peer_id > 0 && E != p_peer_id) { - continue; // Continue, not for this peer. - } HashMap<int, bool>::Iterator F = psc->confirmed_peers.find(E); if (!F) { diff --git a/scene/multiplayer/scene_cache_interface.h b/modules/multiplayer/scene_cache_interface.h index 6bfd683cf4..1e80792fe7 100644 --- a/scene/multiplayer/scene_cache_interface.h +++ b/modules/multiplayer/scene_cache_interface.h @@ -31,13 +31,15 @@ #ifndef SCENE_CACHE_INTERFACE_H #define SCENE_CACHE_INTERFACE_H -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" -class SceneCacheInterface : public MultiplayerCacheInterface { - GDCLASS(SceneCacheInterface, MultiplayerCacheInterface); +class SceneMultiplayer; + +class SceneCacheInterface : public RefCounted { + GDCLASS(SceneCacheInterface, RefCounted); private: - MultiplayerAPI *multiplayer = nullptr; + SceneMultiplayer *multiplayer = nullptr; //path sent caches struct PathSentCache { @@ -61,23 +63,20 @@ private: protected: Error _send_confirm_path(Node *p_node, NodePath p_path, PathSentCache *psc, const List<int> &p_peers); - static MultiplayerCacheInterface *_create(MultiplayerAPI *p_multiplayer); public: - static void make_default(); - - virtual void clear() override; - virtual void on_peer_change(int p_id, bool p_connected) override; - virtual void process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) override; - virtual void process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) override; + void clear(); + void on_peer_change(int p_id, bool p_connected); + void process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len); + void process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len); // Returns true if all peers have cached path. - virtual bool send_object_cache(Object *p_obj, int p_target, int &p_id) override; - virtual int make_object_cache(Object *p_obj) override; - virtual Object *get_cached_object(int p_from, uint32_t p_cache_id) override; - virtual bool is_cache_confirmed(NodePath p_path, int p_peer) override; + bool send_object_cache(Object *p_obj, int p_target, int &p_id); + int make_object_cache(Object *p_obj); + Object *get_cached_object(int p_from, uint32_t p_cache_id); + bool is_cache_confirmed(NodePath p_path, int p_peer); - SceneCacheInterface(MultiplayerAPI *p_multiplayer) { multiplayer = p_multiplayer; } + SceneCacheInterface(SceneMultiplayer *p_multiplayer) { multiplayer = p_multiplayer; } }; #endif // SCENE_CACHE_INTERFACE_H diff --git a/modules/multiplayer/scene_multiplayer.cpp b/modules/multiplayer/scene_multiplayer.cpp new file mode 100644 index 0000000000..3fc1eef366 --- /dev/null +++ b/modules/multiplayer/scene_multiplayer.cpp @@ -0,0 +1,332 @@ +/*************************************************************************/ +/* scene_multiplayer.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "scene_multiplayer.h" + +#include "core/debugger/engine_debugger.h" +#include "core/io/marshalls.h" + +#include <stdint.h> + +#ifdef DEBUG_ENABLED +#include "core/os/os.h" +#endif + +#ifdef DEBUG_ENABLED +void SceneMultiplayer::profile_bandwidth(const String &p_inout, int p_size) { + if (EngineDebugger::is_profiling("multiplayer")) { + Array values; + values.push_back(p_inout); + values.push_back(OS::get_singleton()->get_ticks_msec()); + values.push_back(p_size); + EngineDebugger::profiler_add_frame_data("multiplayer", values); + } +} +#endif + +Error SceneMultiplayer::poll() { + if (!multiplayer_peer.is_valid() || multiplayer_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED) { + return ERR_UNCONFIGURED; + } + + multiplayer_peer->poll(); + + if (!multiplayer_peer.is_valid()) { // It's possible that polling might have resulted in a disconnection, so check here. + return OK; + } + + while (multiplayer_peer->get_available_packet_count()) { + int sender = multiplayer_peer->get_packet_peer(); + const uint8_t *packet; + int len; + + Error err = multiplayer_peer->get_packet(&packet, len); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Error getting packet! %d", err)); + + remote_sender_id = sender; + _process_packet(sender, packet, len); + remote_sender_id = 0; + + if (!multiplayer_peer.is_valid()) { + return OK; // It's also possible that a packet or RPC caused a disconnection, so also check here. + } + } + replicator->on_network_process(); + return OK; +} + +void SceneMultiplayer::clear() { + connected_peers.clear(); + packet_cache.clear(); + cache->clear(); +} + +void SceneMultiplayer::set_root_path(const NodePath &p_path) { + ERR_FAIL_COND_MSG(!p_path.is_absolute() && !p_path.is_empty(), "SceneMultiplayer root path must be absolute."); + root_path = p_path; +} + +NodePath SceneMultiplayer::get_root_path() const { + return root_path; +} + +void SceneMultiplayer::set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) { + if (p_peer == multiplayer_peer) { + return; // Nothing to do + } + + ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED, + "Supplied MultiplayerPeer must be connecting or connected."); + + if (multiplayer_peer.is_valid()) { + multiplayer_peer->disconnect("peer_connected", callable_mp(this, &SceneMultiplayer::_add_peer)); + multiplayer_peer->disconnect("peer_disconnected", callable_mp(this, &SceneMultiplayer::_del_peer)); + multiplayer_peer->disconnect("connection_succeeded", callable_mp(this, &SceneMultiplayer::_connected_to_server)); + multiplayer_peer->disconnect("connection_failed", callable_mp(this, &SceneMultiplayer::_connection_failed)); + multiplayer_peer->disconnect("server_disconnected", callable_mp(this, &SceneMultiplayer::_server_disconnected)); + clear(); + } + + multiplayer_peer = p_peer; + + if (multiplayer_peer.is_valid()) { + multiplayer_peer->connect("peer_connected", callable_mp(this, &SceneMultiplayer::_add_peer)); + multiplayer_peer->connect("peer_disconnected", callable_mp(this, &SceneMultiplayer::_del_peer)); + multiplayer_peer->connect("connection_succeeded", callable_mp(this, &SceneMultiplayer::_connected_to_server)); + multiplayer_peer->connect("connection_failed", callable_mp(this, &SceneMultiplayer::_connection_failed)); + multiplayer_peer->connect("server_disconnected", callable_mp(this, &SceneMultiplayer::_server_disconnected)); + } + replicator->on_reset(); +} + +Ref<MultiplayerPeer> SceneMultiplayer::get_multiplayer_peer() { + return multiplayer_peer; +} + +void SceneMultiplayer::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) { + ERR_FAIL_COND_MSG(root_path.is_empty(), "Multiplayer root was not initialized. If you are using custom multiplayer, remember to set the root path via SceneMultiplayer.set_root_path before using it."); + ERR_FAIL_COND_MSG(p_packet_len < 1, "Invalid packet received. Size too small."); + +#ifdef DEBUG_ENABLED + profile_bandwidth("in", p_packet_len); +#endif + + // Extract the `packet_type` from the LSB three bits: + uint8_t packet_type = p_packet[0] & CMD_MASK; + + switch (packet_type) { + case NETWORK_COMMAND_SIMPLIFY_PATH: { + cache->process_simplify_path(p_from, p_packet, p_packet_len); + } break; + + case NETWORK_COMMAND_CONFIRM_PATH: { + cache->process_confirm_path(p_from, p_packet, p_packet_len); + } break; + + case NETWORK_COMMAND_REMOTE_CALL: { + rpc->process_rpc(p_from, p_packet, p_packet_len); + } break; + + case NETWORK_COMMAND_RAW: { + _process_raw(p_from, p_packet, p_packet_len); + } break; + case NETWORK_COMMAND_SPAWN: { + replicator->on_spawn_receive(p_from, p_packet, p_packet_len); + } break; + case NETWORK_COMMAND_DESPAWN: { + replicator->on_despawn_receive(p_from, p_packet, p_packet_len); + } break; + case NETWORK_COMMAND_SYNC: { + replicator->on_sync_receive(p_from, p_packet, p_packet_len); + } break; + } +} + +void SceneMultiplayer::_add_peer(int p_id) { + connected_peers.insert(p_id); + cache->on_peer_change(p_id, true); + replicator->on_peer_change(p_id, true); + emit_signal(SNAME("peer_connected"), p_id); +} + +void SceneMultiplayer::_del_peer(int p_id) { + replicator->on_peer_change(p_id, false); + cache->on_peer_change(p_id, false); + connected_peers.erase(p_id); + emit_signal(SNAME("peer_disconnected"), p_id); +} + +void SceneMultiplayer::_connected_to_server() { + emit_signal(SNAME("connected_to_server")); +} + +void SceneMultiplayer::_connection_failed() { + emit_signal(SNAME("connection_failed")); +} + +void SceneMultiplayer::_server_disconnected() { + replicator->on_reset(); + emit_signal(SNAME("server_disconnected")); +} + +Error SceneMultiplayer::send_bytes(Vector<uint8_t> p_data, int p_to, MultiplayerPeer::TransferMode p_mode, int p_channel) { + ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet."); + ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no multiplayer peer is active."); + ERR_FAIL_COND_V_MSG(multiplayer_peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED, "Trying to send a raw packet via a multiplayer peer which is not connected."); + + if (packet_cache.size() < p_data.size() + 1) { + packet_cache.resize(p_data.size() + 1); + } + + const uint8_t *r = p_data.ptr(); + packet_cache.write[0] = NETWORK_COMMAND_RAW; + memcpy(&packet_cache.write[1], &r[0], p_data.size()); + + multiplayer_peer->set_target_peer(p_to); + multiplayer_peer->set_transfer_channel(p_channel); + multiplayer_peer->set_transfer_mode(p_mode); + + return multiplayer_peer->put_packet(packet_cache.ptr(), p_data.size() + 1); +} + +void SceneMultiplayer::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) { + ERR_FAIL_COND_MSG(p_packet_len < 2, "Invalid packet received. Size too small."); + + Vector<uint8_t> out; + int len = p_packet_len - 1; + out.resize(len); + { + uint8_t *w = out.ptrw(); + memcpy(&w[0], &p_packet[1], len); + } + emit_signal(SNAME("peer_packet"), p_from, out); +} + +int SceneMultiplayer::get_unique_id() { + ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), 0, "No multiplayer peer is assigned. Unable to get unique ID."); + return multiplayer_peer->get_unique_id(); +} + +void SceneMultiplayer::set_refuse_new_connections(bool p_refuse) { + ERR_FAIL_COND_MSG(!multiplayer_peer.is_valid(), "No multiplayer peer is assigned. Unable to set 'refuse_new_connections'."); + multiplayer_peer->set_refuse_new_connections(p_refuse); +} + +bool SceneMultiplayer::is_refusing_new_connections() const { + ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), false, "No multiplayer peer is assigned. Unable to get 'refuse_new_connections'."); + return multiplayer_peer->is_refusing_new_connections(); +} + +Vector<int> SceneMultiplayer::get_peer_ids() { + ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), Vector<int>(), "No multiplayer peer is assigned. Assume no peers are connected."); + + Vector<int> ret; + for (const int &E : connected_peers) { + ret.push_back(E); + } + + return ret; +} + +void SceneMultiplayer::set_allow_object_decoding(bool p_enable) { + allow_object_decoding = p_enable; +} + +bool SceneMultiplayer::is_object_decoding_allowed() const { + return allow_object_decoding; +} + +String SceneMultiplayer::get_rpc_md5(const Object *p_obj) { + return rpc->get_rpc_md5(p_obj); +} + +Error SceneMultiplayer::rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { + return rpc->rpcp(p_obj, p_peer_id, p_method, p_arg, p_argcount); +} + +Error SceneMultiplayer::object_configuration_add(Object *p_obj, Variant p_config) { + if (p_obj == nullptr && p_config.get_type() == Variant::NODE_PATH) { + set_root_path(p_config); + return OK; + } + MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(p_config.get_validated_object()); + MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object()); + if (spawner) { + return replicator->on_spawn(p_obj, p_config); + } else if (sync) { + return replicator->on_replication_start(p_obj, p_config); + } + return ERR_INVALID_PARAMETER; +} + +Error SceneMultiplayer::object_configuration_remove(Object *p_obj, Variant p_config) { + if (p_obj == nullptr && p_config.get_type() == Variant::NODE_PATH) { + ERR_FAIL_COND_V(root_path != p_config.operator NodePath(), ERR_INVALID_PARAMETER); + set_root_path(NodePath()); + return OK; + } + MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(p_config.get_validated_object()); + MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object()); + if (spawner) { + return replicator->on_despawn(p_obj, p_config); + } + if (sync) { + return replicator->on_replication_stop(p_obj, p_config); + } + return ERR_INVALID_PARAMETER; +} + +void SceneMultiplayer::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_root_path", "path"), &SceneMultiplayer::set_root_path); + ClassDB::bind_method(D_METHOD("get_root_path"), &SceneMultiplayer::get_root_path); + ClassDB::bind_method(D_METHOD("clear"), &SceneMultiplayer::clear); + ClassDB::bind_method(D_METHOD("set_refuse_new_connections", "refuse"), &SceneMultiplayer::set_refuse_new_connections); + ClassDB::bind_method(D_METHOD("is_refusing_new_connections"), &SceneMultiplayer::is_refusing_new_connections); + ClassDB::bind_method(D_METHOD("set_allow_object_decoding", "enable"), &SceneMultiplayer::set_allow_object_decoding); + ClassDB::bind_method(D_METHOD("is_object_decoding_allowed"), &SceneMultiplayer::is_object_decoding_allowed); + ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode", "channel"), &SceneMultiplayer::send_bytes, DEFVAL(MultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(MultiplayerPeer::TRANSFER_MODE_RELIABLE), DEFVAL(0)); + + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_path"), "set_root_path", "get_root_path"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_object_decoding"), "set_allow_object_decoding", "is_object_decoding_allowed"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_connections"), "set_refuse_new_connections", "is_refusing_new_connections"); + ADD_PROPERTY_DEFAULT("refuse_new_connections", false); + + ADD_SIGNAL(MethodInfo("peer_packet", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::PACKED_BYTE_ARRAY, "packet"))); +} + +SceneMultiplayer::SceneMultiplayer() { + replicator = Ref<SceneReplicationInterface>(memnew(SceneReplicationInterface(this))); + rpc = Ref<SceneRPCInterface>(memnew(SceneRPCInterface(this))); + cache = Ref<SceneCacheInterface>(memnew(SceneCacheInterface(this))); +} + +SceneMultiplayer::~SceneMultiplayer() { + clear(); +} diff --git a/modules/multiplayer/scene_multiplayer.h b/modules/multiplayer/scene_multiplayer.h new file mode 100644 index 0000000000..a99cca7b21 --- /dev/null +++ b/modules/multiplayer/scene_multiplayer.h @@ -0,0 +1,136 @@ +/*************************************************************************/ +/* scene_multiplayer.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SCENE_MULTIPLAYER_H +#define SCENE_MULTIPLAYER_H + +#include "scene/main/multiplayer_api.h" + +#include "scene_cache_interface.h" +#include "scene_replication_interface.h" +#include "scene_rpc_interface.h" + +class SceneMultiplayer : public MultiplayerAPI { + GDCLASS(SceneMultiplayer, MultiplayerAPI); + +public: + enum NetworkCommands { + NETWORK_COMMAND_REMOTE_CALL = 0, + NETWORK_COMMAND_SIMPLIFY_PATH, + NETWORK_COMMAND_CONFIRM_PATH, + NETWORK_COMMAND_RAW, + NETWORK_COMMAND_SPAWN, + NETWORK_COMMAND_DESPAWN, + NETWORK_COMMAND_SYNC, + }; + + // For each command, the 4 MSB can contain custom flags, as defined by subsystems. + enum { + CMD_FLAG_0_SHIFT = 4, + CMD_FLAG_1_SHIFT = 5, + CMD_FLAG_2_SHIFT = 6, + CMD_FLAG_3_SHIFT = 7, + }; + + // This is the mask that will be used to extract the command. + enum { + CMD_MASK = 7, // 0x7 -> 0b00001111 + }; + +private: + Ref<MultiplayerPeer> multiplayer_peer; + HashSet<int> connected_peers; + int remote_sender_id = 0; + int remote_sender_override = 0; + + Vector<uint8_t> packet_cache; + + NodePath root_path; + bool allow_object_decoding = false; + + Ref<SceneCacheInterface> cache; + Ref<SceneReplicationInterface> replicator; + Ref<SceneRPCInterface> rpc; + +protected: + static void _bind_methods(); + + void _process_packet(int p_from, const uint8_t *p_packet, int p_packet_len); + void _process_raw(int p_from, const uint8_t *p_packet, int p_packet_len); + + void _add_peer(int p_id); + void _del_peer(int p_id); + void _connected_to_server(); + void _connection_failed(); + void _server_disconnected(); + +public: + virtual void set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) override; + virtual Ref<MultiplayerPeer> get_multiplayer_peer() override; + + virtual Error poll() override; + virtual int get_unique_id() override; + virtual Vector<int> get_peer_ids() override; + virtual int get_remote_sender_id() override { return remote_sender_override ? remote_sender_override : remote_sender_id; } + + virtual Error rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) override; + + virtual Error object_configuration_add(Object *p_obj, Variant p_config) override; + virtual Error object_configuration_remove(Object *p_obj, Variant p_config) override; + + void clear(); + + // Usually from object_configuration_add/remove + void set_root_path(const NodePath &p_path); + NodePath get_root_path() const; + + Error send_bytes(Vector<uint8_t> p_data, int p_to = MultiplayerPeer::TARGET_PEER_BROADCAST, MultiplayerPeer::TransferMode p_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE, int p_channel = 0); + String get_rpc_md5(const Object *p_obj); + + const HashSet<int> get_connected_peers() const { return connected_peers; } + + void set_remote_sender_override(int p_id) { remote_sender_override = p_id; } + void set_refuse_new_connections(bool p_refuse); + bool is_refusing_new_connections() const; + + void set_allow_object_decoding(bool p_enable); + bool is_object_decoding_allowed() const; + + Ref<SceneCacheInterface> get_path_cache() { return cache; } + +#ifdef DEBUG_ENABLED + void profile_bandwidth(const String &p_inout, int p_size); +#endif + + SceneMultiplayer(); + ~SceneMultiplayer(); +}; + +#endif // SCENE_MULTIPLAYER_H diff --git a/scene/resources/scene_replication_config.cpp b/modules/multiplayer/scene_replication_config.cpp index 6789f9f7d5..ae06516b7b 100644 --- a/scene/resources/scene_replication_config.cpp +++ b/modules/multiplayer/scene_replication_config.cpp @@ -30,7 +30,7 @@ #include "scene_replication_config.h" -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" #include "scene/main/node.h" bool SceneReplicationConfig::_set(const StringName &p_name, const Variant &p_value) { diff --git a/scene/resources/scene_replication_config.h b/modules/multiplayer/scene_replication_config.h index ab3658d2a7..ab3658d2a7 100644 --- a/scene/resources/scene_replication_config.h +++ b/modules/multiplayer/scene_replication_config.h diff --git a/scene/multiplayer/scene_replication_interface.cpp b/modules/multiplayer/scene_replication_interface.cpp index c616c5bb85..6e3dbfab47 100644 --- a/scene/multiplayer/scene_replication_interface.cpp +++ b/modules/multiplayer/scene_replication_interface.cpp @@ -32,21 +32,15 @@ #include "core/io/marshalls.h" #include "scene/main/node.h" -#include "scene/multiplayer/multiplayer_spawner.h" -#include "scene/multiplayer/multiplayer_synchronizer.h" + +#include "multiplayer_spawner.h" +#include "multiplayer_synchronizer.h" +#include "scene_multiplayer.h" #define MAKE_ROOM(m_amount) \ if (packet_cache.size() < m_amount) \ packet_cache.resize(m_amount); -MultiplayerReplicationInterface *SceneReplicationInterface::_create(MultiplayerAPI *p_multiplayer) { - return memnew(SceneReplicationInterface(p_multiplayer)); -} - -void SceneReplicationInterface::make_default() { - MultiplayerAPI::create_default_replication_interface = _create; -} - void SceneReplicationInterface::_free_remotes(int p_id) { const HashMap<uint32_t, ObjectID> remotes = rep_state->peer_get_remotes(p_id); for (const KeyValue<uint32_t, ObjectID> &E : remotes) { @@ -134,7 +128,7 @@ Error SceneReplicationInterface::on_replication_start(Object *p_obj, Variant p_c // Add to synchronizer list and setup visibility. rep_state->config_add_sync(node, sync); const ObjectID oid = node->get_instance_id(); - sync->connect("visibility_changed", callable_mp(this, &SceneReplicationInterface::_visibility_changed), varray(oid)); + sync->connect("visibility_changed", callable_mp(this, &SceneReplicationInterface::_visibility_changed).bind(oid)); if (multiplayer->has_multiplayer_peer() && sync->is_multiplayer_authority()) { _update_sync_visibility(0, oid); } @@ -239,7 +233,7 @@ Error SceneReplicationInterface::_update_spawn_visibility(int p_peer, const Obje _make_spawn_packet(node, len); for (int pid : to_spawn) { int path_id; - multiplayer->send_object_cache(spawner, pid, path_id); + multiplayer->get_path_cache()->send_object_cache(spawner, pid, path_id); _send_raw(packet_cache.ptr(), len, pid, true); rep_state->peer_add_spawn(pid, p_oid); } @@ -267,7 +261,7 @@ Error SceneReplicationInterface::_send_raw(const uint8_t *p_buffer, int p_size, Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer(); peer->set_target_peer(p_peer); peer->set_transfer_channel(0); - peer->set_transfer_mode(p_reliable ? Multiplayer::TRANSFER_MODE_RELIABLE : Multiplayer::TRANSFER_MODE_UNRELIABLE); + peer->set_transfer_mode(p_reliable ? MultiplayerPeer::TRANSFER_MODE_RELIABLE : MultiplayerPeer::TRANSFER_MODE_UNRELIABLE); return peer->put_packet(p_buffer, p_size); } @@ -306,12 +300,12 @@ Error SceneReplicationInterface::_make_spawn_packet(Node *p_node, int &r_len) { } // Encode scene ID, path ID, net ID, node name. - int path_id = multiplayer->make_object_cache(spawner); + int path_id = multiplayer->get_path_cache()->make_object_cache(spawner); CharString cname = p_node->get_name().operator String().utf8(); int nlen = encode_cstring(cname.get_data(), nullptr); MAKE_ROOM(1 + 1 + 4 + 4 + 4 + nlen + (is_custom ? 4 + spawn_arg_size : 0) + state_size); uint8_t *ptr = packet_cache.ptrw(); - ptr[0] = (uint8_t)MultiplayerAPI::NETWORK_COMMAND_SPAWN; + ptr[0] = (uint8_t)SceneMultiplayer::NETWORK_COMMAND_SPAWN; ptr[1] = scene_id; int ofs = 2; ofs += encode_uint32(path_id, &ptr[ofs]); @@ -339,7 +333,7 @@ Error SceneReplicationInterface::_make_despawn_packet(Node *p_node, int &r_len) const ObjectID oid = p_node->get_instance_id(); MAKE_ROOM(5); uint8_t *ptr = packet_cache.ptrw(); - ptr[0] = (uint8_t)MultiplayerAPI::NETWORK_COMMAND_DESPAWN; + ptr[0] = (uint8_t)SceneMultiplayer::NETWORK_COMMAND_DESPAWN; int ofs = 1; uint32_t nid = rep_state->get_net_id(oid); ofs += encode_uint32(nid, &ptr[ofs]); @@ -354,7 +348,7 @@ Error SceneReplicationInterface::on_spawn_receive(int p_from, const uint8_t *p_b ofs += 1; uint32_t node_target = decode_uint32(&p_buffer[ofs]); ofs += 4; - MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(multiplayer->get_cached_object(p_from, node_target)); + MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(multiplayer->get_path_cache()->get_cached_object(p_from, node_target)); ERR_FAIL_COND_V(!spawner, ERR_DOES_NOT_EXIST); ERR_FAIL_COND_V(p_from != spawner->get_multiplayer_authority(), ERR_UNAUTHORIZED); @@ -402,6 +396,8 @@ Error SceneReplicationInterface::on_spawn_receive(int p_from, const uint8_t *p_b pending_buffer_size = state_len; } parent->add_child(node); + spawner->emit_signal(SNAME("spawned"), node); + pending_spawn = ObjectID(); pending_buffer = nullptr; pending_buffer_size = 0; @@ -417,10 +413,17 @@ Error SceneReplicationInterface::on_despawn_receive(int p_from, const uint8_t *p Error err = rep_state->peer_del_remote(p_from, net_id, &node); ERR_FAIL_COND_V(err != OK, err); ERR_FAIL_COND_V(!node, ERR_BUG); + + MultiplayerSpawner *spawner = rep_state->get_spawner(node->get_instance_id()); + ERR_FAIL_COND_V(!spawner, ERR_DOES_NOT_EXIST); + ERR_FAIL_COND_V(p_from != spawner->get_multiplayer_authority(), ERR_UNAUTHORIZED); + if (node->get_parent() != nullptr) { node->get_parent()->remove_child(node); } node->queue_delete(); + spawner->emit_signal(SNAME("despawned"), node); + return OK; } @@ -431,7 +434,7 @@ void SceneReplicationInterface::_send_sync(int p_peer, uint64_t p_msec) { } MAKE_ROOM(sync_mtu); uint8_t *ptr = packet_cache.ptrw(); - ptr[0] = MultiplayerAPI::NETWORK_COMMAND_SYNC; + ptr[0] = SceneMultiplayer::NETWORK_COMMAND_SYNC; int ofs = 1; ofs += encode_uint16(rep_state->peer_sync_next(p_peer), &ptr[1]); // Can only send updates for already notified nodes. @@ -447,7 +450,7 @@ void SceneReplicationInterface::_send_sync(int p_peer, uint64_t p_msec) { uint32_t net_id = rep_state->get_net_id(oid); if (net_id == 0 || (net_id & 0x80000000)) { int path_id = 0; - bool verified = multiplayer->send_object_cache(sync, p_peer, path_id); + bool verified = multiplayer->get_path_cache()->send_object_cache(sync, p_peer, path_id); ERR_CONTINUE_MSG(path_id < 0, "This should never happen!"); if (net_id == 0) { // First time path based ID. @@ -499,7 +502,7 @@ Error SceneReplicationInterface::on_sync_receive(int p_from, const uint8_t *p_bu ofs += 4; Node *node = nullptr; if (net_id & 0x80000000) { - MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(multiplayer->get_cached_object(p_from, net_id & 0x7FFFFFFF)); + MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(multiplayer->get_path_cache()->get_cached_object(p_from, net_id & 0x7FFFFFFF)); ERR_FAIL_COND_V(!sync || sync->get_multiplayer_authority() != p_from, ERR_UNAUTHORIZED); node = sync->get_node(sync->get_root_path()); } else { diff --git a/scene/multiplayer/scene_replication_interface.h b/modules/multiplayer/scene_replication_interface.h index 9ddab2d383..8981647429 100644 --- a/scene/multiplayer/scene_replication_interface.h +++ b/modules/multiplayer/scene_replication_interface.h @@ -31,12 +31,14 @@ #ifndef SCENE_REPLICATION_INTERFACE_H #define SCENE_REPLICATION_INTERFACE_H -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" -#include "scene/multiplayer/scene_replication_state.h" +#include "scene_replication_state.h" -class SceneReplicationInterface : public MultiplayerReplicationInterface { - GDCLASS(SceneReplicationInterface, MultiplayerReplicationInterface); +class SceneMultiplayer; + +class SceneReplicationInterface : public RefCounted { + GDCLASS(SceneReplicationInterface, RefCounted); private: void _send_sync(int p_peer, uint64_t p_msec); @@ -50,7 +52,7 @@ private: void _free_remotes(int p_peer); Ref<SceneReplicationState> rep_state; - MultiplayerAPI *multiplayer = nullptr; + SceneMultiplayer *multiplayer = nullptr; PackedByteArray packet_cache; int sync_mtu = 1350; // Highly dependent on underlying protocol. @@ -59,26 +61,23 @@ private: const uint8_t *pending_buffer = nullptr; int pending_buffer_size = 0; -protected: - static MultiplayerReplicationInterface *_create(MultiplayerAPI *p_multiplayer); - public: static void make_default(); - virtual void on_reset() override; - virtual void on_peer_change(int p_id, bool p_connected) override; + void on_reset(); + void on_peer_change(int p_id, bool p_connected); - virtual Error on_spawn(Object *p_obj, Variant p_config) override; - virtual Error on_despawn(Object *p_obj, Variant p_config) override; - virtual Error on_replication_start(Object *p_obj, Variant p_config) override; - virtual Error on_replication_stop(Object *p_obj, Variant p_config) override; - virtual void on_network_process() override; + Error on_spawn(Object *p_obj, Variant p_config); + Error on_despawn(Object *p_obj, Variant p_config); + Error on_replication_start(Object *p_obj, Variant p_config); + Error on_replication_stop(Object *p_obj, Variant p_config); + void on_network_process(); - virtual Error on_spawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) override; - virtual Error on_despawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) override; - virtual Error on_sync_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) override; + Error on_spawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len); + Error on_despawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len); + Error on_sync_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len); - SceneReplicationInterface(MultiplayerAPI *p_multiplayer) { + SceneReplicationInterface(SceneMultiplayer *p_multiplayer) { rep_state.instantiate(); multiplayer = p_multiplayer; } diff --git a/scene/multiplayer/scene_replication_state.cpp b/modules/multiplayer/scene_replication_state.cpp index f6a51ff9c7..25442bb7fa 100644 --- a/scene/multiplayer/scene_replication_state.cpp +++ b/modules/multiplayer/scene_replication_state.cpp @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scene/multiplayer/scene_replication_state.h" +#include "scene_replication_state.h" -#include "core/multiplayer/multiplayer_api.h" -#include "scene/multiplayer/multiplayer_spawner.h" -#include "scene/multiplayer/multiplayer_synchronizer.h" #include "scene/scene_string_names.h" +#include "multiplayer_spawner.h" +#include "multiplayer_synchronizer.h" + SceneReplicationState::TrackedNode &SceneReplicationState::_track(const ObjectID &p_id) { if (!tracked_nodes.has(p_id)) { tracked_nodes[p_id] = TrackedNode(p_id); Node *node = Object::cast_to<Node>(ObjectDB::get_instance(p_id)); - node->connect(SceneStringNames::get_singleton()->tree_exited, callable_mp(this, &SceneReplicationState::_untrack), varray(p_id), Node::CONNECT_ONESHOT); + node->connect(SceneStringNames::get_singleton()->tree_exited, callable_mp(this, &SceneReplicationState::_untrack).bind(p_id), Node::CONNECT_ONESHOT); } return tracked_nodes[p_id]; } diff --git a/scene/multiplayer/scene_replication_state.h b/modules/multiplayer/scene_replication_state.h index 01b70b11b8..bdff6ae3b7 100644 --- a/scene/multiplayer/scene_replication_state.h +++ b/modules/multiplayer/scene_replication_state.h @@ -33,6 +33,9 @@ #include "core/object/ref_counted.h" +#include "multiplayer_spawner.h" +#include "multiplayer_synchronizer.h" + class MultiplayerSpawner; class MultiplayerSynchronizer; class Node; diff --git a/scene/multiplayer/scene_rpc_interface.cpp b/modules/multiplayer/scene_rpc_interface.cpp index 144a10c665..65090b9316 100644 --- a/scene/multiplayer/scene_rpc_interface.cpp +++ b/modules/multiplayer/scene_rpc_interface.cpp @@ -28,21 +28,28 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scene/multiplayer/scene_rpc_interface.h" +#include "scene_rpc_interface.h" #include "core/debugger/engine_debugger.h" #include "core/io/marshalls.h" -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" #include "scene/main/node.h" #include "scene/main/window.h" -MultiplayerRPCInterface *SceneRPCInterface::_create(MultiplayerAPI *p_multiplayer) { - return memnew(SceneRPCInterface(p_multiplayer)); -} +#include "scene_multiplayer.h" -void SceneRPCInterface::make_default() { - MultiplayerAPI::create_default_rpc_interface = _create; -} +// The RPC meta is composed by a single byte that contains (starting from the least significant bit): +// - `NetworkCommands` in the first four bits. +// - `NetworkNodeIdCompression` in the next 2 bits. +// - `NetworkNameIdCompression` in the next 1 bit. +// - `byte_only_or_no_args` in the next 1 bit. +#define NODE_ID_COMPRESSION_SHIFT SceneMultiplayer::CMD_FLAG_0_SHIFT +#define NAME_ID_COMPRESSION_SHIFT SceneMultiplayer::CMD_FLAG_2_SHIFT +#define BYTE_ONLY_OR_NO_ARGS_SHIFT SceneMultiplayer::CMD_FLAG_3_SHIFT + +#define NODE_ID_COMPRESSION_FLAG ((1 << NODE_ID_COMPRESSION_SHIFT) | (1 << (NODE_ID_COMPRESSION_SHIFT + 1))) +#define NAME_ID_COMPRESSION_FLAG (1 << NAME_ID_COMPRESSION_SHIFT) +#define BYTE_ONLY_OR_NO_ARGS_FLAG (1 << BYTE_ONLY_OR_NO_ARGS_SHIFT) #ifdef DEBUG_ENABLED _FORCE_INLINE_ void SceneRPCInterface::_profile_node_data(const String &p_what, ObjectID p_id) { @@ -67,50 +74,58 @@ int get_packet_len(uint32_t p_node_target, int p_packet_len) { } } -const Multiplayer::RPCConfig _get_rpc_config(const Node *p_node, const StringName &p_method, uint16_t &r_id) { - const Vector<Multiplayer::RPCConfig> node_config = p_node->get_node_rpc_methods(); - for (int i = 0; i < node_config.size(); i++) { - if (node_config[i].name == p_method) { - r_id = ((uint16_t)i) | (1 << 15); - return node_config[i]; - } +void SceneRPCInterface::_parse_rpc_config(const Variant &p_config, bool p_for_node, RPCConfigCache &r_cache) { + if (p_config.get_type() == Variant::NIL) { + return; } - if (p_node->get_script_instance()) { - const Vector<Multiplayer::RPCConfig> script_config = p_node->get_script_instance()->get_rpc_methods(); - for (int i = 0; i < script_config.size(); i++) { - if (script_config[i].name == p_method) { - r_id = (uint16_t)i; - return script_config[i]; - } + ERR_FAIL_COND(p_config.get_type() != Variant::DICTIONARY); + const Dictionary config = p_config; + Array names = config.keys(); + names.sort(); // Ensure ID order + for (int i = 0; i < names.size(); i++) { + ERR_CONTINUE(names[i].get_type() != Variant::STRING); + String name = names[i].operator String(); + ERR_CONTINUE(config[name].get_type() != Variant::DICTIONARY); + ERR_CONTINUE(!config[name].operator Dictionary().has("rpc_mode")); + Dictionary dict = config[name]; + RPCConfig cfg; + cfg.name = name; + cfg.rpc_mode = ((MultiplayerAPI::RPCMode)dict.get("rpc_mode", MultiplayerAPI::RPC_MODE_AUTHORITY).operator int()); + cfg.transfer_mode = ((MultiplayerPeer::TransferMode)dict.get("transfer_mode", MultiplayerPeer::TRANSFER_MODE_RELIABLE).operator int()); + cfg.call_local = dict.get("call_local", false).operator bool(); + cfg.channel = dict.get("channel", 0).operator int(); + uint16_t id = ((uint16_t)i); + if (p_for_node) { + id |= (1 << 15); } + r_cache.configs[id] = cfg; + r_cache.ids[name] = id; } - return Multiplayer::RPCConfig(); } -const Multiplayer::RPCConfig _get_rpc_config_by_id(Node *p_node, uint16_t p_id) { - Vector<Multiplayer::RPCConfig> config; - uint16_t id = p_id; - if (id & (1 << 15)) { - id = id & ~(1 << 15); - config = p_node->get_node_rpc_methods(); - } else if (p_node->get_script_instance()) { - config = p_node->get_script_instance()->get_rpc_methods(); +const SceneRPCInterface::RPCConfigCache &SceneRPCInterface::_get_node_config(const Node *p_node) { + const ObjectID oid = p_node->get_instance_id(); + if (rpc_cache.has(oid)) { + return rpc_cache[oid]; } - if (id < config.size()) { - return config[id]; + RPCConfigCache cache; + _parse_rpc_config(p_node->get_node_rpc_config(), true, cache); + if (p_node->get_script_instance()) { + _parse_rpc_config(p_node->get_script_instance()->get_rpc_config(), false, cache); } - return Multiplayer::RPCConfig(); + rpc_cache[oid] = cache; + return rpc_cache[oid]; } -_FORCE_INLINE_ bool _can_call_mode(Node *p_node, Multiplayer::RPCMode mode, int p_remote_id) { +_FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, int p_remote_id) { switch (mode) { - case Multiplayer::RPC_MODE_DISABLED: { + case MultiplayerAPI::RPC_MODE_DISABLED: { return false; } break; - case Multiplayer::RPC_MODE_ANY_PEER: { + case MultiplayerAPI::RPC_MODE_ANY_PEER: { return true; } break; - case Multiplayer::RPC_MODE_AUTHORITY: { + case MultiplayerAPI::RPC_MODE_AUTHORITY: { return !p_node->is_multiplayer_authority() && p_remote_id == p_node->get_multiplayer_authority(); } break; } @@ -118,19 +133,13 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, Multiplayer::RPCMode mode, int return false; } -String SceneRPCInterface::get_rpc_md5(const Object *p_obj) const { +String SceneRPCInterface::get_rpc_md5(const Object *p_obj) { const Node *node = Object::cast_to<Node>(p_obj); ERR_FAIL_COND_V(!node, ""); + const RPCConfigCache cache = _get_node_config(node); String rpc_list; - const Vector<Multiplayer::RPCConfig> node_config = node->get_node_rpc_methods(); - for (int i = 0; i < node_config.size(); i++) { - rpc_list += String(node_config[i].name); - } - if (node->get_script_instance()) { - const Vector<Multiplayer::RPCConfig> script_config = node->get_script_instance()->get_rpc_methods(); - for (int i = 0; i < script_config.size(); i++) { - rpc_list += String(script_config[i].name); - } + for (const KeyValue<uint16_t, RPCConfig> &config : cache.configs) { + rpc_list += String(config.value.name); } return rpc_list.md5_text(); } @@ -159,7 +168,7 @@ Node *SceneRPCInterface::_process_get_node(int p_from, const uint8_t *p_packet, return node; } else { // Use cached path. - return Object::cast_to<Node>(multiplayer->get_cached_object(p_from, p_node_target)); + return Object::cast_to<Node>(multiplayer->get_path_cache()->get_cached_object(p_from, p_node_target)); } } @@ -240,8 +249,9 @@ void SceneRPCInterface::_process_rpc(Node *p_node, const uint16_t p_rpc_method_i ERR_FAIL_COND_MSG(p_offset > p_packet_len, "Invalid packet received. Size too small."); // Check that remote can call the RPC on this node. - const Multiplayer::RPCConfig config = _get_rpc_config_by_id(p_node, p_rpc_method_id); - ERR_FAIL_COND(config.name == StringName()); + const RPCConfigCache &cache_config = _get_node_config(p_node); + ERR_FAIL_COND(!cache_config.configs.has(p_rpc_method_id)); + const RPCConfig &config = cache_config.configs[p_rpc_method_id]; bool can_call = _can_call_mode(p_node, config.rpc_mode, p_from); ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(config.name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)config.rpc_mode) + ", authority is " + itos(p_node->get_multiplayer_authority()) + "."); @@ -286,7 +296,7 @@ void SceneRPCInterface::_process_rpc(Node *p_node, const uint16_t p_rpc_method_i } } -void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const Multiplayer::RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount) { +void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount) { Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer(); ERR_FAIL_COND_MSG(peer.is_null(), "Attempt to call RPC without active multiplayer peer."); @@ -297,14 +307,14 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con ERR_FAIL_COND_MSG(p_argcount > 255, "Too many arguments (>255)."); if (p_to != 0 && !multiplayer->get_connected_peers().has(ABS(p_to))) { - ERR_FAIL_COND_MSG(p_to == peer->get_unique_id(), "Attempt to call RPC on yourself! Peer unique ID: " + itos(peer->get_unique_id()) + "."); + ERR_FAIL_COND_MSG(p_to == multiplayer->get_unique_id(), "Attempt to call RPC on yourself! Peer unique ID: " + itos(multiplayer->get_unique_id()) + "."); ERR_FAIL_MSG("Attempt to call RPC with unknown peer ID: " + itos(p_to) + "."); } // See if all peers have cached path (if so, call can be fast). int psc_id; - const bool has_all_peers = multiplayer->send_object_cache(p_from, p_to, psc_id); + const bool has_all_peers = multiplayer->get_path_cache()->send_object_cache(p_from, p_to, psc_id); // Create base packet, lots of hardcode because it must be tight. @@ -315,7 +325,7 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con packet_cache.resize(m_amount); // Encode meta. - uint8_t command_type = MultiplayerAPI::NETWORK_COMMAND_REMOTE_CALL; + uint8_t command_type = SceneMultiplayer::NETWORK_COMMAND_REMOTE_CALL; uint8_t node_id_compression = UINT8_MAX; uint8_t name_id_compression = UINT8_MAX; bool byte_only_or_no_args = false; @@ -426,7 +436,7 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con continue; // Continue, not for this peer. } - bool confirmed = multiplayer->is_cache_confirmed(from_path, P); + bool confirmed = multiplayer->get_path_cache()->is_cache_confirmed(from_path, P); peer->set_target_peer(P); // To this one specifically. @@ -443,22 +453,25 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con } } -void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { +Error SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer(); - ERR_FAIL_COND_MSG(!peer.is_valid(), "Trying to call an RPC while no multiplayer peer is active."); + ERR_FAIL_COND_V_MSG(!peer.is_valid(), ERR_UNCONFIGURED, "Trying to call an RPC while no multiplayer peer is active."); Node *node = Object::cast_to<Node>(p_obj); - ERR_FAIL_COND(!node); - ERR_FAIL_COND_MSG(!node->is_inside_tree(), "Trying to call an RPC on a node which is not inside SceneTree."); - ERR_FAIL_COND_MSG(peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a multiplayer peer which is not connected."); + ERR_FAIL_COND_V_MSG(!node || !node->is_inside_tree(), ERR_INVALID_PARAMETER, "The object must be a valid Node inside the SceneTree"); + ERR_FAIL_COND_V_MSG(peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, ERR_CONNECTION_ERROR, "Trying to call an RPC via a multiplayer peer which is not connected."); - int node_id = peer->get_unique_id(); + int caller_id = multiplayer->get_unique_id(); bool call_local_native = false; bool call_local_script = false; - uint16_t rpc_id = UINT16_MAX; - const Multiplayer::RPCConfig config = _get_rpc_config(node, p_method, rpc_id); - ERR_FAIL_COND_MSG(config.name == StringName(), + const RPCConfigCache &config_cache = _get_node_config(node); + uint16_t rpc_id = config_cache.ids.has(p_method) ? config_cache.ids[p_method] : UINT16_MAX; + ERR_FAIL_COND_V_MSG(rpc_id == UINT16_MAX, ERR_INVALID_PARAMETER, vformat("Unable to get the RPC configuration for the function \"%s\" at path: \"%s\". This happens when the method is missing or not marked for RPCs in the local script.", p_method, node->get_path())); - if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) { + const RPCConfig &config = config_cache.configs[rpc_id]; + + ERR_FAIL_COND_V_MSG(p_peer_id == caller_id && !config.call_local, ERR_INVALID_PARAMETER, "RPC '" + p_method + "' on yourself is not allowed by selected mode."); + + if (p_peer_id == 0 || p_peer_id == caller_id || (p_peer_id < 0 && p_peer_id != -caller_id)) { if (rpc_id & (1 << 15)) { call_local_native = config.call_local; } else { @@ -466,7 +479,7 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m } } - if (p_peer_id != node_id) { + if (p_peer_id != caller_id) { #ifdef DEBUG_ENABLED _profile_node_data("rpc_out", node->get_instance_id()); #endif @@ -477,7 +490,7 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m if (call_local_native) { Callable::CallError ce; - multiplayer->set_remote_sender_override(peer->get_unique_id()); + multiplayer->set_remote_sender_override(multiplayer->get_unique_id()); node->callp(p_method, p_arg, p_argcount, ce); multiplayer->set_remote_sender_override(0); @@ -485,7 +498,7 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m String error = Variant::get_call_error_text(node, p_method, p_arg, p_argcount, ce); error = "rpc() aborted in local call: - " + error + "."; ERR_PRINT(error); - return; + return FAILED; } } @@ -493,7 +506,7 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m Callable::CallError ce; ce.error = Callable::CallError::CALL_OK; - multiplayer->set_remote_sender_override(peer->get_unique_id()); + multiplayer->set_remote_sender_override(multiplayer->get_unique_id()); node->get_script_instance()->callp(p_method, p_arg, p_argcount, ce); multiplayer->set_remote_sender_override(0); @@ -501,9 +514,8 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m String error = Variant::get_call_error_text(node, p_method, p_arg, p_argcount, ce); error = "rpc() aborted in script local call: - " + error + "."; ERR_PRINT(error); - return; + return FAILED; } } - - ERR_FAIL_COND_MSG(p_peer_id == node_id && !config.call_local, "RPC '" + p_method + "' on yourself is not allowed by selected mode."); + return OK; } diff --git a/scene/multiplayer/scene_rpc_interface.h b/modules/multiplayer/scene_rpc_interface.h index 86e1d0d280..aa9be525a2 100644 --- a/scene/multiplayer/scene_rpc_interface.h +++ b/modules/multiplayer/scene_rpc_interface.h @@ -31,13 +31,40 @@ #ifndef SCENE_RPC_INTERFACE_H #define SCENE_RPC_INTERFACE_H -#include "core/multiplayer/multiplayer.h" -#include "core/multiplayer/multiplayer_api.h" +#include "core/object/ref_counted.h" +#include "scene/main/multiplayer_api.h" -class SceneRPCInterface : public MultiplayerRPCInterface { - GDCLASS(SceneRPCInterface, MultiplayerRPCInterface); +class SceneMultiplayer; +class Node; + +class SceneRPCInterface : public RefCounted { + GDCLASS(SceneRPCInterface, RefCounted); private: + struct RPCConfig { + StringName name; + MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; + bool call_local = false; + MultiplayerPeer::TransferMode transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE; + int channel = 0; + + bool operator==(RPCConfig const &p_other) const { + return name == p_other.name; + } + }; + + struct RPCConfigCache { + HashMap<uint16_t, RPCConfig> configs; + HashMap<StringName, uint16_t> ids; + }; + + struct SortRPCConfig { + StringName::AlphCompare compare; + bool operator()(const RPCConfig &p_a, const RPCConfig &p_b) const { + return compare(p_a.name, p_b.name); + } + }; + enum NetworkNodeIdCompression { NETWORK_NODE_ID_COMPRESSION_8 = 0, NETWORK_NODE_ID_COMPRESSION_16, @@ -49,43 +76,27 @@ private: NETWORK_NAME_ID_COMPRESSION_16, }; - // The RPC meta is composed by a single byte that contains (starting from the least significant bit): - // - `NetworkCommands` in the first four bits. - // - `NetworkNodeIdCompression` in the next 2 bits. - // - `NetworkNameIdCompression` in the next 1 bit. - // - `byte_only_or_no_args` in the next 1 bit. - enum { - NODE_ID_COMPRESSION_SHIFT = MultiplayerAPI::CMD_FLAG_0_SHIFT, // 2 bits for this. - NAME_ID_COMPRESSION_SHIFT = MultiplayerAPI::CMD_FLAG_2_SHIFT, - BYTE_ONLY_OR_NO_ARGS_SHIFT = MultiplayerAPI::CMD_FLAG_3_SHIFT, - }; - - enum { - NODE_ID_COMPRESSION_FLAG = (1 << NODE_ID_COMPRESSION_SHIFT) | (1 << (NODE_ID_COMPRESSION_SHIFT + 1)), // 2 bits for this. - NAME_ID_COMPRESSION_FLAG = (1 << NAME_ID_COMPRESSION_SHIFT), - BYTE_ONLY_OR_NO_ARGS_FLAG = (1 << BYTE_ONLY_OR_NO_ARGS_SHIFT), - }; - - MultiplayerAPI *multiplayer = nullptr; + SceneMultiplayer *multiplayer = nullptr; Vector<uint8_t> packet_cache; -protected: - static MultiplayerRPCInterface *_create(MultiplayerAPI *p_multiplayer); + HashMap<ObjectID, RPCConfigCache> rpc_cache; +protected: _FORCE_INLINE_ void _profile_node_data(const String &p_what, ObjectID p_id); void _process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset); - void _send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const Multiplayer::RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount); + void _send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount); Node *_process_get_node(int p_from, const uint8_t *p_packet, uint32_t p_node_target, int p_packet_len); -public: - static void make_default(); + void _parse_rpc_config(const Variant &p_config, bool p_for_node, RPCConfigCache &r_cache); + const RPCConfigCache &_get_node_config(const Node *p_node); - virtual void rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) override; - virtual void process_rpc(int p_from, const uint8_t *p_packet, int p_packet_len) override; - virtual String get_rpc_md5(const Object *p_obj) const override; +public: + Error rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount); + void process_rpc(int p_from, const uint8_t *p_packet, int p_packet_len); + String get_rpc_md5(const Object *p_obj); - SceneRPCInterface(MultiplayerAPI *p_multiplayer) { multiplayer = p_multiplayer; } + SceneRPCInterface(SceneMultiplayer *p_multiplayer) { multiplayer = p_multiplayer; } }; #endif // SCENE_RPC_INTERFACE_H diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index bcbc721dbb..2cdb5b7cb4 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -249,8 +249,10 @@ Array GodotNavigationServer::map_get_regions(RID p_map) const { Array regions_rids; const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, regions_rids); - for (NavRegion *region : map->get_regions()) { - regions_rids.push_back(region->get_self()); + const LocalVector<NavRegion *> regions = map->get_regions(); + regions_rids.resize(regions.size()); + for (uint32_t i = 0; i < regions.size(); i++) { + regions_rids[i] = regions[i]->get_self(); } return regions_rids; } @@ -259,8 +261,10 @@ Array GodotNavigationServer::map_get_agents(RID p_map) const { Array agents_rids; const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, agents_rids); - for (RvoAgent *agent : map->get_agents()) { - agents_rids.push_back(agent->get_self()); + const LocalVector<RvoAgent *> agents = map->get_agents(); + agents_rids.resize(agents.size()); + for (uint32_t i = 0; i < agents.size(); i++) { + agents_rids[i] = agents[i]->get_self(); } return agents_rids; } @@ -539,15 +543,15 @@ COMMAND_1(free, RID, p_object) { NavMap *map = map_owner.get_or_null(p_object); // Removes any assigned region - std::vector<NavRegion *> regions = map->get_regions(); - for (size_t i(0); i < regions.size(); i++) { + LocalVector<NavRegion *> regions = map->get_regions(); + for (uint32_t i = 0; i < regions.size(); i++) { map->remove_region(regions[i]); regions[i]->set_map(nullptr); } // Remove any assigned agent - std::vector<RvoAgent *> agents = map->get_agents(); - for (size_t i(0); i < agents.size(); i++) { + LocalVector<RvoAgent *> agents = map->get_agents(); + for (uint32_t i = 0; i < agents.size(); i++) { map->remove_agent(agents[i]); agents[i]->set_map(nullptr); } diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index 8e7e99888c..da1f8cba0b 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -69,7 +69,7 @@ class GodotNavigationServer : public NavigationServer3D { /// Mutex used to make any operation threadsafe. Mutex operations_mutex; - std::vector<SetCommand *> commands; + LocalVector<SetCommand *> commands; mutable RID_Owner<NavMap> map_owner; mutable RID_Owner<NavRegion> region_owner; diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 46daa54239..49029b5513 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -117,7 +117,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p } // List of all reachable navigation polys. - std::vector<gd::NavigationPoly> navigation_polys; + LocalVector<gd::NavigationPoly> navigation_polys; navigation_polys.reserve(polygons.size() * 0.75); // Add the start polygon to the reachable navigation polygons. @@ -170,20 +170,18 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p const Vector3 new_entry = Geometry3D::get_closest_point_to_segment(least_cost_poly->entry, pathway); const float new_distance = (least_cost_poly->entry.distance_to(new_entry) * region_travel_cost) + region_enter_cost + least_cost_poly->traveled_distance; - const std::vector<gd::NavigationPoly>::iterator it = std::find( - navigation_polys.begin(), - navigation_polys.end(), - gd::NavigationPoly(connection.polygon)); + int64_t already_visited_polygon_index = navigation_polys.find(gd::NavigationPoly(connection.polygon)); - if (it != navigation_polys.end()) { + if (already_visited_polygon_index != -1) { // Polygon already visited, check if we can reduce the travel cost. - if (new_distance < it->traveled_distance) { - it->back_navigation_poly_id = least_cost_id; - it->back_navigation_edge = connection.edge; - it->back_navigation_edge_pathway_start = connection.pathway_start; - it->back_navigation_edge_pathway_end = connection.pathway_end; - it->traveled_distance = new_distance; - it->entry = new_entry; + gd::NavigationPoly &avp = navigation_polys[already_visited_polygon_index]; + if (new_distance < avp.traveled_distance) { + avp.back_navigation_poly_id = least_cost_id; + avp.back_navigation_edge = connection.edge; + avp.back_navigation_edge_pathway_start = connection.pathway_start; + avp.back_navigation_edge_pathway_end = connection.pathway_end; + avp.traveled_distance = new_distance; + avp.entry = new_entry; } } else { // Add the neighbour polygon to the reachable ones. @@ -470,15 +468,15 @@ void NavMap::add_region(NavRegion *p_region) { } void NavMap::remove_region(NavRegion *p_region) { - const std::vector<NavRegion *>::iterator it = std::find(regions.begin(), regions.end(), p_region); - if (it != regions.end()) { - regions.erase(it); + int64_t region_index = regions.find(p_region); + if (region_index != -1) { + regions.remove_at_unordered(region_index); regenerate_links = true; } } bool NavMap::has_agent(RvoAgent *agent) const { - return std::find(agents.begin(), agents.end(), agent) != agents.end(); + return (agents.find(agent) != -1); } void NavMap::add_agent(RvoAgent *agent) { @@ -490,15 +488,15 @@ void NavMap::add_agent(RvoAgent *agent) { void NavMap::remove_agent(RvoAgent *agent) { remove_agent_as_controlled(agent); - const std::vector<RvoAgent *>::iterator it = std::find(agents.begin(), agents.end(), agent); - if (it != agents.end()) { - agents.erase(it); + int64_t agent_index = agents.find(agent); + if (agent_index != -1) { + agents.remove_at_unordered(agent_index); agents_dirty = true; } } void NavMap::set_agent_as_controlled(RvoAgent *agent) { - const bool exist = std::find(controlled_agents.begin(), controlled_agents.end(), agent) != controlled_agents.end(); + const bool exist = (controlled_agents.find(agent) != -1); if (!exist) { ERR_FAIL_COND(!has_agent(agent)); controlled_agents.push_back(agent); @@ -506,22 +504,23 @@ void NavMap::set_agent_as_controlled(RvoAgent *agent) { } void NavMap::remove_agent_as_controlled(RvoAgent *agent) { - const std::vector<RvoAgent *>::iterator it = std::find(controlled_agents.begin(), controlled_agents.end(), agent); - if (it != controlled_agents.end()) { - controlled_agents.erase(it); + int64_t active_avoidance_agent_index = controlled_agents.find(agent); + if (active_avoidance_agent_index != -1) { + controlled_agents.remove_at_unordered(active_avoidance_agent_index); + agents_dirty = true; } } void NavMap::sync() { // Check if we need to update the links. if (regenerate_polygons) { - for (size_t r(0); r < regions.size(); r++) { + for (uint32_t r = 0; r < regions.size(); r++) { regions[r]->scratch_polygons(); } regenerate_links = true; } - for (size_t r(0); r < regions.size(); r++) { + for (uint32_t r = 0; r < regions.size(); r++) { if (regions[r]->sync()) { regenerate_links = true; } @@ -529,33 +528,33 @@ void NavMap::sync() { if (regenerate_links) { // Remove regions connections. - for (size_t r(0); r < regions.size(); r++) { + for (uint32_t r = 0; r < regions.size(); r++) { regions[r]->get_connections().clear(); } // Resize the polygon count. int count = 0; - for (size_t r(0); r < regions.size(); r++) { + for (uint32_t r = 0; r < regions.size(); r++) { count += regions[r]->get_polygons().size(); } polygons.resize(count); // Copy all region polygons in the map. count = 0; - for (size_t r(0); r < regions.size(); r++) { - std::copy( - regions[r]->get_polygons().data(), - regions[r]->get_polygons().data() + regions[r]->get_polygons().size(), - polygons.begin() + count); + for (uint32_t r = 0; r < regions.size(); r++) { + const LocalVector<gd::Polygon> &polygons_source = regions[r]->get_polygons(); + for (uint32_t n = 0; n < polygons_source.size(); n++) { + polygons[count + n] = polygons_source[n]; + } count += regions[r]->get_polygons().size(); } // Group all edges per key. HashMap<gd::EdgeKey, Vector<gd::Edge::Connection>, gd::EdgeKey> connections; - for (size_t poly_id(0); poly_id < polygons.size(); poly_id++) { + for (uint32_t poly_id = 0; poly_id < polygons.size(); poly_id++) { gd::Polygon &poly(polygons[poly_id]); - for (size_t p(0); p < poly.points.size(); p++) { + for (uint32_t p = 0; p < poly.points.size(); p++) { int next_point = (p + 1) % poly.points.size(); gd::EdgeKey ek(poly.points[p].key, poly.points[next_point].key); @@ -662,6 +661,7 @@ void NavMap::sync() { // Update agents tree. if (agents_dirty) { + // cannot use LocalVector here as RVO library expects std::vector to build KdTree std::vector<RVO::Agent *> raw_agents; raw_agents.reserve(agents.size()); for (size_t i(0); i < agents.size(); i++) { @@ -683,7 +683,7 @@ void NavMap::compute_single_step(uint32_t index, RvoAgent **agent) { void NavMap::step(real_t p_deltatime) { deltatime = p_deltatime; if (controlled_agents.size() > 0) { - WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &NavMap::compute_single_step, controlled_agents.data(), controlled_agents.size(), -1, true, SNAME("NavigationMapAgents")); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &NavMap::compute_single_step, controlled_agents.ptr(), controlled_agents.size(), -1, true, SNAME("NavigationMapAgents")); WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); } } @@ -694,7 +694,7 @@ void NavMap::dispatch_callbacks() { } } -void NavMap::clip_path(const std::vector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const { +void NavMap::clip_path(const LocalVector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const { Vector3 from = path[path.size() - 1]; if (from.is_equal_approx(p_to_point)) { diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h index 98a5c24b3e..e50a1afbe9 100644 --- a/modules/navigation/nav_map.h +++ b/modules/navigation/nav_map.h @@ -58,10 +58,10 @@ class NavMap : public NavRid { bool regenerate_polygons = true; bool regenerate_links = true; - std::vector<NavRegion *> regions; + LocalVector<NavRegion *> regions; /// Map polygons - std::vector<gd::Polygon> polygons; + LocalVector<gd::Polygon> polygons; /// Rvo world RVO::KdTree rvo; @@ -70,10 +70,10 @@ class NavMap : public NavRid { bool agents_dirty = false; /// All the Agents (even the controlled one) - std::vector<RvoAgent *> agents; + LocalVector<RvoAgent *> agents; /// Controlled agents - std::vector<RvoAgent *> controlled_agents; + LocalVector<RvoAgent *> controlled_agents; /// Physics delta time real_t deltatime = 0.0; @@ -111,14 +111,14 @@ public: void add_region(NavRegion *p_region); void remove_region(NavRegion *p_region); - const std::vector<NavRegion *> &get_regions() const { + const LocalVector<NavRegion *> &get_regions() const { return regions; } bool has_agent(RvoAgent *agent) const; void add_agent(RvoAgent *agent); void remove_agent(RvoAgent *agent); - const std::vector<RvoAgent *> &get_agents() const { + const LocalVector<RvoAgent *> &get_agents() const { return agents; } @@ -135,7 +135,7 @@ public: private: void compute_single_step(uint32_t index, RvoAgent **agent); - void clip_path(const std::vector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const; + void clip_path(const LocalVector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const; }; #endif // NAV_MAP_H diff --git a/modules/navigation/nav_region.h b/modules/navigation/nav_region.h index 484856ae36..c9d2d80f6c 100644 --- a/modules/navigation/nav_region.h +++ b/modules/navigation/nav_region.h @@ -53,7 +53,7 @@ class NavRegion : public NavRid { bool polygons_dirty = true; /// Cache - std::vector<gd::Polygon> polygons; + LocalVector<gd::Polygon> polygons; public: NavRegion() {} @@ -93,7 +93,7 @@ public: Vector3 get_connection_pathway_start(int p_connection_id) const; Vector3 get_connection_pathway_end(int p_connection_id) const; - std::vector<gd::Polygon> const &get_polygons() const { + LocalVector<gd::Polygon> const &get_polygons() const { return polygons; } diff --git a/modules/navigation/nav_utils.h b/modules/navigation/nav_utils.h index a9f4e0e2fc..47f04b6a75 100644 --- a/modules/navigation/nav_utils.h +++ b/modules/navigation/nav_utils.h @@ -34,7 +34,7 @@ #include "core/math/vector3.h" #include "core/templates/hash_map.h" #include "core/templates/hashfuncs.h" -#include "core/templates/vector.h" +#include "core/templates/local_vector.h" #include <vector> class NavRegion; @@ -96,13 +96,13 @@ struct Polygon { NavRegion *owner = nullptr; /// The points of this `Polygon` - std::vector<Point> points; + LocalVector<Point> points; /// Are the points clockwise ? bool clockwise; /// The edges of this `Polygon` - std::vector<Edge> edges; + LocalVector<Edge> edges; /// The center of this `Polygon` Vector3 center; @@ -124,6 +124,8 @@ struct NavigationPoly { /// The distance to the destination. float traveled_distance = 0.0; + NavigationPoly() { poly = nullptr; } + NavigationPoly(const Polygon *p_poly) : poly(p_poly) {} diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index 6e8ac77f79..848e554fb0 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -42,6 +42,7 @@ #include "scene/resources/concave_polygon_shape_3d.h" #include "scene/resources/convex_polygon_shape_3d.h" #include "scene/resources/cylinder_shape_3d.h" +#include "scene/resources/height_map_shape_3d.h" #include "scene/resources/primitive_meshes.h" #include "scene/resources/shape_3d.h" #include "scene/resources/sphere_shape_3d.h" @@ -275,6 +276,50 @@ void NavigationMeshGenerator::_parse_geometry(const Transform3D &p_navmesh_trans _add_faces(faces, transform, p_vertices, p_indices); } } + + HeightMapShape3D *heightmap_shape = Object::cast_to<HeightMapShape3D>(*s); + if (heightmap_shape) { + int heightmap_depth = heightmap_shape->get_map_depth(); + int heightmap_width = heightmap_shape->get_map_width(); + + if (heightmap_depth >= 2 && heightmap_width >= 2) { + const Vector<real_t> &map_data = heightmap_shape->get_map_data(); + + Vector2 heightmap_gridsize(heightmap_width - 1, heightmap_depth - 1); + Vector2 start = heightmap_gridsize * -0.5; + + Vector<Vector3> vertex_array; + vertex_array.resize((heightmap_depth - 1) * (heightmap_width - 1) * 6); + int map_data_current_index = 0; + + for (int d = 0; d < heightmap_depth - 1; d++) { + for (int w = 0; w < heightmap_width - 1; w++) { + if (map_data_current_index + 1 + heightmap_depth < map_data.size()) { + float top_left_height = map_data[map_data_current_index]; + float top_right_height = map_data[map_data_current_index + 1]; + float bottom_left_height = map_data[map_data_current_index + heightmap_depth]; + float bottom_right_height = map_data[map_data_current_index + 1 + heightmap_depth]; + + Vector3 top_left = Vector3(start.x + w, top_left_height, start.y + d); + Vector3 top_right = Vector3(start.x + w + 1.0, top_right_height, start.y + d); + Vector3 bottom_left = Vector3(start.x + w, bottom_left_height, start.y + d + 1.0); + Vector3 bottom_right = Vector3(start.x + w + 1.0, bottom_right_height, start.y + d + 1.0); + + vertex_array.push_back(top_right); + vertex_array.push_back(bottom_left); + vertex_array.push_back(top_left); + vertex_array.push_back(top_right); + vertex_array.push_back(bottom_right); + vertex_array.push_back(bottom_left); + } + map_data_current_index += 1; + } + } + if (vertex_array.size() > 0) { + _add_faces(vertex_array, transform, p_vertices, p_indices); + } + } + } } } } @@ -362,6 +407,50 @@ void NavigationMeshGenerator::_parse_geometry(const Transform3D &p_navmesh_trans PackedVector3Array faces = Variant(dict["faces"]); _add_faces(faces, shapes[i], p_vertices, p_indices); } break; + case PhysicsServer3D::SHAPE_HEIGHTMAP: { + Dictionary dict = data; + ///< dict( int:"width", int:"depth",float:"cell_size", float_array:"heights" + int heightmap_depth = dict["depth"]; + int heightmap_width = dict["width"]; + + if (heightmap_depth >= 2 && heightmap_width >= 2) { + const Vector<real_t> &map_data = dict["heights"]; + + Vector2 heightmap_gridsize(heightmap_width - 1, heightmap_depth - 1); + Vector2 start = heightmap_gridsize * -0.5; + + Vector<Vector3> vertex_array; + vertex_array.resize((heightmap_depth - 1) * (heightmap_width - 1) * 6); + int map_data_current_index = 0; + + for (int d = 0; d < heightmap_depth - 1; d++) { + for (int w = 0; w < heightmap_width - 1; w++) { + if (map_data_current_index + 1 + heightmap_depth < map_data.size()) { + float top_left_height = map_data[map_data_current_index]; + float top_right_height = map_data[map_data_current_index + 1]; + float bottom_left_height = map_data[map_data_current_index + heightmap_depth]; + float bottom_right_height = map_data[map_data_current_index + 1 + heightmap_depth]; + + Vector3 top_left = Vector3(start.x + w, top_left_height, start.y + d); + Vector3 top_right = Vector3(start.x + w + 1.0, top_right_height, start.y + d); + Vector3 bottom_left = Vector3(start.x + w, bottom_left_height, start.y + d + 1.0); + Vector3 bottom_right = Vector3(start.x + w + 1.0, bottom_right_height, start.y + d + 1.0); + + vertex_array.push_back(top_right); + vertex_array.push_back(bottom_left); + vertex_array.push_back(top_left); + vertex_array.push_back(top_right); + vertex_array.push_back(bottom_right); + vertex_array.push_back(bottom_left); + } + map_data_current_index += 1; + } + } + if (vertex_array.size() > 0) { + _add_faces(vertex_array, shapes[i], p_vertices, p_indices); + } + } + } break; default: { WARN_PRINT("Unsupported collision shape type."); } break; diff --git a/modules/ogg/config.py b/modules/ogg/config.py index 5a417ba8dd..f7ec4de6be 100644 --- a/modules/ogg/config.py +++ b/modules/ogg/config.py @@ -8,8 +8,8 @@ def configure(env): def get_doc_classes(): return [ - "OGGPacketSequence", - "OGGPacketSequencePlayback", + "OggPacketSequence", + "OggPacketSequencePlayback", ] diff --git a/modules/ogg/doc_classes/OGGPacketSequence.xml b/modules/ogg/doc_classes/OggPacketSequence.xml index bff3691ce0..d3bd4455d8 100644 --- a/modules/ogg/doc_classes/OGGPacketSequence.xml +++ b/modules/ogg/doc_classes/OggPacketSequence.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OGGPacketSequence" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OggPacketSequence" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> - A sequence of OGG packets. + A sequence of Ogg packets. </brief_description> <description> - A sequence of OGG packets. + A sequence of Ogg packets. </description> <tutorials> </tutorials> @@ -21,7 +21,7 @@ Contains the granule positions for each page in this packet sequence. </member> <member name="packet_data" type="Array" setter="set_packet_data" getter="get_packet_data" default="[]"> - Contains the raw packets that make up this OGGPacketSequence. + Contains the raw packets that make up this OggPacketSequence. </member> <member name="sampling_rate" type="float" setter="set_sampling_rate" getter="get_sampling_rate" default="0.0"> Holds sample rate information about this sequence. Must be set by another class that actually understands the codec. diff --git a/modules/ogg/doc_classes/OGGPacketSequencePlayback.xml b/modules/ogg/doc_classes/OggPacketSequencePlayback.xml index 11fc1f4cb6..5c0d75278b 100644 --- a/modules/ogg/doc_classes/OGGPacketSequencePlayback.xml +++ b/modules/ogg/doc_classes/OggPacketSequencePlayback.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OGGPacketSequencePlayback" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OggPacketSequencePlayback" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> </brief_description> <description> diff --git a/modules/ogg/ogg_packet_sequence.cpp b/modules/ogg/ogg_packet_sequence.cpp index e18fa9e590..de8bf4a087 100644 --- a/modules/ogg/ogg_packet_sequence.cpp +++ b/modules/ogg/ogg_packet_sequence.cpp @@ -31,7 +31,7 @@ #include "ogg_packet_sequence.h" #include "core/variant/typed_array.h" -void OGGPacketSequence::push_page(int64_t p_granule_pos, const Vector<PackedByteArray> &p_data) { +void OggPacketSequence::push_page(int64_t p_granule_pos, const Vector<PackedByteArray> &p_data) { Vector<PackedByteArray> data_stored; for (int i = 0; i < p_data.size(); i++) { data_stored.push_back(p_data[i]); @@ -41,7 +41,7 @@ void OGGPacketSequence::push_page(int64_t p_granule_pos, const Vector<PackedByte data_version++; } -void OGGPacketSequence::set_packet_data(const Array &p_data) { +void OggPacketSequence::set_packet_data(const Array &p_data) { data_version++; // Update the data version so old playbacks know that they can't rely on us anymore. page_data.clear(); for (int page_idx = 0; page_idx < p_data.size(); page_idx++) { @@ -54,7 +54,7 @@ void OGGPacketSequence::set_packet_data(const Array &p_data) { } } -Array OGGPacketSequence::get_packet_data() const { +Array OggPacketSequence::get_packet_data() const { Array ret; for (const Vector<PackedByteArray> &page : page_data) { Array page_variant; @@ -66,7 +66,7 @@ Array OGGPacketSequence::get_packet_data() const { return ret; } -void OGGPacketSequence::set_packet_granule_positions(const Array &p_granule_positions) { +void OggPacketSequence::set_packet_granule_positions(const Array &p_granule_positions) { data_version++; // Update the data version so old playbacks know that they can't rely on us anymore. page_granule_positions.clear(); for (int page_idx = 0; page_idx < p_granule_positions.size(); page_idx++) { @@ -75,7 +75,7 @@ void OGGPacketSequence::set_packet_granule_positions(const Array &p_granule_posi } } -Array OGGPacketSequence::get_packet_granule_positions() const { +Array OggPacketSequence::get_packet_granule_positions() const { Array ret; for (int64_t granule_pos : page_granule_positions) { ret.push_back(granule_pos); @@ -83,22 +83,22 @@ Array OGGPacketSequence::get_packet_granule_positions() const { return ret; } -void OGGPacketSequence::set_sampling_rate(float p_sampling_rate) { +void OggPacketSequence::set_sampling_rate(float p_sampling_rate) { sampling_rate = p_sampling_rate; } -float OGGPacketSequence::get_sampling_rate() const { +float OggPacketSequence::get_sampling_rate() const { return sampling_rate; } -int64_t OGGPacketSequence::get_final_granule_pos() const { +int64_t OggPacketSequence::get_final_granule_pos() const { if (!page_granule_positions.is_empty()) { return page_granule_positions[page_granule_positions.size() - 1]; } return -1; } -float OGGPacketSequence::get_length() const { +float OggPacketSequence::get_length() const { int64_t granule_pos = get_final_granule_pos(); if (granule_pos < 0) { return 0; @@ -106,33 +106,33 @@ float OGGPacketSequence::get_length() const { return granule_pos / sampling_rate; } -Ref<OGGPacketSequencePlayback> OGGPacketSequence::instantiate_playback() { - Ref<OGGPacketSequencePlayback> playback; +Ref<OggPacketSequencePlayback> OggPacketSequence::instantiate_playback() { + Ref<OggPacketSequencePlayback> playback; playback.instantiate(); - playback->ogg_packet_sequence = Ref<OGGPacketSequence>(this); + playback->ogg_packet_sequence = Ref<OggPacketSequence>(this); playback->data_version = data_version; return playback; } -void OGGPacketSequence::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_packet_data", "packet_data"), &OGGPacketSequence::set_packet_data); - ClassDB::bind_method(D_METHOD("get_packet_data"), &OGGPacketSequence::get_packet_data); +void OggPacketSequence::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_packet_data", "packet_data"), &OggPacketSequence::set_packet_data); + ClassDB::bind_method(D_METHOD("get_packet_data"), &OggPacketSequence::get_packet_data); - ClassDB::bind_method(D_METHOD("set_packet_granule_positions", "granule_positions"), &OGGPacketSequence::set_packet_granule_positions); - ClassDB::bind_method(D_METHOD("get_packet_granule_positions"), &OGGPacketSequence::get_packet_granule_positions); + ClassDB::bind_method(D_METHOD("set_packet_granule_positions", "granule_positions"), &OggPacketSequence::set_packet_granule_positions); + ClassDB::bind_method(D_METHOD("get_packet_granule_positions"), &OggPacketSequence::get_packet_granule_positions); - ClassDB::bind_method(D_METHOD("set_sampling_rate", "sampling_rate"), &OGGPacketSequence::set_sampling_rate); - ClassDB::bind_method(D_METHOD("get_sampling_rate"), &OGGPacketSequence::get_sampling_rate); + ClassDB::bind_method(D_METHOD("set_sampling_rate", "sampling_rate"), &OggPacketSequence::set_sampling_rate); + ClassDB::bind_method(D_METHOD("get_sampling_rate"), &OggPacketSequence::get_sampling_rate); - ClassDB::bind_method(D_METHOD("get_length"), &OGGPacketSequence::get_length); + ClassDB::bind_method(D_METHOD("get_length"), &OggPacketSequence::get_length); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "packet_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_data", "get_packet_data"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "granule_positions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_granule_positions", "get_packet_granule_positions"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sampling_rate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_sampling_rate", "get_sampling_rate"); } -bool OGGPacketSequencePlayback::next_ogg_packet(ogg_packet **p_packet) const { +bool OggPacketSequencePlayback::next_ogg_packet(ogg_packet **p_packet) const { ERR_FAIL_COND_V(data_version != ogg_packet_sequence->data_version, false); ERR_FAIL_COND_V(ogg_packet_sequence->page_data.is_empty(), false); ERR_FAIL_COND_V(ogg_packet_sequence->page_granule_positions.is_empty(), false); @@ -161,7 +161,7 @@ bool OGGPacketSequencePlayback::next_ogg_packet(ogg_packet **p_packet) const { return true; } -uint32_t OGGPacketSequencePlayback::seek_page_internal(int64_t granule, uint32_t after_page_inclusive, uint32_t before_page_inclusive) { +uint32_t OggPacketSequencePlayback::seek_page_internal(int64_t granule, uint32_t after_page_inclusive, uint32_t before_page_inclusive) { // FIXME: This function needs better corner case handling. if (before_page_inclusive == after_page_inclusive) { return before_page_inclusive; @@ -198,7 +198,7 @@ uint32_t OGGPacketSequencePlayback::seek_page_internal(int64_t granule, uint32_t } } -bool OGGPacketSequencePlayback::seek_page(int64_t p_granule_pos) { +bool OggPacketSequencePlayback::seek_page(int64_t p_granule_pos) { int correct_page = seek_page_internal(p_granule_pos, 0, ogg_packet_sequence->page_data.size() - 1); if (correct_page == -1) { return false; @@ -213,10 +213,10 @@ bool OGGPacketSequencePlayback::seek_page(int64_t p_granule_pos) { return true; } -OGGPacketSequencePlayback::OGGPacketSequencePlayback() { +OggPacketSequencePlayback::OggPacketSequencePlayback() { packet = new ogg_packet(); } -OGGPacketSequencePlayback::~OGGPacketSequencePlayback() { +OggPacketSequencePlayback::~OggPacketSequencePlayback() { delete packet; } diff --git a/modules/ogg/ogg_packet_sequence.h b/modules/ogg/ogg_packet_sequence.h index 76b673c6ac..efd3b64a39 100644 --- a/modules/ogg/ogg_packet_sequence.h +++ b/modules/ogg/ogg_packet_sequence.h @@ -38,12 +38,12 @@ #include "core/variant/variant.h" #include "thirdparty/libogg/ogg/ogg.h" -class OGGPacketSequencePlayback; +class OggPacketSequencePlayback; -class OGGPacketSequence : public Resource { - GDCLASS(OGGPacketSequence, Resource); +class OggPacketSequence : public Resource { + GDCLASS(OggPacketSequence, Resource); - friend class OGGPacketSequencePlayback; + friend class OggPacketSequencePlayback; // List of pages, each of which is a list of packets on that page. The innermost PackedByteArrays contain complete ogg packets. Vector<Vector<PackedByteArray>> page_data; @@ -73,7 +73,7 @@ public: void set_packet_granule_positions(const Array &p_granule_positions); Array get_packet_granule_positions() const; - // Sets a sampling rate associated with this object. OGGPacketSequence doesn't understand codecs, + // Sets a sampling rate associated with this object. OggPacketSequence doesn't understand codecs, // so this value is naively stored as a convenience. void set_sampling_rate(float p_sampling_rate); @@ -86,18 +86,18 @@ public: // Returns the granule position of the last page in this sequence. int64_t get_final_granule_pos() const; - Ref<OGGPacketSequencePlayback> instantiate_playback(); + Ref<OggPacketSequencePlayback> instantiate_playback(); - OGGPacketSequence() {} - virtual ~OGGPacketSequence() {} + OggPacketSequence() {} + virtual ~OggPacketSequence() {} }; -class OGGPacketSequencePlayback : public RefCounted { - GDCLASS(OGGPacketSequencePlayback, RefCounted); +class OggPacketSequencePlayback : public RefCounted { + GDCLASS(OggPacketSequencePlayback, RefCounted); - friend class OGGPacketSequence; + friend class OggPacketSequence; - Ref<OGGPacketSequence> ogg_packet_sequence; + Ref<OggPacketSequence> ogg_packet_sequence; mutable int64_t page_cursor = 0; mutable int32_t packet_cursor = 0; @@ -121,8 +121,8 @@ public: // Returns true on success, false on failure. bool seek_page(int64_t p_granule_pos); - OGGPacketSequencePlayback(); - virtual ~OGGPacketSequencePlayback(); + OggPacketSequencePlayback(); + virtual ~OggPacketSequencePlayback(); }; #endif // OGG_PACKET_SEQUENCE_H diff --git a/modules/ogg/register_types.cpp b/modules/ogg/register_types.cpp index 01f04aa3d5..aca6d1e1f8 100644 --- a/modules/ogg/register_types.cpp +++ b/modules/ogg/register_types.cpp @@ -37,8 +37,8 @@ void initialize_ogg_module(ModuleInitializationLevel p_level) { return; } - GDREGISTER_CLASS(OGGPacketSequence); - GDREGISTER_CLASS(OGGPacketSequencePlayback); + GDREGISTER_CLASS(OggPacketSequence); + GDREGISTER_CLASS(OggPacketSequencePlayback); } void uninitialize_ogg_module(ModuleInitializationLevel p_level) { diff --git a/modules/openxr/editor/openxr_action_map_editor.cpp b/modules/openxr/editor/openxr_action_map_editor.cpp index 87b7f50224..0a2d0a3110 100644 --- a/modules/openxr/editor/openxr_action_map_editor.cpp +++ b/modules/openxr/editor/openxr_action_map_editor.cpp @@ -258,7 +258,7 @@ void OpenXRActionMapEditor::_load_action_map(const String p_path, bool p_create_ } void OpenXRActionMapEditor::_on_save_action_map() { - Error err = ResourceSaver::save(edited_path, action_map); + Error err = ResourceSaver::save(action_map, edited_path); if (err != OK) { EditorNode::get_singleton()->show_warning(vformat(TTR("Error saving file: %s"), edited_path)); return; diff --git a/modules/openxr/editor/openxr_interaction_profile_editor.cpp b/modules/openxr/editor/openxr_interaction_profile_editor.cpp index 24ac5494dd..e2dc2d1b74 100644 --- a/modules/openxr/editor/openxr_interaction_profile_editor.cpp +++ b/modules/openxr/editor/openxr_interaction_profile_editor.cpp @@ -169,9 +169,7 @@ void OpenXRInteractionProfileEditor::_add_io_path(VBoxContainer *p_container, co Button *path_add = memnew(Button); path_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); path_add->set_flat(true); - Vector<Variant> add_binds; - add_binds.push_back(String(p_io_path->openxr_path)); - path_add->connect("pressed", callable_mp(this, &OpenXRInteractionProfileEditor::select_action_for), add_binds); + path_add->connect("pressed", callable_mp(this, &OpenXRInteractionProfileEditor::select_action_for).bind(String(p_io_path->openxr_path))); path_hb->add_child(path_add); if (interaction_profile.is_valid()) { @@ -198,10 +196,7 @@ void OpenXRInteractionProfileEditor::_add_io_path(VBoxContainer *p_container, co Button *action_rem = memnew(Button); action_rem->set_flat(true); action_rem->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); - Vector<Variant> remove_binds; - remove_binds.push_back(action->get_name_with_set()); - remove_binds.push_back(String(p_io_path->openxr_path)); - action_rem->connect("pressed", callable_mp((OpenXRInteractionProfileEditorBase *)this, &OpenXRInteractionProfileEditorBase::_remove_binding), remove_binds); + action_rem->connect("pressed", callable_mp((OpenXRInteractionProfileEditorBase *)this, &OpenXRInteractionProfileEditorBase::_remove_binding).bind(action->get_name_with_set(), String(p_io_path->openxr_path))); action_hb->add_child(action_rem); } } diff --git a/modules/openxr/editor/openxr_select_action_dialog.cpp b/modules/openxr/editor/openxr_select_action_dialog.cpp index c2a2965200..80e58044d5 100644 --- a/modules/openxr/editor/openxr_select_action_dialog.cpp +++ b/modules/openxr/editor/openxr_select_action_dialog.cpp @@ -96,11 +96,9 @@ void OpenXRSelectActionDialog::open() { Button *action_button = memnew(Button); String action_name = action->get_name_with_set(); - Vector<Variant> binds; - binds.push_back(action_name); action_button->set_flat(true); action_button->set_text(action->get_name() + ": " + action->get_localized_name()); - action_button->connect("pressed", callable_mp(this, &OpenXRSelectActionDialog::_on_select_action), binds); + action_button->connect("pressed", callable_mp(this, &OpenXRSelectActionDialog::_on_select_action).bind(action_name)); action_hb->add_child(action_button); action_buttons[action_name] = action_button->get_path(); diff --git a/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp b/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp index 12b110f146..23b025db08 100644 --- a/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp +++ b/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp @@ -80,11 +80,9 @@ void OpenXRSelectInteractionProfileDialog::open(PackedStringArray p_do_not_inclu String path = interaction_profiles[i]; if (!p_do_not_include.has(path)) { Button *ip_button = memnew(Button); - Vector<Variant> binds; - binds.push_back(path); ip_button->set_flat(true); ip_button->set_text(OpenXRDefs::get_profile(path)->display_name); - ip_button->connect("pressed", callable_mp(this, &OpenXRSelectInteractionProfileDialog::_on_select_interaction_profile), binds); + ip_button->connect("pressed", callable_mp(this, &OpenXRSelectInteractionProfileDialog::_on_select_interaction_profile).bind(path)); main_vb->add_child(ip_button); ip_buttons[path] = ip_button->get_path(); diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index 938b017e3a..92d074cb75 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -58,19 +58,14 @@ bool OpenXRAPI::openxr_is_enabled(bool p_check_run_in_editor) { // @TODO we need an overrule switch so we can force enable openxr, i.e run "godot --openxr_enabled" if (Engine::get_singleton()->is_editor_hint() && p_check_run_in_editor) { -#ifdef TOOLS_ENABLED // Disabled for now, using XR inside of the editor we'll be working on during the coming months. return false; - - // bool enabled = GLOBAL_GET("xr/openxr/in_editor"); // EDITOR_GET("xr/openxr/in_editor"); - // return enabled; -#else - // we should never get here, editor hint won't be true if the editor isn't compiled in. - return false; -#endif } else { - bool enabled = GLOBAL_GET("xr/openxr/enabled"); - return enabled; + if (XRServer::get_xr_mode() == XRServer::XRMODE_DEFAULT) { + return GLOBAL_GET("xr/openxr/enabled"); + } else { + return XRServer::get_xr_mode() == XRServer::XRMODE_ON; + } } } diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp index 1447be5c77..6c2f08e21d 100644 --- a/modules/openxr/openxr_interface.cpp +++ b/modules/openxr/openxr_interface.cpp @@ -123,7 +123,7 @@ void OpenXRInterface::_load_action_map() { #ifdef TOOLS_ENABLED // Save our action sets so our user can action_map->set_path(default_tres_name, true); - ResourceSaver::save(default_tres_name, action_map); + ResourceSaver::save(action_map, default_tres_name); #endif } } diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml index deabc5ccd3..52a7fe492f 100644 --- a/modules/regex/doc_classes/RegEx.xml +++ b/modules/regex/doc_classes/RegEx.xml @@ -62,6 +62,13 @@ Compiles and assign the search pattern to use. Returns [constant OK] if the compilation is successful. If an error is encountered, details are printed to standard output and an error is returned. </description> </method> + <method name="create_from_string" qualifiers="static"> + <return type="RegEx" /> + <argument index="0" name="pattern" type="String" /> + <description> + Creates and compiles a new [RegEx] object. + </description> + </method> <method name="get_group_count" qualifiers="const"> <return type="int" /> <description> @@ -96,7 +103,7 @@ </description> </method> <method name="search_all" qualifiers="const"> - <return type="Array" /> + <return type="RegExMatch[]" /> <argument index="0" name="subject" type="String" /> <argument index="1" name="offset" type="int" default="0" /> <argument index="2" name="end" type="int" default="-1" /> diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index bbe92139e0..569066867a 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -159,6 +159,13 @@ void RegEx::_pattern_info(uint32_t what, void *where) const { pcre2_pattern_info_32((pcre2_code_32 *)code, what, where); } +Ref<RegEx> RegEx::create_from_string(const String &p_pattern) { + Ref<RegEx> ret; + ret.instantiate(); + ret->compile(p_pattern); + return ret; +} + void RegEx::clear() { if (code) { pcre2_code_free_32((pcre2_code_32 *)code); @@ -194,6 +201,7 @@ Error RegEx::compile(const String &p_pattern) { Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end) const { ERR_FAIL_COND_V(!is_valid(), nullptr); + ERR_FAIL_COND_V_MSG(p_offset < 0, nullptr, "RegEx search offset must be >= 0"); Ref<RegExMatch> result = memnew(RegExMatch); @@ -257,9 +265,11 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end) return result; } -Array RegEx::search_all(const String &p_subject, int p_offset, int p_end) const { +TypedArray<RegExMatch> RegEx::search_all(const String &p_subject, int p_offset, int p_end) const { + ERR_FAIL_COND_V_MSG(p_offset < 0, Array(), "RegEx search offset must be >= 0"); + int last_end = -1; - Array result; + TypedArray<RegExMatch> result; Ref<RegExMatch> match = search(p_subject, p_offset, p_end); while (match.is_valid()) { if (last_end == match->get_end(0)) { @@ -274,6 +284,7 @@ Array RegEx::search_all(const String &p_subject, int p_offset, int p_end) const String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_all, int p_offset, int p_end) const { ERR_FAIL_COND_V(!is_valid(), String()); + ERR_FAIL_COND_V_MSG(p_offset < 0, String(), "RegEx sub offset must be >= 0"); // safety_zone is the number of chars we allocate in addition to the number of chars expected in order to // guard against the PCRE API writing one additional \0 at the end. PCRE's API docs are unclear on whether @@ -380,6 +391,8 @@ RegEx::~RegEx() { } void RegEx::_bind_methods() { + ClassDB::bind_static_method("RegEx", D_METHOD("create_from_string", "pattern"), &RegEx::create_from_string); + ClassDB::bind_method(D_METHOD("clear"), &RegEx::clear); ClassDB::bind_method(D_METHOD("compile", "pattern"), &RegEx::compile); ClassDB::bind_method(D_METHOD("search", "subject", "offset", "end"), &RegEx::search, DEFVAL(0), DEFVAL(-1)); diff --git a/modules/regex/regex.h b/modules/regex/regex.h index 1455188670..9296de929f 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -37,6 +37,7 @@ #include "core/templates/vector.h" #include "core/variant/array.h" #include "core/variant/dictionary.h" +#include "core/variant/typed_array.h" class RegExMatch : public RefCounted { GDCLASS(RegExMatch, RefCounted); @@ -81,11 +82,13 @@ protected: static void _bind_methods(); public: + static Ref<RegEx> create_from_string(const String &p_pattern); + void clear(); Error compile(const String &p_pattern); Ref<RegExMatch> search(const String &p_subject, int p_offset = 0, int p_end = -1) const; - Array search_all(const String &p_subject, int p_offset = 0, int p_end = -1) const; + TypedArray<RegExMatch> search_all(const String &p_subject, int p_offset = 0, int p_end = -1) const; String sub(const String &p_subject, const String &p_replacement, bool p_all = false, int p_offset = 0, int p_end = -1) const; bool is_valid() const; diff --git a/modules/regex/tests/test_regex.h b/modules/regex/tests/test_regex.h index 3f500e7b2f..91af393db1 100644 --- a/modules/regex/tests/test_regex.h +++ b/modules/regex/tests/test_regex.h @@ -130,16 +130,6 @@ TEST_CASE("[RegEx] Empty Pattern") { CHECK(re.is_valid()); } -TEST_CASE("[RegEx] Invalid offset") { - const String s = "Godot"; - - RegEx re("o"); - REQUIRE(re.is_valid()); - CHECK(re.search(s, -1) == nullptr); - CHECK(re.search_all(s, -1).size() == 0); - CHECK(re.sub(s, "", true, -1) == ""); -} - TEST_CASE("[RegEx] Invalid end position") { const String s = "Godot"; diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub index 2d764a4006..c6678307af 100644 --- a/modules/text_server_adv/SCsub +++ b/modules/text_server_adv/SCsub @@ -36,8 +36,8 @@ def make_icu_data(target, source, env): # Thirdparty source files thirdparty_obj = [] -freetype_enabled = env.module_check_dependencies("text_server_adv", ["freetype"], True) -msdfgen_enabled = env.module_check_dependencies("text_server_adv", ["msdfgen"], True) +freetype_enabled = "freetype" in env.module_list +msdfgen_enabled = "msdfgen" in env.module_list if env["builtin_harfbuzz"]: env_harfbuzz = env_modules.Clone() @@ -113,15 +113,18 @@ if env["builtin_harfbuzz"]: if freetype_enabled: thirdparty_sources += [ "src/hb-ft.cc", - "src/hb-graphite2.cc", ] + if env["graphite"]: + thirdparty_sources += [ + "src/hb-graphite2.cc", + ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_harfbuzz.Append(CPPPATH=["#thirdparty/harfbuzz/src"]) + env_harfbuzz.Prepend(CPPPATH=["#thirdparty/harfbuzz/src"]) env_harfbuzz.Append(CCFLAGS=["-DHAVE_ICU"]) if env["builtin_icu"]: - env_harfbuzz.Append(CPPPATH=["#thirdparty/icu4c/common/"]) + env_harfbuzz.Prepend(CPPPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"]) env_harfbuzz.Append(CCFLAGS=["-DU_HAVE_LIB_SUFFIX=1", "-DU_LIB_SUFFIX_C_NAME=_godot", "-DHAVE_ICU_BUILTIN"]) if freetype_enabled: @@ -132,9 +135,9 @@ if env["builtin_harfbuzz"]: ] ) if env["builtin_freetype"]: - env_harfbuzz.Append(CPPPATH=["#thirdparty/freetype/include"]) - if env["builtin_graphite"]: - env_harfbuzz.Append(CPPPATH=["#thirdparty/graphite/include"]) + env_harfbuzz.Prepend(CPPPATH=["#thirdparty/freetype/include"]) + if env["builtin_graphite"] and env["graphite"]: + env_harfbuzz.Prepend(CPPPATH=["#thirdparty/graphite/include"]) env_harfbuzz.Append(CCFLAGS=["-DGRAPHITE2_STATIC"]) if env["platform"] == "android" or env["platform"] == "linuxbsd": @@ -146,7 +149,7 @@ if env["builtin_harfbuzz"]: else: env_harfbuzz.Append(CCFLAGS=["-DHB_NO_MT"]) - env_text_server_adv.Append(CPPPATH=["#thirdparty/harfbuzz/src"]) + env_text_server_adv.Prepend(CPPPATH=["#thirdparty/harfbuzz/src"]) lib = env_harfbuzz.add_library("harfbuzz_builtin", thirdparty_sources) thirdparty_obj += lib @@ -165,7 +168,7 @@ if env["builtin_harfbuzz"]: env.Append(LIBS=[lib]) -if env["builtin_graphite"] and freetype_enabled: +if env["builtin_graphite"] and freetype_enabled and env["graphite"]: env_graphite = env_modules.Clone() env_graphite.disable_warnings() @@ -209,7 +212,7 @@ if env["builtin_graphite"] and freetype_enabled: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_graphite.Append(CPPPATH=["#thirdparty/graphite/src", "#thirdparty/graphite/include"]) + env_graphite.Prepend(CPPPATH=["#thirdparty/graphite/src", "#thirdparty/graphite/include"]) env_graphite.Append( CCFLAGS=[ "-DGRAPHITE2_STATIC", @@ -439,6 +442,10 @@ if env["builtin_icu"]: "common/uvectr32.cpp", "common/uvectr64.cpp", "common/wintz.cpp", + "i18n/scriptset.cpp", + "i18n/ucln_in.cpp", + "i18n/uspoof.cpp", + "i18n/uspoof_impl.cpp", ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] @@ -447,11 +454,11 @@ if env["builtin_icu"]: if env_icu["tools"]: env_icu.Depends("#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/" + icu_data_name) env_icu.Command("#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/" + icu_data_name, make_icu_data) - env_text_server_adv.Append(CPPPATH=["#thirdparty/icu4c/"]) + env_text_server_adv.Prepend(CPPPATH=["#thirdparty/icu4c/"]) else: thirdparty_sources += ["icu_data/icudata_stub.cpp"] - env_icu.Append(CPPPATH=["#thirdparty/icu4c/common/"]) + env_icu.Prepend(CPPPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"]) env_icu.Append( CXXFLAGS=[ "-DU_STATIC_IMPLEMENTATION", @@ -463,6 +470,7 @@ if env["builtin_icu"]: "-DUCONFIG_NO_IDNA", "-DUCONFIG_NO_FILE_IO", "-DUCONFIG_NO_TRANSLITERATION", + "-DUCONFIG_NO_REGULAR_EXPRESSIONS", "-DPKGDATA_MODE=static", "-DU_ENABLE_DYLOAD=0", "-DU_HAVE_LIB_SUFFIX=1", @@ -480,7 +488,7 @@ if env["builtin_icu"]: if env_text_server_adv["tools"]: env_text_server_adv.Append(CXXFLAGS=["-DICU_STATIC_DATA"]) - env_text_server_adv.Append(CPPPATH=["#thirdparty/icu4c/common/"]) + env_text_server_adv.Prepend(CPPPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"]) lib = env_icu.add_library("icu_builtin", thirdparty_sources) thirdparty_obj += lib @@ -504,13 +512,14 @@ if env["builtin_icu"]: module_obj = [] if env["builtin_msdfgen"] and msdfgen_enabled: - env_text_server_adv.Append(CPPPATH=["#thirdparty/msdfgen"]) + env_text_server_adv.Prepend(CPPPATH=["#thirdparty/msdfgen"]) if env["builtin_freetype"] and freetype_enabled: - env_text_server_adv.Append(CPPPATH=["#thirdparty/freetype/include"]) + env_text_server_adv.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) + env_text_server_adv.Prepend(CPPPATH=["#thirdparty/freetype/include"]) -if env["builtin_graphite"] and freetype_enabled: - env_text_server_adv.Append(CPPPATH=["#thirdparty/graphite/include"]) +if env["builtin_graphite"] and freetype_enabled and env["graphite"]: + env_text_server_adv.Prepend(CPPPATH=["#thirdparty/graphite/include"]) env_text_server_adv.add_source_files(module_obj, "*.cpp") env.modules_sources += module_obj diff --git a/modules/text_server_adv/config.py b/modules/text_server_adv/config.py index 8c8df9b05e..179a2ff378 100644 --- a/modules/text_server_adv/config.py +++ b/modules/text_server_adv/config.py @@ -2,6 +2,14 @@ def can_build(env, platform): return True +def get_opts(platform): + from SCons.Variables import BoolVariable + + return [ + BoolVariable("graphite", "Enable SIL Graphite smart fonts support", True), + ] + + def configure(env): pass diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index fa234081f0..73dbf2f443 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -346,6 +346,8 @@ bool TextServerAdvanced::has_feature(Feature p_feature) const { case FEATURE_FONT_VARIABLE: case FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION: case FEATURE_USE_SUPPORT_DATA: + case FEATURE_UNICODE_IDENTIFIERS: + case FEATURE_UNICODE_SECURITY: return true; default: { } @@ -1359,7 +1361,13 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f fd->underline_position = (-FT_MulFix(fd->face->underline_position, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale; fd->underline_thickness = (FT_MulFix(fd->face->underline_thickness, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale; +#if HB_VERSION_ATLEAST(3, 3, 0) hb_font_set_synthetic_slant(fd->hb_handle, p_font_data->transform[0][1]); +#else +#ifndef _MSC_VER +#warning Building with HarfBuzz < 3.3.0, synthetic slant offset correction disabled. +#endif +#endif if (!p_font_data->face_init) { // Get style flags and name. @@ -1626,6 +1634,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f for (unsigned int i = 0; i < count; i++) { Dictionary ftr; +#if HB_VERSION_ATLEAST(2, 1, 0) hb_ot_name_id_t lbl_id; if (hb_ot_layout_feature_get_name_ids(hb_face, HB_OT_TAG_GSUB, i, &lbl_id, nullptr, nullptr, nullptr, nullptr)) { PackedInt32Array lbl; @@ -1635,6 +1644,11 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f hb_ot_name_get_utf32(hb_face, lbl_id, hb_language_from_string(TranslationServer::get_singleton()->get_tool_locale().ascii().get_data(), -1), &text_size, (uint32_t *)lbl.ptrw()); ftr["label"] = String((const char32_t *)lbl.ptr()); } +#else +#ifndef _MSC_VER +#warning Building with HarfBuzz < 2.1.0, readable OpenType feature names disabled. +#endif +#endif ftr["type"] = _get_tag_type(feature_tags[i]); ftr["hidden"] = _get_tag_hidden(feature_tags[i]); @@ -1649,6 +1663,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f for (unsigned int i = 0; i < count; i++) { Dictionary ftr; +#if HB_VERSION_ATLEAST(2, 1, 0) hb_ot_name_id_t lbl_id; if (hb_ot_layout_feature_get_name_ids(hb_face, HB_OT_TAG_GPOS, i, &lbl_id, nullptr, nullptr, nullptr, nullptr)) { PackedInt32Array lbl; @@ -1658,6 +1673,11 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f hb_ot_name_get_utf32(hb_face, lbl_id, hb_language_from_string(TranslationServer::get_singleton()->get_tool_locale().ascii().get_data(), -1), &text_size, (uint32_t *)lbl.ptrw()); ftr["label"] = String((const char32_t *)lbl.ptr()); } +#else +#ifndef _MSC_VER +#warning Building with HarfBuzz < 2.1.0, readable OpenType feature names disabled. +#endif +#endif ftr["type"] = _get_tag_type(feature_tags[i]); ftr["hidden"] = _get_tag_hidden(feature_tags[i]); @@ -4225,7 +4245,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_l Glyph *sd_glyphs = sd->glyphs.ptrw(); - if (p_trim_flags.has_flag(OVERRUN_TRIM) || sd_glyphs == nullptr || p_width <= 0 || !(sd->width > p_width || enforce_ellipsis)) { + if ((p_trim_flags & OVERRUN_TRIM) == OVERRUN_NO_TRIM || sd_glyphs == nullptr || p_width <= 0 || !(sd->width > p_width || enforce_ellipsis)) { sd->overrun_trim_data.trim_pos = -1; sd->overrun_trim_data.ellipsis_pos = -1; return; @@ -4686,7 +4706,7 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(const RID &p_shape for (int i = 0; i < sd_size; i++) { if (sd_glyphs[i].count > 0) { char32_t c = sd->text[sd_glyphs[i].start - sd->start]; - if (c == 0x0640) { + if (c == 0x0640 && sd_glyphs[i].start == sd_glyphs[i].end - 1) { sd_glyphs[i].flags |= GRAPHEME_IS_ELONGATION; } if (sd->jstops.has(sd_glyphs[i].start)) { @@ -4698,6 +4718,11 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(const RID &p_shape if (sd_glyphs[i].font_rid != RID()) { Glyph gl = _shape_single_glyph(sd, 0x0640, HB_SCRIPT_ARABIC, HB_DIRECTION_RTL, sd->glyphs[i].font_rid, sd->glyphs[i].font_size); if ((sd_glyphs[i].flags & GRAPHEME_IS_VALID) == GRAPHEME_IS_VALID) { +#if HB_VERSION_ATLEAST(5, 1, 0) + if ((i > 0) && ((sd_glyphs[i - 1].flags & GRAPHEME_IS_SAFE_TO_INSERT_TATWEEL) != GRAPHEME_IS_SAFE_TO_INSERT_TATWEEL)) { + continue; + } +#endif gl.start = sd_glyphs[i].start; gl.end = sd_glyphs[i].end; gl.repeat = 0; @@ -4888,11 +4913,16 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star hb_buffer_clear_contents(p_sd->hb_buffer); hb_buffer_set_direction(p_sd->hb_buffer, p_direction); + int flags = (p_start == 0 ? HB_BUFFER_FLAG_BOT : 0) | (p_end == p_sd->text.length() ? HB_BUFFER_FLAG_EOT : 0); if (p_sd->preserve_control) { - hb_buffer_set_flags(p_sd->hb_buffer, (hb_buffer_flags_t)(HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES | (p_start == 0 ? HB_BUFFER_FLAG_BOT : 0) | (p_end == p_sd->text.length() ? HB_BUFFER_FLAG_EOT : 0))); + flags |= HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES; } else { - hb_buffer_set_flags(p_sd->hb_buffer, (hb_buffer_flags_t)(HB_BUFFER_FLAG_DEFAULT | (p_start == 0 ? HB_BUFFER_FLAG_BOT : 0) | (p_end == p_sd->text.length() ? HB_BUFFER_FLAG_EOT : 0))); + flags |= HB_BUFFER_FLAG_DEFAULT; } +#if HB_VERSION_ATLEAST(5, 1, 0) + flags |= HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL; +#endif + hb_buffer_set_flags(p_sd->hb_buffer, (hb_buffer_flags_t)flags); hb_buffer_set_script(p_sd->hb_buffer, p_script); if (p_sd->spans[p_span].language.is_empty()) { @@ -4956,10 +4986,16 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star gl.font_rid = p_fonts[p_fb_index]; gl.font_size = fs; - if (glyph_info[i].mask & HB_GLYPH_FLAG_DEFINED) { + if (glyph_info[i].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) { gl.flags |= GRAPHEME_IS_CONNECTED; } +#if HB_VERSION_ATLEAST(5, 1, 0) + if (glyph_info[i].mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL) { + gl.flags |= GRAPHEME_IS_SAFE_TO_INSERT_TATWEEL; + } +#endif + gl.index = glyph_info[i].codepoint; if (gl.index != 0) { _ensure_glyph(fd, fss, gl.index); @@ -5621,6 +5657,68 @@ String TextServerAdvanced::percent_sign(const String &p_language) const { return "%"; } +int TextServerAdvanced::is_confusable(const String &p_string, const PackedStringArray &p_dict) const { + UErrorCode status = U_ZERO_ERROR; + int match_index = -1; + + Char16String utf16 = p_string.utf16(); + Vector<UChar *> skeletons; + skeletons.resize(p_dict.size()); + + USpoofChecker *sc = uspoof_open(&status); + uspoof_setChecks(sc, USPOOF_CONFUSABLE, &status); + for (int i = 0; i < p_dict.size(); i++) { + Char16String word = p_dict[i].utf16(); + int32_t len = uspoof_getSkeleton(sc, 0, word.get_data(), -1, NULL, 0, &status); + skeletons.write[i] = (UChar *)memalloc(++len * sizeof(UChar)); + status = U_ZERO_ERROR; + uspoof_getSkeleton(sc, 0, word.get_data(), -1, skeletons.write[i], len, &status); + } + + int32_t len = uspoof_getSkeleton(sc, 0, utf16.get_data(), -1, NULL, 0, &status); + UChar *skel = (UChar *)memalloc(++len * sizeof(UChar)); + status = U_ZERO_ERROR; + uspoof_getSkeleton(sc, 0, utf16.get_data(), -1, skel, len, &status); + for (int i = 0; i < skeletons.size(); i++) { + if (u_strcmp(skel, skeletons[i]) == 0) { + match_index = i; + break; + } + } + memfree(skel); + + for (int i = 0; i < skeletons.size(); i++) { + memfree(skeletons.write[i]); + } + uspoof_close(sc); + + ERR_FAIL_COND_V_MSG(U_FAILURE(status), -1, u_errorName(status)); + + return match_index; +} + +bool TextServerAdvanced::spoof_check(const String &p_string) const { + UErrorCode status = U_ZERO_ERROR; + Char16String utf16 = p_string.utf16(); + + USet *allowed = uset_openEmpty(); + uset_addAll(allowed, uspoof_getRecommendedSet(&status)); + uset_addAll(allowed, uspoof_getInclusionSet(&status)); + + USpoofChecker *sc = uspoof_open(&status); + uspoof_setAllowedChars(sc, allowed, &status); + uspoof_setRestrictionLevel(sc, USPOOF_MODERATELY_RESTRICTIVE); + + int32_t bitmask = uspoof_check(sc, utf16.get_data(), -1, NULL, &status); + + uspoof_close(sc); + uset_close(allowed); + + ERR_FAIL_COND_V_MSG(U_FAILURE(status), false, u_errorName(status)); + + return (bitmask != 0); +} + String TextServerAdvanced::strip_diacritics(const String &p_string) const { UErrorCode err = U_ZERO_ERROR; @@ -5739,6 +5837,191 @@ PackedInt32Array TextServerAdvanced::string_get_word_breaks(const String &p_stri return ret; } +bool TextServerAdvanced::is_valid_identifier(const String &p_string) const { + enum UAX31SequenceStatus { + SEQ_NOT_STARTED, + SEQ_STARTED, + SEQ_STARTED_VIR, + SEQ_NEAR_END, + }; + + const char32_t *str = p_string.ptr(); + int len = p_string.length(); + + if (len == 0) { + return false; // Empty string. + } + + UErrorCode err = U_ZERO_ERROR; + Char16String utf16 = p_string.utf16(); + const UNormalizer2 *norm_c = unorm2_getNFCInstance(&err); + if (U_FAILURE(err)) { + return false; // Failed to load normalizer. + } + bool isnurom = unorm2_isNormalized(norm_c, utf16.ptr(), utf16.length(), &err); + if (U_FAILURE(err) || !isnurom) { + return false; // Do not conform to Normalization Form C. + } + + UAX31SequenceStatus A1_sequence_status = SEQ_NOT_STARTED; + UScriptCode A1_scr = USCRIPT_INHERITED; + UAX31SequenceStatus A2_sequence_status = SEQ_NOT_STARTED; + UScriptCode A2_scr = USCRIPT_INHERITED; + UAX31SequenceStatus B_sequence_status = SEQ_NOT_STARTED; + UScriptCode B_scr = USCRIPT_INHERITED; + + for (int i = 0; i < len; i++) { + err = U_ZERO_ERROR; + UScriptCode scr = uscript_getScript(str[i], &err); + if (U_FAILURE(err)) { + return false; // Invalid script. + } + if (uscript_getUsage(scr) != USCRIPT_USAGE_RECOMMENDED) { + return false; // Not a recommended script. + } + uint8_t cat = u_charType(str[i]); + int32_t jt = u_getIntPropertyValue(str[i], UCHAR_JOINING_TYPE); + + // UAX #31 section 2.3 subsections A1, A2 and B, check ZWNJ and ZWJ usage. + switch (A1_sequence_status) { + case SEQ_NEAR_END: { + if ((A1_scr > USCRIPT_INHERITED) && (scr > USCRIPT_INHERITED) && (scr != A1_scr)) { + return false; // Mixed script. + } + if (jt == U_JT_RIGHT_JOINING || jt == U_JT_DUAL_JOINING) { + A1_sequence_status = SEQ_NOT_STARTED; // Valid end of sequence, reset. + } else if (jt != U_JT_TRANSPARENT) { + return false; // Invalid end of sequence. + } + } break; + case SEQ_STARTED: { + if ((A1_scr > USCRIPT_INHERITED) && (scr > USCRIPT_INHERITED) && (scr != A1_scr)) { + A1_sequence_status = SEQ_NOT_STARTED; // Reset. + } else { + if (jt != U_JT_TRANSPARENT) { + if (str[i] == 0x200C /*ZWNJ*/) { + A1_sequence_status = SEQ_NEAR_END; + continue; + } else { + A1_sequence_status = SEQ_NOT_STARTED; // Reset. + } + } + } + } break; + default: + break; + } + if (A1_sequence_status == SEQ_NOT_STARTED) { + if (jt == U_JT_LEFT_JOINING || jt == U_JT_DUAL_JOINING) { + A1_sequence_status = SEQ_STARTED; + A1_scr = scr; + } + }; + + switch (A2_sequence_status) { + case SEQ_NEAR_END: { + if ((A2_scr > USCRIPT_INHERITED) && (scr > USCRIPT_INHERITED) && (scr != A2_scr)) { + return false; // Mixed script. + } + if (cat == U_UPPERCASE_LETTER || cat == U_LOWERCASE_LETTER || cat == U_TITLECASE_LETTER || cat == U_MODIFIER_LETTER || cat == U_OTHER_LETTER) { + A2_sequence_status = SEQ_NOT_STARTED; // Valid end of sequence, reset. + } else if (cat != U_MODIFIER_LETTER || u_getCombiningClass(str[i]) == 0) { + return false; // Invalid end of sequence. + } + } break; + case SEQ_STARTED_VIR: { + if ((A2_scr > USCRIPT_INHERITED) && (scr > USCRIPT_INHERITED) && (scr != A2_scr)) { + A2_sequence_status = SEQ_NOT_STARTED; // Reset. + } else { + if (str[i] == 0x200C /*ZWNJ*/) { + A2_sequence_status = SEQ_NEAR_END; + continue; + } else if (cat != U_MODIFIER_LETTER || u_getCombiningClass(str[i]) == 0) { + A2_sequence_status = SEQ_NOT_STARTED; // Reset. + } + } + } break; + case SEQ_STARTED: { + if ((A2_scr > USCRIPT_INHERITED) && (scr > USCRIPT_INHERITED) && (scr != A2_scr)) { + A2_sequence_status = SEQ_NOT_STARTED; // Reset. + } else { + if (u_getCombiningClass(str[i]) == 9 /*Virama Combining Class*/) { + A2_sequence_status = SEQ_STARTED_VIR; + } else if (cat != U_MODIFIER_LETTER) { + A2_sequence_status = SEQ_NOT_STARTED; // Reset. + } + } + } break; + default: + break; + } + if (A2_sequence_status == SEQ_NOT_STARTED) { + if (cat == U_UPPERCASE_LETTER || cat == U_LOWERCASE_LETTER || cat == U_TITLECASE_LETTER || cat == U_MODIFIER_LETTER || cat == U_OTHER_LETTER) { + A2_sequence_status = SEQ_STARTED; + A2_scr = scr; + } + } + + switch (B_sequence_status) { + case SEQ_NEAR_END: { + if ((B_scr > USCRIPT_INHERITED) && (scr > USCRIPT_INHERITED) && (scr != B_scr)) { + return false; // Mixed script. + } + if (u_getIntPropertyValue(str[i], UCHAR_INDIC_SYLLABIC_CATEGORY) != U_INSC_VOWEL_DEPENDENT) { + B_sequence_status = SEQ_NOT_STARTED; // Valid end of sequence, reset. + } else { + return false; // Invalid end of sequence. + } + } break; + case SEQ_STARTED_VIR: { + if ((B_scr > USCRIPT_INHERITED) && (scr > USCRIPT_INHERITED) && (scr != B_scr)) { + B_sequence_status = SEQ_NOT_STARTED; // Reset. + } else { + if (str[i] == 0x200D /*ZWJ*/) { + B_sequence_status = SEQ_NEAR_END; + continue; + } else if (cat != U_MODIFIER_LETTER || u_getCombiningClass(str[i]) == 0) { + B_sequence_status = SEQ_NOT_STARTED; // Reset. + } + } + } break; + case SEQ_STARTED: { + if ((B_scr > USCRIPT_INHERITED) && (scr > USCRIPT_INHERITED) && (scr != B_scr)) { + B_sequence_status = SEQ_NOT_STARTED; // Reset. + } else { + if (u_getCombiningClass(str[i]) == 9 /*Virama Combining Class*/) { + B_sequence_status = SEQ_STARTED_VIR; + } else if (cat != U_MODIFIER_LETTER) { + B_sequence_status = SEQ_NOT_STARTED; // Reset. + } + } + } break; + default: + break; + } + if (B_sequence_status == SEQ_NOT_STARTED) { + if (cat == U_UPPERCASE_LETTER || cat == U_LOWERCASE_LETTER || cat == U_TITLECASE_LETTER || cat == U_MODIFIER_LETTER || cat == U_OTHER_LETTER) { + B_sequence_status = SEQ_STARTED; + B_scr = scr; + } + } + + if (u_hasBinaryProperty(str[i], UCHAR_PATTERN_SYNTAX) || u_hasBinaryProperty(str[i], UCHAR_PATTERN_WHITE_SPACE) || u_hasBinaryProperty(str[i], UCHAR_NONCHARACTER_CODE_POINT)) { + return false; // Not a XID_Start or XID_Continue character. + } + if (i == 0) { + if (!(cat == U_LOWERCASE_LETTER || cat == U_UPPERCASE_LETTER || cat == U_TITLECASE_LETTER || cat == U_OTHER_LETTER || cat == U_MODIFIER_LETTER || cat == U_LETTER_NUMBER || str[0] == 0x2118 || str[0] == 0x212E || str[0] == 0x309B || str[0] == 0x309C || str[0] == 0x005F)) { + return false; // Not a XID_Start character. + } + } else { + if (!(cat == U_LOWERCASE_LETTER || cat == U_UPPERCASE_LETTER || cat == U_TITLECASE_LETTER || cat == U_OTHER_LETTER || cat == U_MODIFIER_LETTER || cat == U_LETTER_NUMBER || cat == U_NON_SPACING_MARK || cat == U_COMBINING_SPACING_MARK || cat == U_DECIMAL_DIGIT_NUMBER || cat == U_CONNECTOR_PUNCTUATION || str[i] == 0x2118 || str[i] == 0x212E || str[i] == 0x309B || str[i] == 0x309C || str[i] == 0x1369 || str[i] == 0x1371 || str[i] == 0x00B7 || str[i] == 0x0387 || str[i] == 0x19DA || str[i] == 0x0E33 || str[i] == 0x0EB3 || str[i] == 0xFF9E || str[i] == 0xFF9F)) { + return false; // Not a XID_Continue character. + } + } + } + return true; +} + TextServerAdvanced::TextServerAdvanced() { _insert_num_systems_lang(); _insert_feature_sets(); diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 8cd0e753ba..7ae329d616 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -101,6 +101,7 @@ using namespace godot; #include <unicode/uloc.h> #include <unicode/unorm2.h> #include <unicode/uscript.h> +#include <unicode/uspoof.h> #include <unicode/ustring.h> #include <unicode/utypes.h> @@ -112,7 +113,10 @@ using namespace godot; #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H #include FT_BBOX_H - +#include FT_CONFIG_OPTIONS_H +#if !defined(FT_CONFIG_OPTION_USE_BROTLI) && !defined(_MSC_VER) +#warning FreeType is configured without Brotli support, built-in fonts will not be available. +#endif #include <hb-ft.h> #include <hb-ot.h> #endif @@ -701,7 +705,11 @@ public: virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const override; + virtual int is_confusable(const String &p_string, const PackedStringArray &p_dict) const override; + virtual bool spoof_check(const String &p_string) const override; + virtual String strip_diacritics(const String &p_string) const override; + virtual bool is_valid_identifier(const String &p_string) const override; virtual String string_to_upper(const String &p_string, const String &p_language = "") const override; virtual String string_to_lower(const String &p_string, const String &p_language = "") const override; diff --git a/modules/text_server_fb/SCsub b/modules/text_server_fb/SCsub index 121f38fcd5..429d2e1fdc 100644 --- a/modules/text_server_fb/SCsub +++ b/modules/text_server_fb/SCsub @@ -3,15 +3,16 @@ Import("env") Import("env_modules") -freetype_enabled = env.module_check_dependencies("text_server_fb", ["freetype"], True) -msdfgen_enabled = env.module_check_dependencies("text_server_fb", ["msdfgen"], True) +freetype_enabled = "freetype" in env.module_list +msdfgen_enabled = "msdfgen" in env.module_list env_text_server_fb = env_modules.Clone() if env["builtin_msdfgen"] and msdfgen_enabled: - env_text_server_fb.Append(CPPPATH=["#thirdparty/msdfgen"]) + env_text_server_fb.Prepend(CPPPATH=["#thirdparty/msdfgen"]) if env["builtin_freetype"] and freetype_enabled: - env_text_server_fb.Append(CPPPATH=["#thirdparty/freetype/include"]) + env_text_server_fb.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) + env_text_server_fb.Prepend(CPPPATH=["#thirdparty/freetype/include"]) env_text_server_fb.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 50ea4677b1..55d912a10a 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -3204,7 +3204,7 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(const RID &p_shaped_l Glyph *sd_glyphs = sd->glyphs.ptrw(); - if (p_trim_flags.has_flag(OVERRUN_TRIM) || sd_glyphs == nullptr || p_width <= 0 || !(sd->width > p_width || enforce_ellipsis)) { + if ((p_trim_flags & OVERRUN_TRIM) == OVERRUN_NO_TRIM || sd_glyphs == nullptr || p_width <= 0 || !(sd->width > p_width || enforce_ellipsis)) { sd->overrun_trim_data.trim_pos = -1; sd->overrun_trim_data.ellipsis_pos = -1; return; diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index adb5cbb817..fef19d442b 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -98,6 +98,10 @@ using namespace godot; #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H #include FT_BBOX_H +#include FT_CONFIG_OPTIONS_H +#if !defined(FT_CONFIG_OPTION_USE_BROTLI) && !defined(_MSC_VER) +#warning FreeType is configured without Brotli support, built-in fonts will not be available. +#endif #endif /*************************************************************************/ diff --git a/modules/tga/SCsub b/modules/tga/SCsub index 067caa6ea0..ccd7d2ee37 100644 --- a/modules/tga/SCsub +++ b/modules/tga/SCsub @@ -5,5 +5,5 @@ Import("env_modules") env_tga = env_modules.Clone() -# Godot's own source files +# Godot source files env_tga.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/theora/config.py b/modules/theora/config.py index 7f354a8fda..9a27e8e132 100644 --- a/modules/theora/config.py +++ b/modules/theora/config.py @@ -1,7 +1,8 @@ def can_build(env, platform): if env["arch"].startswith("rv"): return False - return env.module_check_dependencies("theora", ["ogg", "vorbis"]) + env.module_add_dependencies("theora", ["ogg", "vorbis"]) + return True def configure(env): diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 74a61bc4b7..7f8e9d8254 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -42,10 +42,32 @@ #include "editor/editor_node.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" +#include "scene/gui/check_button.h" +#include "scene/gui/graph_edit.h" +#include "scene/gui/separator.h" #include "scene/gui/view_panner.h" #include "scene/main/window.h" #ifdef TOOLS_ENABLED + +void VisualScriptEditedProperty::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_edited_property", "value"), &VisualScriptEditedProperty::set_edited_property); + ClassDB::bind_method(D_METHOD("get_edited_property"), &VisualScriptEditedProperty::get_edited_property); + + ADD_PROPERTY(PropertyInfo(Variant::NIL, "edited_property", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_edited_property", "get_edited_property"); +} + +void VisualScriptEditedProperty::set_edited_property(Variant p_variant) { + edited_property = p_variant; +} + +Variant VisualScriptEditedProperty::get_edited_property() const { + return edited_property; +} + +///////////////// + class VisualScriptEditorSignalEdit : public Object { GDCLASS(VisualScriptEditorSignalEdit, Object); @@ -687,8 +709,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) { gnode->set_meta("__vnode", node); gnode->set_name(itos(E)); - gnode->connect("dragged", callable_mp(this, &VisualScriptEditor::_node_moved), varray(E)); - gnode->connect("close_request", callable_mp(this, &VisualScriptEditor::_remove_node), varray(E), CONNECT_DEFERRED); + gnode->connect("dragged", callable_mp(this, &VisualScriptEditor::_node_moved).bind(E)); + gnode->connect("close_request", callable_mp(this, &VisualScriptEditor::_remove_node).bind(E), CONNECT_DEFERRED); { Ref<VisualScriptFunction> v = node; @@ -708,7 +730,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Button *btn = memnew(Button); btn->set_text(TTR("Add Input Port")); hbnc->add_child(btn); - btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port), varray(E), CONNECT_DEFERRED); + btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port).bind(E), CONNECT_DEFERRED); } if (nd_list->is_output_port_editable()) { if (nd_list->is_input_port_editable()) { @@ -718,7 +740,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Button *btn = memnew(Button); btn->set_text(TTR("Add Output Port")); hbnc->add_child(btn); - btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_output_port), varray(E), CONNECT_DEFERRED); + btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_output_port).bind(E), CONNECT_DEFERRED); } gnode->add_child(hbnc); } else if (Object::cast_to<VisualScriptExpression>(node.ptr())) { @@ -728,7 +750,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { line_edit->set_expand_to_text_length_enabled(true); line_edit->add_theme_font_override("font", get_theme_font(SNAME("source"), SNAME("EditorFonts"))); gnode->add_child(line_edit); - line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed), varray(E)); + line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed).bind(E)); } else { String text = node->get_text(); if (!text.is_empty()) { @@ -744,7 +766,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { gnode->set_comment(true); gnode->set_resizable(true); gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE); - gnode->connect("resize_request", callable_mp(this, &VisualScriptEditor::_comment_node_resized), varray(E)); + gnode->connect("resize_request", callable_mp(this, &VisualScriptEditor::_comment_node_resized).bind(E)); } if (node_styles.has(node->get_category())) { @@ -847,8 +869,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) { name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0)); name_box->set_text(left_name); name_box->set_expand_to_text_length_enabled(true); - name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E)); - name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E, i, true)); + name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size).bind(E)); + name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out).bind(name_box, E, i, true)); } else { hbc->add_child(memnew(Label(left_name))); } @@ -861,13 +883,13 @@ void VisualScriptEditor::_update_graph(int p_only_id) { opbtn->select(left_type); opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); hbc->add_child(opbtn); - opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E, i, true), CONNECT_DEFERRED); + opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type).bind(E, i, true), CONNECT_DEFERRED); } Button *rmbtn = memnew(Button); rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); hbc->add_child(rmbtn); - rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_input_port), varray(E, i), CONNECT_DEFERRED); + rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_input_port).bind(E, i), CONNECT_DEFERRED); } else { hbc->add_child(memnew(Label(left_name))); } @@ -886,7 +908,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { if (left_type == Variant::COLOR) { button->set_custom_minimum_size(Size2(30, 0) * EDSCALE); - button->connect("draw", callable_mp(this, &VisualScriptEditor::_draw_color_over_button), varray(button, value)); + button->connect("draw", callable_mp(this, &VisualScriptEditor::_draw_color_over_button).bind(button, value)); } else if (left_type == Variant::OBJECT && Ref<Resource>(value).is_valid()) { Ref<Resource> res = value; Array arr; @@ -941,7 +963,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { } else { button->set_text(value); } - button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited), varray(button, E, i)); + button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited).bind(button, E, i)); hbc2->add_child(button); } } else { @@ -965,7 +987,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Button *rmbtn = memnew(Button); rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); hbc->add_child(rmbtn); - rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_output_port), varray(E, i), CONNECT_DEFERRED); + rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_output_port).bind(E, i), CONNECT_DEFERRED); if (nd_list->is_output_port_type_editable()) { OptionButton *opbtn = memnew(OptionButton); @@ -975,7 +997,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { opbtn->select(right_type); opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); hbc->add_child(opbtn); - opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E, i, false), CONNECT_DEFERRED); + opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type).bind(E, i, false), CONNECT_DEFERRED); } if (nd_list->is_output_port_name_editable()) { @@ -984,8 +1006,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) { name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0)); name_box->set_text(right_name); name_box->set_expand_to_text_length_enabled(true); - name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E)); - name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E, i, false)); + name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size).bind(E)); + name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out).bind(name_box, E, i, false)); } else { hbc->add_child(memnew(Label(right_name))); } @@ -1470,7 +1492,7 @@ void VisualScriptEditor::_add_func_input() { func_input_vbox->add_child(hbox); hbox->set_meta("id", hbox->get_index()); - delete_button->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_func_input), varray(hbox)); + delete_button->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_func_input).bind(hbox)); name_box->select_all(); name_box->grab_focus(); @@ -3898,14 +3920,14 @@ int VisualScriptEditor::_create_new_node_from_name(const String &p_text, const V return new_id; } -void VisualScriptEditor::_default_value_changed() { +void VisualScriptEditor::_default_value_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing) { Ref<VisualScriptNode> vsn = script->get_node(editing_id); if (vsn.is_null()) { return; } undo_redo->create_action(TTR("Change Input Value")); - undo_redo->add_do_method(vsn.ptr(), "set_default_input_value", editing_input, default_value_edit->get_variant()); + undo_redo->add_do_method(vsn.ptr(), "set_default_input_value", editing_input, p_value); undo_redo->add_undo_method(vsn.ptr(), "set_default_input_value", editing_input, vsn->get_default_input_value(editing_input)); undo_redo->add_do_method(this, "_update_graph", editing_id); @@ -3928,9 +3950,6 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i Variant::construct(pinfo.type, existing, &existingp, 1, ce); } - default_value_edit->set_position(Object::cast_to<Control>(p_button)->get_screen_position() + Vector2(0, Object::cast_to<Control>(p_button)->get_size().y) * graph->get_zoom()); - default_value_edit->reset_size(); - if (pinfo.type == Variant::NODE_PATH) { Node *edited_scene = get_tree()->get_edited_scene_root(); if (edited_scene) { // Fixing an old crash bug ( Visual Script Crashes on editing NodePath with an empty scene open). @@ -3948,11 +3967,33 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i } } - if (default_value_edit->edit(nullptr, pinfo.name, pinfo.type, existing, pinfo.hint, pinfo.hint_string)) { - if (pinfo.hint == PROPERTY_HINT_MULTILINE_TEXT) { - default_value_edit->popup_centered_ratio(); + edited_default_property_holder->set_edited_property(existing); + + if (default_property_editor) { + default_property_editor->disconnect("property_changed", callable_mp(this, &VisualScriptEditor::_default_value_changed)); + default_property_editor_popup->remove_child(default_property_editor); + } + + default_property_editor = EditorInspector::instantiate_property_editor(edited_default_property_holder.ptr(), pinfo.type, "edited_property", pinfo.hint, pinfo.hint_string, PROPERTY_USAGE_NONE); + if (default_property_editor) { + default_property_editor->set_object_and_property(edited_default_property_holder.ptr(), "edited_property"); + default_property_editor->update_property(); + default_property_editor->set_name_split_ratio(0); + default_property_editor_popup->add_child(default_property_editor); + + default_property_editor->connect("property_changed", callable_mp(this, &VisualScriptEditor::_default_value_changed)); + + Button *button = Object::cast_to<Button>(p_button); + if (button) { + default_property_editor_popup->set_position(button->get_screen_position() + Vector2(0, button->get_size().height) * graph->get_zoom()); + } + + default_property_editor_popup->reset_size(); + + if (pinfo.hint == PROPERTY_HINT_MULTILINE_TEXT || !button) { + default_property_editor_popup->popup_centered_ratio(); } else { - default_value_edit->popup(); + default_property_editor_popup->popup(); } } @@ -3988,9 +4029,9 @@ void VisualScriptEditor::_notification(int p_what) { case NOTIFICATION_READY: { variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members)); - variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED); + variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph).bind(-1), CONNECT_DEFERRED); signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members)); - signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED); + signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph).bind(-1), CONNECT_DEFERRED); [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { @@ -4608,7 +4649,7 @@ VisualScriptEditor::VisualScriptEditor() { members->set_hide_root(true); members->connect("button_clicked", callable_mp(this, &VisualScriptEditor::_member_button)); members->connect("item_edited", callable_mp(this, &VisualScriptEditor::_member_edited)); - members->connect("cell_selected", callable_mp(this, &VisualScriptEditor::_member_selected), varray(), CONNECT_DEFERRED); + members->connect("cell_selected", callable_mp(this, &VisualScriptEditor::_member_selected), CONNECT_DEFERRED); members->connect("gui_input", callable_mp(this, &VisualScriptEditor::_members_gui_input)); members->connect("item_mouse_selected", callable_mp(this, &VisualScriptEditor::_member_rmb_selected)); members->set_allow_rmb_select(true); @@ -4795,9 +4836,11 @@ VisualScriptEditor::VisualScriptEditor() { set_process_input(true); - default_value_edit = memnew(CustomPropertyEditor); - add_child(default_value_edit); - default_value_edit->connect("variant_changed", callable_mp(this, &VisualScriptEditor::_default_value_changed)); + default_property_editor_popup = memnew(PopupPanel); + default_property_editor_popup->set_min_size(Size2i(180, 0) * EDSCALE); + add_child(default_property_editor_popup); + + edited_default_property_holder.instantiate(); new_connect_node_select = memnew(VisualScriptPropertySelector); add_child(new_connect_node_select); diff --git a/modules/visual_script/editor/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h index a6df7bba73..6b337e52f6 100644 --- a/modules/visual_script/editor/visual_script_editor.h +++ b/modules/visual_script/editor/visual_script_editor.h @@ -34,15 +34,31 @@ #include "../visual_script.h" #include "editor/create_dialog.h" #include "editor/plugins/script_editor_plugin.h" -#include "editor/property_editor.h" -#include "scene/gui/graph_edit.h" #include "visual_script_property_selector.h" +class GraphEdit; + class VisualScriptEditorSignalEdit; class VisualScriptEditorVariableEdit; #ifdef TOOLS_ENABLED +class VisualScriptEditedProperty : public RefCounted { + GDCLASS(VisualScriptEditedProperty, RefCounted); + +private: + Variant edited_property; + +protected: + static void _bind_methods(); + +public: + void set_edited_property(Variant p_variant); + Variant get_edited_property() const; + + VisualScriptEditedProperty() {} +}; + // TODO: Maybe this class should be refactored. // See https://github.com/godotengine/godot/issues/51913 class VisualScriptEditor : public ScriptEditorBase { @@ -115,7 +131,9 @@ class VisualScriptEditor : public ScriptEditorBase { AcceptDialog *edit_variable_dialog = nullptr; EditorInspector *edit_variable_edit = nullptr; - CustomPropertyEditor *default_value_edit = nullptr; + PopupPanel *default_property_editor_popup = nullptr; + EditorProperty *default_property_editor = nullptr; + Ref<VisualScriptEditedProperty> edited_default_property_holder; UndoRedo *undo_redo = nullptr; @@ -276,7 +294,7 @@ class VisualScriptEditor : public ScriptEditorBase { int data_disconnect_node = 0; int data_disconnect_port = 0; - void _default_value_changed(); + void _default_value_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing); void _default_value_edited(Node *p_button, int p_id, int p_input_port); void _menu_option(int p_what); diff --git a/modules/visual_script/editor/visual_script_property_selector.cpp b/modules/visual_script/editor/visual_script_property_selector.cpp index f98ce5bb26..712c89368b 100644 --- a/modules/visual_script/editor/visual_script_property_selector.cpp +++ b/modules/visual_script/editor/visual_script_property_selector.cpp @@ -39,6 +39,7 @@ #include "editor/doc_tools.h" #include "editor/editor_feature_profile.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "scene/main/node.h" #include "scene/main/window.h" diff --git a/modules/visual_script/editor/visual_script_property_selector.h b/modules/visual_script/editor/visual_script_property_selector.h index 41f8eea735..4de626467e 100644 --- a/modules/visual_script/editor/visual_script_property_selector.h +++ b/modules/visual_script/editor/visual_script_property_selector.h @@ -33,8 +33,8 @@ #include "../visual_script.h" #include "editor/editor_help.h" -#include "editor/property_editor.h" #include "scene/gui/rich_text_label.h" +#include "scene/gui/tree.h" class VisualScriptPropertySelector : public ConfirmationDialog { GDCLASS(VisualScriptPropertySelector, ConfirmationDialog); diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 742fa75bb7..73249371cd 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -279,7 +279,7 @@ void VisualScript::add_node(int p_id, const Ref<VisualScriptNode> &p_node, const nd.pos = p_pos; Ref<VisualScriptNode> vsn = p_node; - vsn->connect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed), varray(p_id)); + vsn->connect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed).bind(p_id)); vsn->script_used = Ref<VisualScript>(this); vsn->validate_input_default_values(); // Validate when fully loaded. @@ -948,7 +948,7 @@ bool VisualScript::are_subnodes_edited() const { } #endif -const Vector<Multiplayer::RPCConfig> VisualScript::get_rpc_methods() const { +const Variant VisualScript::get_rpc_config() const { return rpc_functions; } @@ -1012,22 +1012,16 @@ void VisualScript::_set_data(const Dictionary &p_data) { for (const KeyValue<StringName, Function> &E : functions) { if (E.value.func_id >= 0 && nodes.has(E.value.func_id)) { Ref<VisualScriptFunction> vsf = nodes[E.value.func_id].node; - if (vsf.is_valid()) { - if (vsf->get_rpc_mode() != Multiplayer::RPC_MODE_DISABLED) { - Multiplayer::RPCConfig nd; - nd.name = E.key; - nd.rpc_mode = vsf->get_rpc_mode(); - nd.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; // TODO - if (rpc_functions.find(nd) == -1) { - rpc_functions.push_back(nd); - } - } + if (!vsf.is_valid() || vsf->get_rpc_mode() == MultiplayerAPI::RPC_MODE_DISABLED) { + continue; } + Dictionary nd; + nd["rpc_mode"] = vsf->get_rpc_mode(); + nd["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE; // TODO + nd["call_local"] = false; // TODO + rpc_functions[E.key] = nd; } } - - // Sort so we are 100% that they are always the same. - rpc_functions.sort_custom<Multiplayer::SortRPCConfig>(); } Dictionary VisualScript::_get_data() const { @@ -1212,6 +1206,10 @@ bool VisualScriptInstance::get(const StringName &p_name, Variant &r_ret) const { } void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const { +#ifdef TOOLS_ENABLED + p_properties->push_back(script->get_class_category()); +#endif // TOOLS_ENABLED + for (const KeyValue<StringName, VisualScript::Variable> &E : script->variables) { if (!E.value._export) { continue; @@ -1811,8 +1809,8 @@ Ref<Script> VisualScriptInstance::get_script() const { return script; } -const Vector<Multiplayer::RPCConfig> VisualScriptInstance::get_rpc_methods() const { - return script->get_rpc_methods(); +const Variant VisualScriptInstance::get_rpc_config() const { + return script->get_rpc_config(); } void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_owner) { @@ -2128,7 +2126,14 @@ void VisualScriptFunctionState::connect_to_signal(Object *p_obj, const String &p binds.push_back(p_binds[i]); } binds.push_back(Ref<VisualScriptFunctionState>(this)); //add myself on the back to avoid dying from unreferencing - p_obj->connect(p_signal, Callable(this, "_signal_callback"), binds, CONNECT_ONESHOT); + + Vector<const Variant *> bind_ptrs; + bind_ptrs.resize(p_binds.size()); + for (int i = 0; i < bind_ptrs.size(); i++) { + bind_ptrs.write[i] = &binds.write[i]; + } + + p_obj->connect(p_signal, Callable(this, "_signal_callback").bindp((const Variant **)bind_ptrs.ptr(), bind_ptrs.size()), CONNECT_ONESHOT); } bool VisualScriptFunctionState::is_valid() const { diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 716310f59b..14cb14e8d9 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -235,7 +235,7 @@ private: HashMap<StringName, Function> functions; HashMap<StringName, Variable> variables; HashMap<StringName, Vector<Argument>> custom_signals; - Vector<Multiplayer::RPCConfig> rpc_functions; + Dictionary rpc_functions; HashMap<Object *, VisualScriptInstance *> instances; @@ -363,7 +363,7 @@ public: virtual int get_member_line(const StringName &p_member) const override; - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override; + virtual const Variant get_rpc_config() const override; #ifdef TOOLS_ENABLED virtual bool are_subnodes_edited() const; @@ -444,7 +444,7 @@ public: virtual ScriptLanguage *get_language(); - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const; + virtual const Variant get_rpc_config() const; VisualScriptInstance(); ~VisualScriptInstance(); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 41f5b28677..5907e6a489 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -90,7 +90,7 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value } if (p_name == "rpc/mode") { - rpc_mode = Multiplayer::RPCMode(int(p_value)); + rpc_mode = MultiplayerAPI::RPCMode(int(p_value)); return true; } @@ -261,11 +261,11 @@ int VisualScriptFunction::get_argument_count() const { return arguments.size(); } -void VisualScriptFunction::set_rpc_mode(Multiplayer::RPCMode p_mode) { +void VisualScriptFunction::set_rpc_mode(MultiplayerAPI::RPCMode p_mode) { rpc_mode = p_mode; } -Multiplayer::RPCMode VisualScriptFunction::get_rpc_mode() const { +MultiplayerAPI::RPCMode VisualScriptFunction::get_rpc_mode() const { return rpc_mode; } @@ -311,14 +311,14 @@ void VisualScriptFunction::reset_state() { stack_size = 256; stack_less = false; sequenced = true; - rpc_mode = Multiplayer::RPC_MODE_DISABLED; + rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; } VisualScriptFunction::VisualScriptFunction() { stack_size = 256; stack_less = false; sequenced = true; - rpc_mode = Multiplayer::RPC_MODE_DISABLED; + rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; } void VisualScriptFunction::set_stack_less(bool p_enable) { diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h index 18573f8682..35e3c490cd 100644 --- a/modules/visual_script/visual_script_nodes.h +++ b/modules/visual_script/visual_script_nodes.h @@ -33,6 +33,7 @@ #include "core/object/gdvirtual.gen.inc" #include "core/object/script_language.h" +#include "scene/main/multiplayer_api.h" #include "visual_script.h" class VisualScriptFunction : public VisualScriptNode { @@ -49,7 +50,7 @@ class VisualScriptFunction : public VisualScriptNode { bool stack_less; int stack_size; - Multiplayer::RPCMode rpc_mode; + MultiplayerAPI::RPCMode rpc_mode; bool sequenced; protected: @@ -90,8 +91,8 @@ public: void set_stack_size(int p_size); int get_stack_size() const; - void set_rpc_mode(Multiplayer::RPCMode p_mode); - Multiplayer::RPCMode get_rpc_mode() const; + void set_rpc_mode(MultiplayerAPI::RPCMode p_mode); + MultiplayerAPI::RPCMode get_rpc_mode() const; virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp index 76f7317daa..8315eea614 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp @@ -34,7 +34,7 @@ #include "core/variant/typed_array.h" #include "thirdparty/libogg/ogg/ogg.h" -int AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_frames) { +int AudioStreamPlaybackOggVorbis::_mix_internal(AudioFrame *p_buffer, int p_frames) { ERR_FAIL_COND_V(!ready, 0); if (!active) { @@ -141,7 +141,7 @@ int AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fram return p_frames - todo; } -int AudioStreamPlaybackOGGVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p_frames) { +int AudioStreamPlaybackOggVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p_frames) { ERR_FAIL_COND_V(!ready, 0); if (!have_samples_left) { ogg_packet *packet = nullptr; @@ -184,11 +184,11 @@ int AudioStreamPlaybackOGGVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p return frames; } -float AudioStreamPlaybackOGGVorbis::get_stream_sampling_rate() { +float AudioStreamPlaybackOggVorbis::get_stream_sampling_rate() { return vorbis_data->get_sampling_rate(); } -bool AudioStreamPlaybackOGGVorbis::_alloc_vorbis() { +bool AudioStreamPlaybackOggVorbis::_alloc_vorbis() { vorbis_info_init(&info); info_is_allocated = true; vorbis_comment_init(&comment); @@ -223,7 +223,7 @@ bool AudioStreamPlaybackOGGVorbis::_alloc_vorbis() { return true; } -void AudioStreamPlaybackOGGVorbis::start(float p_from_pos) { +void AudioStreamPlaybackOggVorbis::start(float p_from_pos) { ERR_FAIL_COND(!ready); loop_fade_remaining = FADE_SIZE; active = true; @@ -232,27 +232,27 @@ void AudioStreamPlaybackOGGVorbis::start(float p_from_pos) { begin_resample(); } -void AudioStreamPlaybackOGGVorbis::stop() { +void AudioStreamPlaybackOggVorbis::stop() { active = false; } -bool AudioStreamPlaybackOGGVorbis::is_playing() const { +bool AudioStreamPlaybackOggVorbis::is_playing() const { return active; } -int AudioStreamPlaybackOGGVorbis::get_loop_count() const { +int AudioStreamPlaybackOggVorbis::get_loop_count() const { return loops; } -float AudioStreamPlaybackOGGVorbis::get_playback_position() const { +float AudioStreamPlaybackOggVorbis::get_playback_position() const { return float(frames_mixed) / vorbis_data->get_sampling_rate(); } -void AudioStreamPlaybackOGGVorbis::tag_used_streams() { +void AudioStreamPlaybackOggVorbis::tag_used_streams() { vorbis_stream->tag_used(get_playback_position()); } -void AudioStreamPlaybackOGGVorbis::seek(float p_time) { +void AudioStreamPlaybackOggVorbis::seek(float p_time) { ERR_FAIL_COND(!ready); ERR_FAIL_COND(vorbis_stream.is_null()); if (!active) { @@ -370,7 +370,7 @@ void AudioStreamPlaybackOGGVorbis::seek(float p_time) { } } -AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() { +AudioStreamPlaybackOggVorbis::~AudioStreamPlaybackOggVorbis() { if (block_is_allocated) { vorbis_block_clear(&block); } @@ -385,13 +385,13 @@ AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() { } } -Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instantiate_playback() { - Ref<AudioStreamPlaybackOGGVorbis> ovs; +Ref<AudioStreamPlayback> AudioStreamOggVorbis::instantiate_playback() { + Ref<AudioStreamPlaybackOggVorbis> ovs; ERR_FAIL_COND_V(packet_sequence.is_null(), nullptr); ovs.instantiate(); - ovs->vorbis_stream = Ref<AudioStreamOGGVorbis>(this); + ovs->vorbis_stream = Ref<AudioStreamOggVorbis>(this); ovs->vorbis_data = packet_sequence; ovs->frames_mixed = 0; ovs->active = false; @@ -403,11 +403,11 @@ Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instantiate_playback() { return nullptr; } -String AudioStreamOGGVorbis::get_stream_name() const { +String AudioStreamOggVorbis::get_stream_name() const { return ""; //return stream_name; } -void AudioStreamOGGVorbis::maybe_update_info() { +void AudioStreamOggVorbis::maybe_update_info() { ERR_FAIL_COND(packet_sequence.is_null()); vorbis_info info; @@ -417,7 +417,7 @@ void AudioStreamOGGVorbis::maybe_update_info() { vorbis_info_init(&info); vorbis_comment_init(&comment); - Ref<OGGPacketSequencePlayback> packet_sequence_playback = packet_sequence->instantiate_playback(); + Ref<OggPacketSequencePlayback> packet_sequence_playback = packet_sequence->instantiate_playback(); for (int i = 0; i < 3; i++) { ogg_packet *packet; @@ -443,90 +443,90 @@ void AudioStreamOGGVorbis::maybe_update_info() { vorbis_info_clear(&info); } -void AudioStreamOGGVorbis::set_packet_sequence(Ref<OGGPacketSequence> p_packet_sequence) { +void AudioStreamOggVorbis::set_packet_sequence(Ref<OggPacketSequence> p_packet_sequence) { packet_sequence = p_packet_sequence; if (packet_sequence.is_valid()) { maybe_update_info(); } } -Ref<OGGPacketSequence> AudioStreamOGGVorbis::get_packet_sequence() const { +Ref<OggPacketSequence> AudioStreamOggVorbis::get_packet_sequence() const { return packet_sequence; } -void AudioStreamOGGVorbis::set_loop(bool p_enable) { +void AudioStreamOggVorbis::set_loop(bool p_enable) { loop = p_enable; } -bool AudioStreamOGGVorbis::has_loop() const { +bool AudioStreamOggVorbis::has_loop() const { return loop; } -void AudioStreamOGGVorbis::set_loop_offset(float p_seconds) { +void AudioStreamOggVorbis::set_loop_offset(float p_seconds) { loop_offset = p_seconds; } -float AudioStreamOGGVorbis::get_loop_offset() const { +float AudioStreamOggVorbis::get_loop_offset() const { return loop_offset; } -float AudioStreamOGGVorbis::get_length() const { +float AudioStreamOggVorbis::get_length() const { ERR_FAIL_COND_V(packet_sequence.is_null(), 0); return packet_sequence->get_length(); } -void AudioStreamOGGVorbis::set_bpm(double p_bpm) { +void AudioStreamOggVorbis::set_bpm(double p_bpm) { ERR_FAIL_COND(p_bpm < 0); bpm = p_bpm; emit_changed(); } -double AudioStreamOGGVorbis::get_bpm() const { +double AudioStreamOggVorbis::get_bpm() const { return bpm; } -void AudioStreamOGGVorbis::set_beat_count(int p_beat_count) { +void AudioStreamOggVorbis::set_beat_count(int p_beat_count) { ERR_FAIL_COND(p_beat_count < 0); beat_count = p_beat_count; emit_changed(); } -int AudioStreamOGGVorbis::get_beat_count() const { +int AudioStreamOggVorbis::get_beat_count() const { return beat_count; } -void AudioStreamOGGVorbis::set_bar_beats(int p_bar_beats) { +void AudioStreamOggVorbis::set_bar_beats(int p_bar_beats) { ERR_FAIL_COND(p_bar_beats < 2); bar_beats = p_bar_beats; emit_changed(); } -int AudioStreamOGGVorbis::get_bar_beats() const { +int AudioStreamOggVorbis::get_bar_beats() const { return bar_beats; } -bool AudioStreamOGGVorbis::is_monophonic() const { +bool AudioStreamOggVorbis::is_monophonic() const { return false; } -void AudioStreamOGGVorbis::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_packet_sequence", "packet_sequence"), &AudioStreamOGGVorbis::set_packet_sequence); - ClassDB::bind_method(D_METHOD("get_packet_sequence"), &AudioStreamOGGVorbis::get_packet_sequence); +void AudioStreamOggVorbis::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_packet_sequence", "packet_sequence"), &AudioStreamOggVorbis::set_packet_sequence); + ClassDB::bind_method(D_METHOD("get_packet_sequence"), &AudioStreamOggVorbis::get_packet_sequence); - ClassDB::bind_method(D_METHOD("set_loop", "enable"), &AudioStreamOGGVorbis::set_loop); - ClassDB::bind_method(D_METHOD("has_loop"), &AudioStreamOGGVorbis::has_loop); + ClassDB::bind_method(D_METHOD("set_loop", "enable"), &AudioStreamOggVorbis::set_loop); + ClassDB::bind_method(D_METHOD("has_loop"), &AudioStreamOggVorbis::has_loop); - ClassDB::bind_method(D_METHOD("set_loop_offset", "seconds"), &AudioStreamOGGVorbis::set_loop_offset); - ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamOGGVorbis::get_loop_offset); + ClassDB::bind_method(D_METHOD("set_loop_offset", "seconds"), &AudioStreamOggVorbis::set_loop_offset); + ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamOggVorbis::get_loop_offset); - ClassDB::bind_method(D_METHOD("set_bpm", "bpm"), &AudioStreamOGGVorbis::set_bpm); - ClassDB::bind_method(D_METHOD("get_bpm"), &AudioStreamOGGVorbis::get_bpm); + ClassDB::bind_method(D_METHOD("set_bpm", "bpm"), &AudioStreamOggVorbis::set_bpm); + ClassDB::bind_method(D_METHOD("get_bpm"), &AudioStreamOggVorbis::get_bpm); - ClassDB::bind_method(D_METHOD("set_beat_count", "count"), &AudioStreamOGGVorbis::set_beat_count); - ClassDB::bind_method(D_METHOD("get_beat_count"), &AudioStreamOGGVorbis::get_beat_count); + ClassDB::bind_method(D_METHOD("set_beat_count", "count"), &AudioStreamOggVorbis::set_beat_count); + ClassDB::bind_method(D_METHOD("get_beat_count"), &AudioStreamOggVorbis::get_beat_count); - ClassDB::bind_method(D_METHOD("set_bar_beats", "count"), &AudioStreamOGGVorbis::set_bar_beats); - ClassDB::bind_method(D_METHOD("get_bar_beats"), &AudioStreamOGGVorbis::get_bar_beats); + ClassDB::bind_method(D_METHOD("set_bar_beats", "count"), &AudioStreamOggVorbis::set_bar_beats); + ClassDB::bind_method(D_METHOD("get_bar_beats"), &AudioStreamOggVorbis::get_bar_beats); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "packet_sequence", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_sequence", "get_packet_sequence"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bpm", PROPERTY_HINT_RANGE, "0,400,0.01,or_greater"), "set_bpm", "get_bpm"); @@ -536,6 +536,6 @@ void AudioStreamOGGVorbis::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset"), "set_loop_offset", "get_loop_offset"); } -AudioStreamOGGVorbis::AudioStreamOGGVorbis() {} +AudioStreamOggVorbis::AudioStreamOggVorbis() {} -AudioStreamOGGVorbis::~AudioStreamOGGVorbis() {} +AudioStreamOggVorbis::~AudioStreamOggVorbis() {} diff --git a/modules/vorbis/audio_stream_ogg_vorbis.h b/modules/vorbis/audio_stream_ogg_vorbis.h index 9b6d928d87..0350e1f761 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.h +++ b/modules/vorbis/audio_stream_ogg_vorbis.h @@ -36,10 +36,10 @@ #include "servers/audio/audio_stream.h" #include "thirdparty/libvorbis/vorbis/codec.h" -class AudioStreamOGGVorbis; +class AudioStreamOggVorbis; -class AudioStreamPlaybackOGGVorbis : public AudioStreamPlaybackResampled { - GDCLASS(AudioStreamPlaybackOGGVorbis, AudioStreamPlaybackResampled); +class AudioStreamPlaybackOggVorbis : public AudioStreamPlaybackResampled { + GDCLASS(AudioStreamPlaybackOggVorbis, AudioStreamPlaybackResampled); uint32_t frames_mixed = 0; bool active = false; @@ -66,11 +66,11 @@ class AudioStreamPlaybackOGGVorbis : public AudioStreamPlaybackResampled { bool have_samples_left = false; bool have_packets_left = false; - friend class AudioStreamOGGVorbis; + friend class AudioStreamOggVorbis; - Ref<OGGPacketSequence> vorbis_data; - Ref<OGGPacketSequencePlayback> vorbis_data_playback; - Ref<AudioStreamOGGVorbis> vorbis_stream; + Ref<OggPacketSequence> vorbis_data; + Ref<OggPacketSequencePlayback> vorbis_data_playback; + Ref<AudioStreamOggVorbis> vorbis_stream; int _mix_frames(AudioFrame *p_buffer, int p_frames); int _mix_frames_vorbis(AudioFrame *p_buffer, int p_frames); @@ -94,16 +94,16 @@ public: virtual void tag_used_streams() override; - AudioStreamPlaybackOGGVorbis() {} - ~AudioStreamPlaybackOGGVorbis(); + AudioStreamPlaybackOggVorbis() {} + ~AudioStreamPlaybackOggVorbis(); }; -class AudioStreamOGGVorbis : public AudioStream { - GDCLASS(AudioStreamOGGVorbis, AudioStream); +class AudioStreamOggVorbis : public AudioStream { + GDCLASS(AudioStreamOggVorbis, AudioStream); OBJ_SAVE_TYPE(AudioStream); // Saves derived classes with common type so they can be interchanged. RES_BASE_EXTENSION("oggvorbisstr"); - friend class AudioStreamPlaybackOGGVorbis; + friend class AudioStreamPlaybackOggVorbis; int channels = 1; float length = 0.0; @@ -114,7 +114,7 @@ class AudioStreamOGGVorbis : public AudioStream { // Also causes allocation and deallocation. void maybe_update_info(); - Ref<OGGPacketSequence> packet_sequence; + Ref<OggPacketSequence> packet_sequence; double bpm = 0; int beat_count = 0; @@ -142,15 +142,15 @@ public: virtual Ref<AudioStreamPlayback> instantiate_playback() override; virtual String get_stream_name() const override; - void set_packet_sequence(Ref<OGGPacketSequence> p_packet_sequence); - Ref<OGGPacketSequence> get_packet_sequence() const; + void set_packet_sequence(Ref<OggPacketSequence> p_packet_sequence); + Ref<OggPacketSequence> get_packet_sequence() const; virtual float get_length() const override; //if supported, otherwise return 0 virtual bool is_monophonic() const override; - AudioStreamOGGVorbis(); - virtual ~AudioStreamOGGVorbis(); + AudioStreamOggVorbis(); + virtual ~AudioStreamOggVorbis(); }; #endif // AUDIO_STREAM_OGG_VORBIS_H diff --git a/modules/vorbis/config.py b/modules/vorbis/config.py index 978eccb29f..a231ef179d 100644 --- a/modules/vorbis/config.py +++ b/modules/vorbis/config.py @@ -1,5 +1,6 @@ def can_build(env, platform): - return env.module_check_dependencies("vorbis", ["ogg"]) + env.module_add_dependencies("vorbis", ["ogg"]) + return True def configure(env): @@ -8,8 +9,8 @@ def configure(env): def get_doc_classes(): return [ - "AudioStreamOGGVorbis", - "AudioStreamPlaybackOGGVorbis", + "AudioStreamOggVorbis", + "AudioStreamPlaybackOggVorbis", ] diff --git a/modules/vorbis/doc_classes/AudioStreamOGGVorbis.xml b/modules/vorbis/doc_classes/AudioStreamOggVorbis.xml index f87296dcd8..225ea4e6ae 100644 --- a/modules/vorbis/doc_classes/AudioStreamOGGVorbis.xml +++ b/modules/vorbis/doc_classes/AudioStreamOggVorbis.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamOGGVorbis" inherits="AudioStream" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="AudioStreamOggVorbis" inherits="AudioStream" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> </brief_description> <description> @@ -19,8 +19,8 @@ <member name="loop_offset" type="float" setter="set_loop_offset" getter="get_loop_offset" default="0.0"> Time in seconds at which the stream starts after being looped. </member> - <member name="packet_sequence" type="OGGPacketSequence" setter="set_packet_sequence" getter="get_packet_sequence"> - Contains the raw OGG data for this stream. + <member name="packet_sequence" type="OggPacketSequence" setter="set_packet_sequence" getter="get_packet_sequence"> + Contains the raw Ogg data for this stream. </member> </members> </class> diff --git a/modules/vorbis/doc_classes/AudioStreamPlaybackOGGVorbis.xml b/modules/vorbis/doc_classes/AudioStreamPlaybackOggVorbis.xml index 68aa46147f..0879c773ac 100644 --- a/modules/vorbis/doc_classes/AudioStreamPlaybackOGGVorbis.xml +++ b/modules/vorbis/doc_classes/AudioStreamPlaybackOggVorbis.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamPlaybackOGGVorbis" inherits="AudioStreamPlaybackResampled" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="AudioStreamPlaybackOggVorbis" inherits="AudioStreamPlaybackResampled" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> </brief_description> <description> diff --git a/modules/vorbis/register_types.cpp b/modules/vorbis/register_types.cpp index 7f81f88cdb..84a71fe82d 100644 --- a/modules/vorbis/register_types.cpp +++ b/modules/vorbis/register_types.cpp @@ -40,13 +40,13 @@ void initialize_vorbis_module(ModuleInitializationLevel p_level) { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - Ref<ResourceImporterOGGVorbis> ogg_vorbis_importer; + Ref<ResourceImporterOggVorbis> ogg_vorbis_importer; ogg_vorbis_importer.instantiate(); ResourceFormatImporter::get_singleton()->add_importer(ogg_vorbis_importer); } #endif - GDREGISTER_CLASS(AudioStreamOGGVorbis); - GDREGISTER_CLASS(AudioStreamPlaybackOGGVorbis); + GDREGISTER_CLASS(AudioStreamOggVorbis); + GDREGISTER_CLASS(AudioStreamPlaybackOggVorbis); } void uninitialize_vorbis_module(ModuleInitializationLevel p_level) { diff --git a/modules/vorbis/resource_importer_ogg_vorbis.cpp b/modules/vorbis/resource_importer_ogg_vorbis.cpp index 9461d531fd..bf5f7206b8 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/vorbis/resource_importer_ogg_vorbis.cpp @@ -40,39 +40,39 @@ #include "editor/import/audio_stream_import_settings.h" #endif -String ResourceImporterOGGVorbis::get_importer_name() const { +String ResourceImporterOggVorbis::get_importer_name() const { return "oggvorbisstr"; } -String ResourceImporterOGGVorbis::get_visible_name() const { +String ResourceImporterOggVorbis::get_visible_name() const { return "oggvorbisstr"; } -void ResourceImporterOGGVorbis::get_recognized_extensions(List<String> *p_extensions) const { +void ResourceImporterOggVorbis::get_recognized_extensions(List<String> *p_extensions) const { p_extensions->push_back("ogg"); } -String ResourceImporterOGGVorbis::get_save_extension() const { +String ResourceImporterOggVorbis::get_save_extension() const { return "oggvorbisstr"; } -String ResourceImporterOGGVorbis::get_resource_type() const { - return "AudioStreamOGGVorbis"; +String ResourceImporterOggVorbis::get_resource_type() const { + return "AudioStreamOggVorbis"; } -bool ResourceImporterOGGVorbis::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const { +bool ResourceImporterOggVorbis::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const { return true; } -int ResourceImporterOGGVorbis::get_preset_count() const { +int ResourceImporterOggVorbis::get_preset_count() const { return 0; } -String ResourceImporterOGGVorbis::get_preset_name(int p_idx) const { +String ResourceImporterOggVorbis::get_preset_name(int p_idx) const { return String(); } -void ResourceImporterOGGVorbis::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { +void ResourceImporterOggVorbis::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "loop_offset"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "bpm", PROPERTY_HINT_RANGE, "0,400,0.01,or_greater"), 0)); @@ -80,9 +80,9 @@ void ResourceImporterOGGVorbis::get_import_options(const String &p_path, List<Im r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "bar_beats", PROPERTY_HINT_RANGE, "2,32,or_greater"), 4)); } -Ref<AudioStreamOGGVorbis> ResourceImporterOGGVorbis::import_ogg_vorbis(const String &p_path) { +Ref<AudioStreamOggVorbis> ResourceImporterOggVorbis::import_ogg_vorbis(const String &p_path) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); - ERR_FAIL_COND_V_MSG(f.is_null(), Ref<AudioStreamOGGVorbis>(), "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(f.is_null(), Ref<AudioStreamOggVorbis>(), "Cannot open file '" + p_path + "'."); uint64_t len = f->get_length(); @@ -92,10 +92,10 @@ Ref<AudioStreamOGGVorbis> ResourceImporterOGGVorbis::import_ogg_vorbis(const Str f->get_buffer(w, len); - Ref<AudioStreamOGGVorbis> ogg_vorbis_stream; + Ref<AudioStreamOggVorbis> ogg_vorbis_stream; ogg_vorbis_stream.instantiate(); - Ref<OGGPacketSequence> ogg_packet_sequence; + Ref<OggPacketSequence> ogg_packet_sequence; ogg_packet_sequence.instantiate(); ogg_stream_state stream_state; @@ -110,16 +110,16 @@ Ref<AudioStreamOGGVorbis> ResourceImporterOGGVorbis::import_ogg_vorbis(const Str size_t packet_count = 0; bool done = false; while (!done) { - ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOGGVorbis>(), "Ogg sync error " + itos(err)); + ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err)); while (ogg_sync_pageout(&sync_state, &page) != 1) { if (cursor >= len) { done = true; break; } - ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOGGVorbis>(), "Ogg sync error " + itos(err)); + ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err)); char *sync_buf = ogg_sync_buffer(&sync_state, OGG_SYNC_BUFFER_SIZE); - ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOGGVorbis>(), "Ogg sync error " + itos(err)); - ERR_FAIL_COND_V(cursor > len, Ref<AudioStreamOGGVorbis>()); + ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err)); + ERR_FAIL_COND_V(cursor > len, Ref<AudioStreamOggVorbis>()); size_t copy_size = len - cursor; if (copy_size > OGG_SYNC_BUFFER_SIZE) { copy_size = OGG_SYNC_BUFFER_SIZE; @@ -127,22 +127,22 @@ Ref<AudioStreamOGGVorbis> ResourceImporterOGGVorbis::import_ogg_vorbis(const Str memcpy(sync_buf, &file_data[cursor], copy_size); ogg_sync_wrote(&sync_state, copy_size); cursor += copy_size; - ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOGGVorbis>(), "Ogg sync error " + itos(err)); + ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err)); } if (done) { break; } - ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOGGVorbis>(), "Ogg sync error " + itos(err)); + ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err)); // Have a page now. if (!initialized_stream) { if (ogg_stream_init(&stream_state, ogg_page_serialno(&page))) { - ERR_FAIL_V_MSG(Ref<AudioStreamOGGVorbis>(), "Failed allocating memory for OGG Vorbis stream."); + ERR_FAIL_V_MSG(Ref<AudioStreamOggVorbis>(), "Failed allocating memory for Ogg Vorbis stream."); } initialized_stream = true; } ogg_stream_pagein(&stream_state, &page); - ERR_FAIL_COND_V_MSG((err = ogg_stream_check(&stream_state)), Ref<AudioStreamOGGVorbis>(), "Ogg stream error " + itos(err)); + ERR_FAIL_COND_V_MSG((err = ogg_stream_check(&stream_state)), Ref<AudioStreamOggVorbis>(), "Ogg stream error " + itos(err)); int desync_iters = 0; Vector<Vector<uint8_t>> packet_data; @@ -153,7 +153,7 @@ Ref<AudioStreamOGGVorbis> ResourceImporterOGGVorbis::import_ogg_vorbis(const Str if (err == -1) { // According to the docs this is usually recoverable, but don't sit here spinning forever. desync_iters++; - ERR_FAIL_COND_V_MSG(desync_iters > 100, Ref<AudioStreamOGGVorbis>(), "Packet sync issue during ogg import"); + ERR_FAIL_COND_V_MSG(desync_iters > 100, Ref<AudioStreamOggVorbis>(), "Packet sync issue during Ogg import"); continue; } else if (err == 0) { // Not enough data to fully reconstruct a packet. Go on to the next page. @@ -186,7 +186,7 @@ Ref<AudioStreamOGGVorbis> ResourceImporterOGGVorbis::import_ogg_vorbis(const Str ogg_sync_clear(&sync_state); if (ogg_packet_sequence->get_packet_granule_positions().is_empty()) { - ERR_FAIL_V_MSG(Ref<AudioStreamOGGVorbis>(), "OGG Vorbis decoding failed. Check that your data is a valid OGG Vorbis audio stream."); + ERR_FAIL_V_MSG(Ref<AudioStreamOggVorbis>(), "Ogg Vorbis decoding failed. Check that your data is a valid Ogg Vorbis audio stream."); } ogg_vorbis_stream->set_packet_sequence(ogg_packet_sequence); @@ -196,26 +196,26 @@ Ref<AudioStreamOGGVorbis> ResourceImporterOGGVorbis::import_ogg_vorbis(const Str #ifdef TOOLS_ENABLED -bool ResourceImporterOGGVorbis::has_advanced_options() const { +bool ResourceImporterOggVorbis::has_advanced_options() const { return true; } -void ResourceImporterOGGVorbis::show_advanced_options(const String &p_path) { - Ref<AudioStreamOGGVorbis> ogg_stream = import_ogg_vorbis(p_path); +void ResourceImporterOggVorbis::show_advanced_options(const String &p_path) { + Ref<AudioStreamOggVorbis> ogg_stream = import_ogg_vorbis(p_path); if (ogg_stream.is_valid()) { AudioStreamImportSettings::get_singleton()->edit(p_path, "oggvorbisstr", ogg_stream); } } #endif -Error ResourceImporterOGGVorbis::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterOggVorbis::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { bool loop = p_options["loop"]; float loop_offset = p_options["loop_offset"]; double bpm = p_options["bpm"]; int beat_count = p_options["beat_count"]; int bar_beats = p_options["bar_beats"]; - Ref<AudioStreamOGGVorbis> ogg_vorbis_stream = import_ogg_vorbis(p_source_file); + Ref<AudioStreamOggVorbis> ogg_vorbis_stream = import_ogg_vorbis(p_source_file); if (ogg_vorbis_stream.is_null()) { return ERR_CANT_OPEN; } @@ -226,8 +226,8 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin ogg_vorbis_stream->set_beat_count(beat_count); ogg_vorbis_stream->set_bar_beats(bar_beats); - return ResourceSaver::save(p_save_path + ".oggvorbisstr", ogg_vorbis_stream); + return ResourceSaver::save(ogg_vorbis_stream, p_save_path + ".oggvorbisstr"); } -ResourceImporterOGGVorbis::ResourceImporterOGGVorbis() { +ResourceImporterOggVorbis::ResourceImporterOggVorbis() { } diff --git a/modules/vorbis/resource_importer_ogg_vorbis.h b/modules/vorbis/resource_importer_ogg_vorbis.h index e6e98a29c1..a1a970e2cc 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.h +++ b/modules/vorbis/resource_importer_ogg_vorbis.h @@ -34,8 +34,8 @@ #include "audio_stream_ogg_vorbis.h" #include "core/io/resource_importer.h" -class ResourceImporterOGGVorbis : public ResourceImporter { - GDCLASS(ResourceImporterOGGVorbis, ResourceImporter); +class ResourceImporterOggVorbis : public ResourceImporter { + GDCLASS(ResourceImporterOggVorbis, ResourceImporter); enum { OGG_SYNC_BUFFER_SIZE = 8192, @@ -44,7 +44,7 @@ class ResourceImporterOGGVorbis : public ResourceImporter { private: // virtual int get_samples_in_packet(Vector<uint8_t> p_packet) = 0; - static Ref<AudioStreamOGGVorbis> import_ogg_vorbis(const String &p_path); + static Ref<AudioStreamOggVorbis> import_ogg_vorbis(const String &p_path); public: #ifdef TOOLS_ENABLED @@ -63,7 +63,7 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; - ResourceImporterOGGVorbis(); + ResourceImporterOggVorbis(); }; #endif // RESOURCE_IMPORTER_OGG_VORBIS_H diff --git a/modules/webp/resource_saver_webp.cpp b/modules/webp/resource_saver_webp.cpp index d270d39163..bd71c2869a 100644 --- a/modules/webp/resource_saver_webp.cpp +++ b/modules/webp/resource_saver_webp.cpp @@ -35,7 +35,7 @@ #include "scene/resources/texture.h" #include "webp_common.h" -Error ResourceSaverWebP::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceSaverWebP::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { Ref<ImageTexture> texture = p_resource; ERR_FAIL_COND_V_MSG(!texture.is_valid(), ERR_INVALID_PARAMETER, "Can't save invalid texture as WEBP."); diff --git a/modules/webp/resource_saver_webp.h b/modules/webp/resource_saver_webp.h index 59e944efa0..cbd5864463 100644 --- a/modules/webp/resource_saver_webp.h +++ b/modules/webp/resource_saver_webp.h @@ -39,7 +39,7 @@ public: static Error save_image(const String &p_path, const Ref<Image> &p_img, const bool p_lossy = false, const float p_quality = 0.75f); static Vector<uint8_t> save_image_to_buffer(const Ref<Image> &p_img, const bool p_lossy = false, const float p_quality = 0.75f); - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual bool recognize(const Ref<Resource> &p_resource) const; virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; diff --git a/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml b/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml index 3996a002ed..df92097135 100644 --- a/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml +++ b/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml @@ -57,7 +57,7 @@ Initialize the multiplayer peer with the given [code]peer_id[/code] (must be between 1 and 2147483647). If [code]server_compatibilty[/code] is [code]false[/code] (default), the multiplayer peer will be immediately in state [constant MultiplayerPeer.CONNECTION_CONNECTED] and [signal MultiplayerPeer.connection_succeeded] will not be emitted. If [code]server_compatibilty[/code] is [code]true[/code] the peer will suppress all [signal MultiplayerPeer.peer_connected] signals until a peer with id [constant MultiplayerPeer.TARGET_PEER_SERVER] connects and then emit [signal MultiplayerPeer.connection_succeeded]. After that the signal [signal MultiplayerPeer.peer_connected] will be emitted for every already connected peer, and any new peer that might connect. If the server peer disconnects after that, signal [signal MultiplayerPeer.server_disconnected] will be emitted and state will become [constant MultiplayerPeer.CONNECTION_CONNECTED]. - You can optionally specify a [code]channels_config[/code] array of [enum TransferMode] which will be used to create extra channels (WebRTC only supports one transfer mode per channel). + You can optionally specify a [code]channels_config[/code] array of [enum MultiplayerPeer.TransferMode] which will be used to create extra channels (WebRTC only supports one transfer mode per channel). </description> </method> <method name="remove_peer"> diff --git a/modules/webrtc/webrtc_multiplayer_peer.cpp b/modules/webrtc/webrtc_multiplayer_peer.cpp index 6f68b84ad3..e03b6b2473 100644 --- a/modules/webrtc/webrtc_multiplayer_peer.cpp +++ b/modules/webrtc/webrtc_multiplayer_peer.cpp @@ -197,14 +197,14 @@ Error WebRTCMultiplayerPeer::initialize(int p_self_id, bool p_server_compat, Arr cfg["ordered"] = true; switch (mode) { - case Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED: + case TRANSFER_MODE_UNRELIABLE_ORDERED: cfg["maxPacketLifetime"] = 1; break; - case Multiplayer::TRANSFER_MODE_UNRELIABLE: + case TRANSFER_MODE_UNRELIABLE: cfg["maxPacketLifetime"] = 1; cfg["ordered"] = false; break; - case Multiplayer::TRANSFER_MODE_RELIABLE: + case TRANSFER_MODE_RELIABLE: break; default: ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, vformat("The 'channels_config' array must contain only enum values from 'MultiplayerPeer.Multiplayer::TransferMode'. Got: %d", mode)); @@ -339,13 +339,13 @@ Error WebRTCMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_si int ch = get_transfer_channel(); if (ch == 0) { switch (get_transfer_mode()) { - case Multiplayer::TRANSFER_MODE_RELIABLE: + case TRANSFER_MODE_RELIABLE: ch = CH_RELIABLE; break; - case Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED: + case TRANSFER_MODE_UNRELIABLE_ORDERED: ch = CH_ORDERED; break; - case Multiplayer::TRANSFER_MODE_UNRELIABLE: + case TRANSFER_MODE_UNRELIABLE: ch = CH_UNRELIABLE; break; } diff --git a/modules/webrtc/webrtc_multiplayer_peer.h b/modules/webrtc/webrtc_multiplayer_peer.h index d4ed7ef7de..ea7c60036b 100644 --- a/modules/webrtc/webrtc_multiplayer_peer.h +++ b/modules/webrtc/webrtc_multiplayer_peer.h @@ -31,7 +31,7 @@ #ifndef WEBRTC_MULTIPLAYER_PEER_H #define WEBRTC_MULTIPLAYER_PEER_H -#include "core/multiplayer/multiplayer_peer.h" +#include "scene/main/multiplayer_peer.h" #include "webrtc_peer_connection.h" class WebRTCMultiplayerPeer : public MultiplayerPeer { diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp index f562de111f..056111ec92 100644 --- a/modules/websocket/register_types.cpp +++ b/modules/websocket/register_types.cpp @@ -33,11 +33,13 @@ #include "core/config/project_settings.h" #include "core/error/error_macros.h" +#include "websocket_client.h" +#include "websocket_server.h" + #ifdef JAVASCRIPT_ENABLED #include "emscripten.h" #include "emws_client.h" #include "emws_peer.h" -#include "emws_server.h" #else #include "wsl_client.h" #include "wsl_server.h" @@ -60,7 +62,6 @@ void initialize_websocket_module(ModuleInitializationLevel p_level) { #ifdef JAVASCRIPT_ENABLED EMWSPeer::make_default(); EMWSClient::make_default(); - EMWSServer::make_default(); #else WSLPeer::make_default(); WSLClient::make_default(); diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h index db529a669d..3259e78b3b 100644 --- a/modules/websocket/websocket_multiplayer_peer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -32,8 +32,8 @@ #define WEBSOCKET_MULTIPLAYER_PEER_H #include "core/error/error_list.h" -#include "core/multiplayer/multiplayer_peer.h" #include "core/templates/list.h" +#include "scene/main/multiplayer_peer.h" #include "websocket_peer.h" class WebSocketMultiplayerPeer : public MultiplayerPeer { diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp index 81802298d9..6427346365 100644 --- a/platform/android/android_input_handler.cpp +++ b/platform/android/android_input_handler.cpp @@ -56,10 +56,10 @@ void AndroidInputHandler::_set_key_modifier_state(Ref<InputEventWithModifiers> e ev->set_ctrl_pressed(control_mem); } -void AndroidInputHandler::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) { +void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycode, int p_unicode, bool p_pressed) { static char32_t prev_wc = 0; - char32_t unicode = p_unicode_char; - if ((p_unicode_char & 0xfffffc00) == 0xd800) { + char32_t unicode = p_unicode; + if ((p_unicode & 0xfffffc00) == 0xd800) { if (prev_wc != 0) { ERR_PRINT("invalid utf16 surrogate input"); } @@ -78,39 +78,38 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_scancode, int p Ref<InputEventKey> ev; ev.instantiate(); - int val = unicode; - Key keycode = android_get_keysym(p_keycode); - Key phy_keycode = android_get_keysym(p_scancode); - if (keycode == Key::SHIFT) { - shift_mem = p_pressed; + Key physical_keycode = godot_code_from_android_code(p_physical_keycode); + Key keycode = physical_keycode; + if (p_keycode != 0) { + keycode = godot_code_from_unicode(p_keycode); } - if (keycode == Key::ALT) { - alt_mem = p_pressed; - } - if (keycode == Key::CTRL) { - control_mem = p_pressed; - } - if (keycode == Key::META) { - meta_mem = p_pressed; + + switch (physical_keycode) { + case Key::SHIFT: { + shift_mem = p_pressed; + } break; + case Key::ALT: { + alt_mem = p_pressed; + } break; + case Key::CTRL: { + control_mem = p_pressed; + } break; + case Key::META: { + meta_mem = p_pressed; + } break; + default: + break; } ev->set_keycode(keycode); - ev->set_physical_keycode(phy_keycode); - ev->set_unicode(val); + ev->set_physical_keycode(physical_keycode); + ev->set_unicode(unicode); ev->set_pressed(p_pressed); _set_key_modifier_state(ev); - if (val == '\n') { - ev->set_keycode(Key::ENTER); - } else if (val == 61448) { - ev->set_keycode(Key::BACKSPACE); - ev->set_unicode((char32_t)Key::BACKSPACE); - } else if (val == 61453) { - ev->set_keycode(Key::ENTER); - ev->set_unicode((char32_t)Key::ENTER); - } else if (p_keycode == 4) { + if (p_physical_keycode == AKEYCODE_BACK) { if (DisplayServerAndroid *dsa = Object::cast_to<DisplayServerAndroid>(DisplayServer::get_singleton())) { dsa->send_window_event(DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST, true); } diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h index 1397ca59e4..6dfab7def8 100644 --- a/platform/android/android_input_handler.h +++ b/platform/android/android_input_handler.h @@ -83,7 +83,7 @@ public: void process_mouse_event(int input_device, int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor = 0, float event_horizontal_factor = 0); void process_double_tap(int event_android_button_mask, Point2 p_pos); void process_joy_event(JoypadEvent p_event); - void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed); + void process_key_event(int p_keycode, int p_physical_keycode, int p_unicode, bool p_pressed); }; #endif // ANDROID_INPUT_HANDLER_H diff --git a/platform/android/android_keys_utils.cpp b/platform/android/android_keys_utils.cpp index 885e4ff145..d2c5fdfd6c 100644 --- a/platform/android/android_keys_utils.cpp +++ b/platform/android/android_keys_utils.cpp @@ -30,12 +30,49 @@ #include "android_keys_utils.h" -Key android_get_keysym(unsigned int p_code) { - for (int i = 0; _ak_to_keycode[i].keysym != Key::UNKNOWN; i++) { - if (_ak_to_keycode[i].keycode == p_code) { - return _ak_to_keycode[i].keysym; +Key godot_code_from_android_code(unsigned int p_code) { + for (int i = 0; android_godot_code_pairs[i].android_code != AKEYCODE_MAX; i++) { + if (android_godot_code_pairs[i].android_code == p_code) { + return android_godot_code_pairs[i].godot_code; } } - return Key::UNKNOWN; } + +Key godot_code_from_unicode(unsigned int p_code) { + unsigned int code = p_code; + if (code > 0xFF) { + return Key::UNKNOWN; + } + // Known control codes. + if (code == '\b') { // 0x08 + return Key::BACKSPACE; + } + if (code == '\t') { // 0x09 + return Key::TAB; + } + if (code == '\n') { // 0x0A + return Key::ENTER; + } + if (code == 0x1B) { + return Key::ESCAPE; + } + if (code == 0x1F) { + return Key::KEY_DELETE; + } + // Unknown control codes. + if (code <= 0x1F || (code >= 0x80 && code <= 0x9F)) { + return Key::UNKNOWN; + } + // Convert to uppercase. + if (code >= 'a' && code <= 'z') { // 0x61 - 0x7A + code -= ('a' - 'A'); + } + if (code >= u'à' && code <= u'ö') { // 0xE0 - 0xF6 + code -= (u'à' - u'À'); // 0xE0 - 0xC0 + } + if (code >= u'ø' && code <= u'þ') { // 0xF8 - 0xFF + code -= (u'ø' - u'Ø'); // 0xF8 - 0xD8 + } + return Key(code); +} diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h index 24a6589fba..5ec3ee17aa 100644 --- a/platform/android/android_keys_utils.h +++ b/platform/android/android_keys_utils.h @@ -34,129 +34,140 @@ #include <android/input.h> #include <core/os/keyboard.h> -struct _WinTranslatePair { - Key keysym = Key::NONE; - unsigned int keycode = 0; +#define AKEYCODE_MAX 0xFFFF + +struct AndroidGodotCodePair { + unsigned int android_code = 0; + Key godot_code = Key::NONE; }; -static _WinTranslatePair _ak_to_keycode[] = { - { Key::TAB, AKEYCODE_TAB }, - { Key::ENTER, AKEYCODE_ENTER }, - { Key::SHIFT, AKEYCODE_SHIFT_LEFT }, - { Key::SHIFT, AKEYCODE_SHIFT_RIGHT }, - { Key::ALT, AKEYCODE_ALT_LEFT }, - { Key::ALT, AKEYCODE_ALT_RIGHT }, - { Key::MENU, AKEYCODE_MENU }, - { Key::PAUSE, AKEYCODE_MEDIA_PLAY_PAUSE }, - { Key::ESCAPE, AKEYCODE_BACK }, - { Key::SPACE, AKEYCODE_SPACE }, - { Key::PAGEUP, AKEYCODE_PAGE_UP }, - { Key::PAGEDOWN, AKEYCODE_PAGE_DOWN }, - { Key::HOME, AKEYCODE_HOME }, //(0x24) - { Key::LEFT, AKEYCODE_DPAD_LEFT }, - { Key::UP, AKEYCODE_DPAD_UP }, - { Key::RIGHT, AKEYCODE_DPAD_RIGHT }, - { Key::DOWN, AKEYCODE_DPAD_DOWN }, - { Key::PERIODCENTERED, AKEYCODE_DPAD_CENTER }, - { Key::BACKSPACE, AKEYCODE_DEL }, - { Key::KEY_0, AKEYCODE_0 }, - { Key::KEY_1, AKEYCODE_1 }, - { Key::KEY_2, AKEYCODE_2 }, - { Key::KEY_3, AKEYCODE_3 }, - { Key::KEY_4, AKEYCODE_4 }, - { Key::KEY_5, AKEYCODE_5 }, - { Key::KEY_6, AKEYCODE_6 }, - { Key::KEY_7, AKEYCODE_7 }, - { Key::KEY_8, AKEYCODE_8 }, - { Key::KEY_9, AKEYCODE_9 }, - { Key::A, AKEYCODE_A }, - { Key::B, AKEYCODE_B }, - { Key::C, AKEYCODE_C }, - { Key::D, AKEYCODE_D }, - { Key::E, AKEYCODE_E }, - { Key::F, AKEYCODE_F }, - { Key::G, AKEYCODE_G }, - { Key::H, AKEYCODE_H }, - { Key::I, AKEYCODE_I }, - { Key::J, AKEYCODE_J }, - { Key::K, AKEYCODE_K }, - { Key::L, AKEYCODE_L }, - { Key::M, AKEYCODE_M }, - { Key::N, AKEYCODE_N }, - { Key::O, AKEYCODE_O }, - { Key::P, AKEYCODE_P }, - { Key::Q, AKEYCODE_Q }, - { Key::R, AKEYCODE_R }, - { Key::S, AKEYCODE_S }, - { Key::T, AKEYCODE_T }, - { Key::U, AKEYCODE_U }, - { Key::V, AKEYCODE_V }, - { Key::W, AKEYCODE_W }, - { Key::X, AKEYCODE_X }, - { Key::Y, AKEYCODE_Y }, - { Key::Z, AKEYCODE_Z }, - { Key::HOMEPAGE, AKEYCODE_EXPLORER }, - { Key::LAUNCH0, AKEYCODE_BUTTON_A }, - { Key::LAUNCH1, AKEYCODE_BUTTON_B }, - { Key::LAUNCH2, AKEYCODE_BUTTON_C }, - { Key::LAUNCH3, AKEYCODE_BUTTON_X }, - { Key::LAUNCH4, AKEYCODE_BUTTON_Y }, - { Key::LAUNCH5, AKEYCODE_BUTTON_Z }, - { Key::LAUNCH6, AKEYCODE_BUTTON_L1 }, - { Key::LAUNCH7, AKEYCODE_BUTTON_R1 }, - { Key::LAUNCH8, AKEYCODE_BUTTON_L2 }, - { Key::LAUNCH9, AKEYCODE_BUTTON_R2 }, - { Key::LAUNCHA, AKEYCODE_BUTTON_THUMBL }, - { Key::LAUNCHB, AKEYCODE_BUTTON_THUMBR }, - { Key::LAUNCHC, AKEYCODE_BUTTON_START }, - { Key::LAUNCHD, AKEYCODE_BUTTON_SELECT }, - { Key::LAUNCHE, AKEYCODE_BUTTON_MODE }, - { Key::VOLUMEMUTE, AKEYCODE_MUTE }, - { Key::VOLUMEDOWN, AKEYCODE_VOLUME_DOWN }, - { Key::VOLUMEUP, AKEYCODE_VOLUME_UP }, - { Key::BACK, AKEYCODE_MEDIA_REWIND }, - { Key::FORWARD, AKEYCODE_MEDIA_FAST_FORWARD }, - { Key::MEDIANEXT, AKEYCODE_MEDIA_NEXT }, - { Key::MEDIAPREVIOUS, AKEYCODE_MEDIA_PREVIOUS }, - { Key::MEDIASTOP, AKEYCODE_MEDIA_STOP }, - { Key::PLUS, AKEYCODE_PLUS }, - { Key::EQUAL, AKEYCODE_EQUALS }, // the '+' key - { Key::COMMA, AKEYCODE_COMMA }, // the ',' key - { Key::MINUS, AKEYCODE_MINUS }, // the '-' key - { Key::SLASH, AKEYCODE_SLASH }, // the '/?' key - { Key::BACKSLASH, AKEYCODE_BACKSLASH }, - { Key::BRACKETLEFT, AKEYCODE_LEFT_BRACKET }, - { Key::BRACKETRIGHT, AKEYCODE_RIGHT_BRACKET }, - { Key::CTRL, AKEYCODE_CTRL_LEFT }, - { Key::CTRL, AKEYCODE_CTRL_RIGHT }, - { Key::UNKNOWN, 0 } +static AndroidGodotCodePair android_godot_code_pairs[] = { + { AKEYCODE_UNKNOWN, Key::UNKNOWN }, // (0) Unknown key code. + { AKEYCODE_HOME, Key::HOME }, // (3) Home key. + { AKEYCODE_BACK, Key::BACK }, // (4) Back key. + { AKEYCODE_0, Key::KEY_0 }, // (7) '0' key. + { AKEYCODE_1, Key::KEY_1 }, // (8) '1' key. + { AKEYCODE_2, Key::KEY_2 }, // (9) '2' key. + { AKEYCODE_3, Key::KEY_3 }, // (10) '3' key. + { AKEYCODE_4, Key::KEY_4 }, // (11) '4' key. + { AKEYCODE_5, Key::KEY_5 }, // (12) '5' key. + { AKEYCODE_6, Key::KEY_6 }, // (13) '6' key. + { AKEYCODE_7, Key::KEY_7 }, // (14) '7' key. + { AKEYCODE_8, Key::KEY_8 }, // (15) '8' key. + { AKEYCODE_9, Key::KEY_9 }, // (16) '9' key. + { AKEYCODE_STAR, Key::ASTERISK }, // (17) '*' key. + { AKEYCODE_POUND, Key::NUMBERSIGN }, // (18) '#' key. + { AKEYCODE_DPAD_UP, Key::UP }, // (19) Directional Pad Up key. + { AKEYCODE_DPAD_DOWN, Key::DOWN }, // (20) Directional Pad Down key. + { AKEYCODE_DPAD_LEFT, Key::LEFT }, // (21) Directional Pad Left key. + { AKEYCODE_DPAD_RIGHT, Key::RIGHT }, // (22) Directional Pad Right key. + { AKEYCODE_VOLUME_UP, Key::VOLUMEUP }, // (24) Volume Up key. + { AKEYCODE_VOLUME_DOWN, Key::VOLUMEDOWN }, // (25) Volume Down key. + { AKEYCODE_CLEAR, Key::CLEAR }, // (28) Clear key. + { AKEYCODE_A, Key::A }, // (29) 'A' key. + { AKEYCODE_B, Key::B }, // (30) 'B' key. + { AKEYCODE_C, Key::C }, // (31) 'C' key. + { AKEYCODE_D, Key::D }, // (32) 'D' key. + { AKEYCODE_E, Key::E }, // (33) 'E' key. + { AKEYCODE_F, Key::F }, // (34) 'F' key. + { AKEYCODE_G, Key::G }, // (35) 'G' key. + { AKEYCODE_H, Key::H }, // (36) 'H' key. + { AKEYCODE_I, Key::I }, // (37) 'I' key. + { AKEYCODE_J, Key::J }, // (38) 'J' key. + { AKEYCODE_K, Key::K }, // (39) 'K' key. + { AKEYCODE_L, Key::L }, // (40) 'L' key. + { AKEYCODE_M, Key::M }, // (41) 'M' key. + { AKEYCODE_N, Key::N }, // (42) 'N' key. + { AKEYCODE_O, Key::O }, // (43) 'O' key. + { AKEYCODE_P, Key::P }, // (44) 'P' key. + { AKEYCODE_Q, Key::Q }, // (45) 'Q' key. + { AKEYCODE_R, Key::R }, // (46) 'R' key. + { AKEYCODE_S, Key::S }, // (47) 'S' key. + { AKEYCODE_T, Key::T }, // (48) 'T' key. + { AKEYCODE_U, Key::U }, // (49) 'U' key. + { AKEYCODE_V, Key::V }, // (50) 'V' key. + { AKEYCODE_W, Key::W }, // (51) 'W' key. + { AKEYCODE_X, Key::X }, // (52) 'X' key. + { AKEYCODE_Y, Key::Y }, // (53) 'Y' key. + { AKEYCODE_Z, Key::Z }, // (54) 'Z' key. + { AKEYCODE_COMMA, Key::COMMA }, // (55) ',’ key. + { AKEYCODE_PERIOD, Key::PERIOD }, // (56) '.' key. + { AKEYCODE_ALT_LEFT, Key::ALT }, // (57) Left Alt modifier key. + { AKEYCODE_ALT_RIGHT, Key::ALT }, // (58) Right Alt modifier key. + { AKEYCODE_SHIFT_LEFT, Key::SHIFT }, // (59) Left Shift modifier key. + { AKEYCODE_SHIFT_RIGHT, Key::SHIFT }, // (60) Right Shift modifier key. + { AKEYCODE_TAB, Key::TAB }, // (61) Tab key. + { AKEYCODE_SPACE, Key::SPACE }, // (62) Space key. + { AKEYCODE_ENTER, Key::ENTER }, // (66) Enter key. + { AKEYCODE_DEL, Key::BACKSPACE }, // (67) Backspace key. + { AKEYCODE_GRAVE, Key::QUOTELEFT }, // (68) '`' (backtick) key. + { AKEYCODE_MINUS, Key::MINUS }, // (69) '-'. + { AKEYCODE_EQUALS, Key::EQUAL }, // (70) '=' key. + { AKEYCODE_LEFT_BRACKET, Key::BRACKETLEFT }, // (71) '[' key. + { AKEYCODE_RIGHT_BRACKET, Key::BRACKETRIGHT }, // (72) ']' key. + { AKEYCODE_BACKSLASH, Key::BACKSLASH }, // (73) '\' key. + { AKEYCODE_SEMICOLON, Key::SEMICOLON }, // (74) ';' key. + { AKEYCODE_APOSTROPHE, Key::APOSTROPHE }, // (75) ''' (apostrophe) key. + { AKEYCODE_SLASH, Key::SLASH }, // (76) '/' key. + { AKEYCODE_AT, Key::AT }, // (77) '@' key. + { AKEYCODE_PLUS, Key::PLUS }, // (81) '+' key. + { AKEYCODE_MENU, Key::MENU }, // (82) Menu key. + { AKEYCODE_SEARCH, Key::SEARCH }, // (84) Search key. + { AKEYCODE_MEDIA_STOP, Key::MEDIASTOP }, // (86) Stop media key. + { AKEYCODE_MEDIA_PREVIOUS, Key::MEDIAPREVIOUS }, // (88) Play Previous media key. + { AKEYCODE_PAGE_UP, Key::PAGEUP }, // (92) Page Up key. + { AKEYCODE_PAGE_DOWN, Key::PAGEDOWN }, // (93) Page Down key. + { AKEYCODE_ESCAPE, Key::ESCAPE }, // (111) Escape key. + { AKEYCODE_FORWARD_DEL, Key::KEY_DELETE }, // (112) Forward Delete key. + { AKEYCODE_CTRL_LEFT, Key::CTRL }, // (113) Left Control modifier key. + { AKEYCODE_CTRL_RIGHT, Key::CTRL }, // (114) Right Control modifier key. + { AKEYCODE_CAPS_LOCK, Key::CAPSLOCK }, // (115) Caps Lock key. + { AKEYCODE_SCROLL_LOCK, Key::SCROLLLOCK }, // (116) Scroll Lock key. + { AKEYCODE_META_LEFT, Key::META }, // (117) Left Meta modifier key. + { AKEYCODE_META_RIGHT, Key::META }, // (118) Right Meta modifier key. + { AKEYCODE_SYSRQ, Key::PRINT }, // (120) System Request / Print Screen key. + { AKEYCODE_BREAK, Key::PAUSE }, // (121) Break / Pause key. + { AKEYCODE_INSERT, Key::INSERT }, // (124) Insert key. + { AKEYCODE_FORWARD, Key::FORWARD }, // (125) Forward key. + { AKEYCODE_MEDIA_PLAY, Key::MEDIAPLAY }, // (126) Play media key. + { AKEYCODE_MEDIA_RECORD, Key::MEDIARECORD }, // (130) Record media key. + { AKEYCODE_F1, Key::F1 }, // (131) F1 key. + { AKEYCODE_F2, Key::F2 }, // (132) F2 key. + { AKEYCODE_F3, Key::F3 }, // (133) F3 key. + { AKEYCODE_F4, Key::F4 }, // (134) F4 key. + { AKEYCODE_F5, Key::F5 }, // (135) F5 key. + { AKEYCODE_F6, Key::F6 }, // (136) F6 key. + { AKEYCODE_F7, Key::F7 }, // (137) F7 key. + { AKEYCODE_F8, Key::F8 }, // (138) F8 key. + { AKEYCODE_F9, Key::F9 }, // (139) F9 key. + { AKEYCODE_F10, Key::F10 }, // (140) F10 key. + { AKEYCODE_F11, Key::F11 }, // (141) F11 key. + { AKEYCODE_F12, Key::F12 }, // (142) F12 key. + { AKEYCODE_NUM_LOCK, Key::NUMLOCK }, // (143) Num Lock key. + { AKEYCODE_NUMPAD_0, Key::KP_0 }, // (144) Numeric keypad '0' key. + { AKEYCODE_NUMPAD_1, Key::KP_1 }, // (145) Numeric keypad '1' key. + { AKEYCODE_NUMPAD_2, Key::KP_2 }, // (146) Numeric keypad '2' key. + { AKEYCODE_NUMPAD_3, Key::KP_3 }, // (147) Numeric keypad '3' key. + { AKEYCODE_NUMPAD_4, Key::KP_4 }, // (148) Numeric keypad '4' key. + { AKEYCODE_NUMPAD_5, Key::KP_5 }, // (149) Numeric keypad '5' key. + { AKEYCODE_NUMPAD_6, Key::KP_6 }, // (150) Numeric keypad '6' key. + { AKEYCODE_NUMPAD_7, Key::KP_7 }, // (151) Numeric keypad '7' key. + { AKEYCODE_NUMPAD_8, Key::KP_8 }, // (152) Numeric keypad '8' key. + { AKEYCODE_NUMPAD_9, Key::KP_9 }, // (153) Numeric keypad '9' key. + { AKEYCODE_NUMPAD_DIVIDE, Key::KP_DIVIDE }, // (154) Numeric keypad '/' key (for division). + { AKEYCODE_NUMPAD_MULTIPLY, Key::KP_MULTIPLY }, // (155) Numeric keypad '*' key (for multiplication). + { AKEYCODE_NUMPAD_SUBTRACT, Key::KP_SUBTRACT }, // (156) Numeric keypad '-' key (for subtraction). + { AKEYCODE_NUMPAD_ADD, Key::KP_ADD }, // (157) Numeric keypad '+' key (for addition). + { AKEYCODE_NUMPAD_DOT, Key::KP_PERIOD }, // (158) Numeric keypad '.' key (for decimals or digit grouping). + { AKEYCODE_NUMPAD_ENTER, Key::KP_ENTER }, // (160) Numeric keypad Enter key. + { AKEYCODE_VOLUME_MUTE, Key::VOLUMEMUTE }, // (164) Volume Mute key. + { AKEYCODE_YEN, Key::YEN }, // (216) Japanese Yen key. + { AKEYCODE_HELP, Key::HELP }, // (259) Help key. + { AKEYCODE_REFRESH, Key::REFRESH }, // (285) Refresh key. + { AKEYCODE_MAX, Key::UNKNOWN } }; -/* -TODO: map these android key: - AKEYCODE_SOFT_LEFT = 1, - AKEYCODE_SOFT_RIGHT = 2, - AKEYCODE_CALL = 5, - AKEYCODE_ENDCALL = 6, - AKEYCODE_STAR = 17, - AKEYCODE_POUND = 18, - AKEYCODE_POWER = 26, - AKEYCODE_CAMERA = 27, - AKEYCODE_CLEAR = 28, - AKEYCODE_SYM = 63, - AKEYCODE_ENVELOPE = 65, - AKEYCODE_GRAVE = 68, - AKEYCODE_SEMICOLON = 74, - AKEYCODE_APOSTROPHE = 75, - AKEYCODE_AT = 77, - AKEYCODE_NUM = 78, - AKEYCODE_HEADSETHOOK = 79, - AKEYCODE_FOCUS = 80, // *Camera* focus - AKEYCODE_NOTIFICATION = 83, - AKEYCODE_SEARCH = 84, - AKEYCODE_PICTSYMBOLS = 94, - AKEYCODE_SWITCH_CHARSET = 95, -*/ -Key android_get_keysym(unsigned int p_code); +Key godot_code_from_android_code(unsigned int p_code); +Key godot_code_from_unicode(unsigned int p_code); #endif // ANDROID_KEYS_UTILS_H diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 3be220d110..b51dd18af6 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -221,12 +221,12 @@ bool DisplayServerAndroid::screen_is_touchscreen(int p_screen) const { return true; } -void DisplayServerAndroid::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) { +void DisplayServerAndroid::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) { GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); ERR_FAIL_NULL(godot_io_java); if (godot_io_java->has_vk()) { - godot_io_java->show_vk(p_existing_text, p_multiline, p_max_length, p_cursor_start, p_cursor_end); + godot_io_java->show_vk(p_existing_text, (int)p_type, p_max_length, p_cursor_start, p_cursor_end); } else { ERR_PRINT("Virtual keyboard not available"); } @@ -276,9 +276,9 @@ void DisplayServerAndroid::_window_callback(const Callable &p_callable, const Va Variant ret; Callable::CallError ce; if (p_deferred) { - p_callable.call((const Variant **)&argp, 1, ret, ce); + p_callable.callp((const Variant **)&argp, 1, ret, ce); } else { - p_callable.call_deferred((const Variant **)&argp, 1); + p_callable.call_deferredp((const Variant **)&argp, 1); } } } @@ -482,7 +482,7 @@ void DisplayServerAndroid::notify_surface_changed(int p_width, int p_height) { Variant ret; Callable::CallError ce; - rect_changed_callback.call(reinterpret_cast<const Variant **>(&sizep), 1, ret, ce); + rect_changed_callback.callp(reinterpret_cast<const Variant **>(&sizep), 1, ret, ce); } DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index 65bf2ec1a8..2f30642319 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -122,7 +122,7 @@ public: virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override; + virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), VirtualKeyboardType p_type = KEYBOARD_TYPE_DEFAULT, int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override; virtual void virtual_keyboard_hide() override; virtual int virtual_keyboard_get_height() const override; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 560f188b82..5bbe0ffab6 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -30,10 +30,10 @@ #include "export.h" -#include "export_plugin.h" - #include "core/os/os.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" +#include "export_plugin.h" void register_android_exporter() { EDITOR_DEF("export/android/android_sdk_path", ""); diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 2cfb152804..6f1b4bde40 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -1671,7 +1671,7 @@ Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExp return enabled_abis; } -void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { +void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name"); if (driver == "opengl3") { r_features->push_back("etc"); @@ -1705,6 +1705,8 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio } plugins_changed.clear(); + // Android supports multiple architectures in an app bundle, so + // we expose each option as a checkbox in the export dialog. const Vector<String> abis = get_abis(); for (int i = 0; i < abis.size(); ++i) { const String abi = abis[i]; @@ -3109,7 +3111,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP CLEANUP_AND_RETURN(OK); } -void EditorExportPlatformAndroid::get_platform_features(List<String> *r_features) { +void EditorExportPlatformAndroid::get_platform_features(List<String> *r_features) const { r_features->push_back("mobile"); r_features->push_back("android"); } diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h index 15ac8091be..1da3f68f9a 100644 --- a/platform/android/export/export_plugin.h +++ b/platform/android/export/export_plugin.h @@ -35,7 +35,7 @@ #include "core/io/zip_io.h" #include "core/os/os.h" -#include "editor/editor_export.h" +#include "editor/export/editor_export_platform.h" const String SPLASH_CONFIG_XML_CONTENT = R"SPLASH(<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> @@ -156,7 +156,7 @@ public: typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); public: - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override; + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; virtual void get_export_options(List<ExportOption> *r_options) override; @@ -231,7 +231,7 @@ public: Error export_project_helper(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int export_format, bool should_sign, int p_flags); - virtual void get_platform_features(List<String> *r_features) override; + virtual void get_platform_features(List<String> *r_features) const override; virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override; diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index 018ae649d6..232b4458c6 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -35,7 +35,7 @@ #include "core/io/file_access.h" #include "core/io/zip_io.h" #include "core/os/os.h" -#include "editor/editor_export.h" +#include "editor/export/editor_export.h" const String godot_project_name_xml_string = R"(<?xml version="1.0" encoding="utf-8"?> <!--WARNING: THIS FILE WILL BE OVERWRITTEN AT BUILD TIME--> diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h index e6fd8c857b..8d7ade8ead 100644 --- a/platform/android/file_access_android.h +++ b/platform/android/file_access_android.h @@ -49,34 +49,34 @@ class FileAccessAndroid : public FileAccess { public: static AAssetManager *asset_manager; - virtual Error _open(const String &p_path, int p_mode_flags); // open a file - virtual bool is_open() const; // true when file is open + virtual Error _open(const String &p_path, int p_mode_flags) override; // open a file + virtual bool is_open() const override; // true when file is open /// returns the path for the current open file - virtual String get_path() const; + virtual String get_path() const override; /// returns the absolute path for the current open file - virtual String get_path_absolute() const; + virtual String get_path_absolute() const override; - virtual void seek(uint64_t p_position); // seek to a given position - virtual void seek_end(int64_t p_position = 0); // seek from the end of file - virtual uint64_t get_position() const; // get position in the file - virtual uint64_t get_length() const; // get size of the file + virtual void seek(uint64_t p_position) override; // seek to a given position + virtual void seek_end(int64_t p_position = 0) override; // seek from the end of file + virtual uint64_t get_position() const override; // get position in the file + virtual uint64_t get_length() const override; // get size of the file - virtual bool eof_reached() const; // reading passed EOF + virtual bool eof_reached() const override; // reading passed EOF - virtual uint8_t get_8() const; // get a byte - virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; + virtual uint8_t get_8() const override; // get a byte + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override; - virtual Error get_error() const; // get last error + virtual Error get_error() const override; // get last error - virtual void flush(); - virtual void store_8(uint8_t p_dest); // store a byte + virtual void flush() override; + virtual void store_8(uint8_t p_dest) override; // store a byte - virtual bool file_exists(const String &p_path); // return true if a file exists + virtual bool file_exists(const String &p_path) override; // return true if a file exists - virtual uint64_t _get_modified_time(const String &p_file) { return 0; } - virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; } - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; } + virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } + virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; } + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; } ~FileAccessAndroid(); }; diff --git a/platform/android/file_access_filesystem_jandroid.cpp b/platform/android/file_access_filesystem_jandroid.cpp index 733d92f741..6b21c18d59 100644 --- a/platform/android/file_access_filesystem_jandroid.cpp +++ b/platform/android/file_access_filesystem_jandroid.cpp @@ -29,9 +29,11 @@ /*************************************************************************/ #include "file_access_filesystem_jandroid.h" + #include "core/os/os.h" #include "core/templates/local_vector.h" #include "thread_jandroid.h" + #include <unistd.h> jobject FileAccessFilesystemJAndroid::file_access_handler = nullptr; @@ -198,7 +200,7 @@ String FileAccessFilesystemJAndroid::get_line() const { if (elem == '\n' || elem == '\0') { // Found the end of the line const_cast<FileAccessFilesystemJAndroid *>(this)->seek(start_position + line_buffer_position + 1); - if (result.parse_utf8((const char *)line_buffer.ptr(), line_buffer_position)) { + if (result.parse_utf8((const char *)line_buffer.ptr(), line_buffer_position, true)) { return String(); } return result; @@ -206,7 +208,7 @@ String FileAccessFilesystemJAndroid::get_line() const { } } - if (result.parse_utf8((const char *)line_buffer.ptr(), line_buffer_position)) { + if (result.parse_utf8((const char *)line_buffer.ptr(), line_buffer_position, true)) { return String(); } return result; diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java index 0434efdf4c..d283de8ce8 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -203,9 +203,10 @@ public class GodotIO { return result; } - public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { - if (edit != null) - edit.showKeyboard(p_existing_text, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end); + public void showKeyboard(String p_existing_text, int p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) { + if (edit != null) { + edit.showKeyboard(p_existing_text, GodotEditText.VirtualKeyboardType.values()[p_type], p_max_input_length, p_cursor_start, p_cursor_end); + } //InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE); //inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java index e2ae62d9cf..f855fc6cf6 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java @@ -151,7 +151,7 @@ public class GodotLib { /** * Forward regular key events from the main thread to the GL thread. */ - public static native void key(int p_keycode, int p_scancode, int p_unicode_char, boolean p_pressed); + public static native void key(int p_keycode, int p_physical_keycode, int p_unicode, boolean p_pressed); /** * Forward game device's key events from the main thread to the GL thread. diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java index ecb2af0a7b..7925b54fc4 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java @@ -52,6 +52,18 @@ public class GodotEditText extends EditText { private final static int HANDLER_OPEN_IME_KEYBOARD = 2; private final static int HANDLER_CLOSE_IME_KEYBOARD = 3; + // Enum must be kept up-to-date with DisplayServer::VirtualKeyboardType + public enum VirtualKeyboardType { + KEYBOARD_TYPE_DEFAULT, + KEYBOARD_TYPE_MULTILINE, + KEYBOARD_TYPE_NUMBER, + KEYBOARD_TYPE_NUMBER_DECIMAL, + KEYBOARD_TYPE_PHONE, + KEYBOARD_TYPE_EMAIL_ADDRESS, + KEYBOARD_TYPE_PASSWORD, + KEYBOARD_TYPE_URL + } + // =========================================================== // Fields // =========================================================== @@ -60,7 +72,7 @@ public class GodotEditText extends EditText { private EditHandler sHandler = new EditHandler(this); private String mOriginText; private int mMaxInputLength = Integer.MAX_VALUE; - private boolean mMultiline = false; + private VirtualKeyboardType mKeyboardType = VirtualKeyboardType.KEYBOARD_TYPE_DEFAULT; private static class EditHandler extends Handler { private final WeakReference<GodotEditText> mEdit; @@ -100,8 +112,8 @@ public class GodotEditText extends EditText { setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_DONE); } - public boolean isMultiline() { - return mMultiline; + public VirtualKeyboardType getKeyboardType() { + return mKeyboardType; } private void handleMessage(final Message msg) { @@ -122,8 +134,31 @@ public class GodotEditText extends EditText { } int inputType = InputType.TYPE_CLASS_TEXT; - if (edit.isMultiline()) { - inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE; + switch (edit.getKeyboardType()) { + case KEYBOARD_TYPE_DEFAULT: + inputType = InputType.TYPE_CLASS_TEXT; + break; + case KEYBOARD_TYPE_MULTILINE: + inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE; + break; + case KEYBOARD_TYPE_NUMBER: + inputType = InputType.TYPE_CLASS_NUMBER; + break; + case KEYBOARD_TYPE_NUMBER_DECIMAL: + inputType = InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; + break; + case KEYBOARD_TYPE_PHONE: + inputType = InputType.TYPE_CLASS_PHONE; + break; + case KEYBOARD_TYPE_EMAIL_ADDRESS: + inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; + break; + case KEYBOARD_TYPE_PASSWORD: + inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD; + break; + case KEYBOARD_TYPE_URL: + inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI; + break; } edit.setInputType(inputType); @@ -201,7 +236,7 @@ public class GodotEditText extends EditText { // =========================================================== // Methods // =========================================================== - public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { + public void showKeyboard(String p_existing_text, VirtualKeyboardType p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) { int maxInputLength = (p_max_input_length <= 0) ? Integer.MAX_VALUE : p_max_input_length; if (p_cursor_start == -1) { // cursor position not given this.mOriginText = p_existing_text; @@ -214,7 +249,7 @@ public class GodotEditText extends EditText { this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_end); } - this.mMultiline = p_multiline; + this.mKeyboardType = p_type; final Message msg = new Message(); msg.what = HANDLER_OPEN_IME_KEYBOARD; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index ccfb865b1a..da15b2490c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -96,10 +96,14 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { GodotLib.joybutton(godotJoyId, button, false); } } else { - final int scanCode = event.getScanCode(); - final int chr = event.getUnicodeChar(0); - GodotLib.key(keyCode, scanCode, chr, false); - } + // getKeyCode(): The physical key that was pressed. + // Godot's keycodes match the ASCII codes, so for single byte unicode characters, + // we can use the unmodified unicode character to determine Godot's keycode. + final int keycode = event.getUnicodeChar(0); + final int physical_keycode = event.getKeyCode(); + final int unicode = event.getUnicodeChar(); + GodotLib.key(keycode, physical_keycode, unicode, false); + }; return true; } @@ -131,9 +135,10 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { GodotLib.joybutton(godotJoyId, button, true); } } else { - final int scanCode = event.getScanCode(); - final int chr = event.getUnicodeChar(0); - GodotLib.key(keyCode, scanCode, chr, true); + final int keycode = event.getUnicodeChar(0); + final int physical_keycode = event.getKeyCode(); + final int unicode = event.getUnicodeChar(); + GodotLib.key(keycode, physical_keycode, unicode, true); } return true; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index e940aafa9e..c959b5f28c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -92,11 +92,9 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene @Override public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) { - //Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after); - for (int i = 0; i < count; ++i) { - GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false); + GodotLib.key(0, KeyEvent.KEYCODE_DEL, 0, true); + GodotLib.key(0, KeyEvent.KEYCODE_DEL, 0, false); if (mHasSelection) { mHasSelection = false; @@ -107,20 +105,18 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene @Override public void onTextChanged(final CharSequence pCharSequence, final int start, final int before, final int count) { - //Log.d(TAG, "onTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",before: " + before); - final int[] newChars = new int[count]; for (int i = start; i < start + count; ++i) { newChars[i - start] = pCharSequence.charAt(i); } for (int i = 0; i < count; ++i) { int key = newChars[i]; - if ((key == '\n') && !mEdit.isMultiline()) { + if ((key == '\n') && !(mEdit.getKeyboardType() == GodotEditText.VirtualKeyboardType.KEYBOARD_TYPE_MULTILINE)) { // Return keys are handled through action events continue; } - GodotLib.key(0, 0, key, true); - GodotLib.key(0, 0, key, false); + GodotLib.key(key, 0, key, true); + GodotLib.key(key, 0, key, false); } } @@ -131,16 +127,16 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene for (int i = 0; i < characters.length(); i++) { final int ch = characters.codePointAt(i); - GodotLib.key(0, 0, ch, true); - GodotLib.key(0, 0, ch, false); + GodotLib.key(ch, 0, ch, true); + GodotLib.key(ch, 0, ch, false); } } if (pActionID == EditorInfo.IME_ACTION_DONE) { // Enter key has been pressed mRenderView.queueOnRenderThread(() -> { - GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true); - GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false); + GodotLib.key(0, KeyEvent.KEYCODE_ENTER, 0, true); + GodotLib.key(0, KeyEvent.KEYCODE_ENTER, 0, false); }); mRenderView.getView().requestFocus(); return true; diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index b71c6ef1e6..5877c15114 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -61,7 +61,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc _get_scaled_density = p_env->GetMethodID(cls, "getScaledDensity", "()F"); _get_screen_refresh_rate = p_env->GetMethodID(cls, "getScreenRefreshRate", "(D)D"); _get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;"); - _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;ZIII)V"); + _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;IIII)V"); _hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V"); _set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V"); _get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I"); @@ -214,12 +214,12 @@ bool GodotIOJavaWrapper::has_vk() { return (_show_keyboard != nullptr) && (_hide_keyboard != nullptr); } -void GodotIOJavaWrapper::show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { +void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) { if (_show_keyboard) { JNIEnv *env = get_jni_env(); ERR_FAIL_NULL(env); jstring jStr = env->NewStringUTF(p_existing.utf8().get_data()); - env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end); + env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_type, p_max_input_length, p_cursor_start, p_cursor_end); } } diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index aec7d1db97..dc68f4d90d 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -82,7 +82,7 @@ public: Rect2i get_display_safe_area(); String get_unique_id(); bool has_vk(); - void show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end); + void show_vk(const String &p_existing, int p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end); void hide_vk(); int get_vk_height(); void set_vk_height(int p_height); diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index f4de4acfad..422c05e5ce 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -376,12 +376,11 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged( } // Called on the UI thread -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_physical_keycode, jint p_unicode, jboolean p_pressed) { if (step.get() <= 0) { return; } - - input_handler->process_key_event(p_keycode, p_scancode, p_unicode_char, p_pressed); + input_handler->process_key_event(p_keycode, p_physical_keycode, p_unicode, p_pressed); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) { diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h index de16f197b8..3c48ca0459 100644 --- a/platform/android/java_godot_lib_jni.h +++ b/platform/android/java_godot_lib_jni.h @@ -51,7 +51,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FI(JNIEn JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y); -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_physical_keycode, jint p_unicode, jboolean p_pressed); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y); diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h index 5dd4d177ea..bbb2dd3ab3 100644 --- a/platform/ios/display_server_ios.h +++ b/platform/ios/display_server_ios.h @@ -199,7 +199,7 @@ public: virtual bool screen_is_touchscreen(int p_screen) const override; - virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) override; + virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) override; virtual void virtual_keyboard_hide() override; void virtual_keyboard_set_height(int height); diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index 73d4a2a427..6ce7e676a2 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -128,7 +128,7 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode } #endif - bool keep_screen_on = bool(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true)); + bool keep_screen_on = bool(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); screen_set_keep_on(keep_screen_on); Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); @@ -219,7 +219,7 @@ void DisplayServerIOS::_window_callback(const Callable &p_callable, const Varian const Variant *argp = &p_arg; Variant ret; Callable::CallError ce; - p_callable.call((const Variant **)&argp, 1, ret, ce); + p_callable.callp((const Variant **)&argp, 1, ret, ce); } } @@ -585,12 +585,44 @@ bool DisplayServerIOS::screen_is_touchscreen(int p_screen) const { return true; } -void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) { +void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) { NSString *existingString = [[NSString alloc] initWithUTF8String:p_existing_text.utf8().get_data()]; + AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault; + AppDelegate.viewController.keyboardView.textContentType = nil; + switch (p_type) { + case KEYBOARD_TYPE_DEFAULT: { + AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault; + } break; + case KEYBOARD_TYPE_MULTILINE: { + AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault; + } break; + case KEYBOARD_TYPE_NUMBER: { + AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeNumberPad; + } break; + case KEYBOARD_TYPE_NUMBER_DECIMAL: { + AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeDecimalPad; + } break; + case KEYBOARD_TYPE_PHONE: { + AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypePhonePad; + AppDelegate.viewController.keyboardView.textContentType = UITextContentTypeTelephoneNumber; + } break; + case KEYBOARD_TYPE_EMAIL_ADDRESS: { + AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeEmailAddress; + AppDelegate.viewController.keyboardView.textContentType = UITextContentTypeEmailAddress; + } break; + case KEYBOARD_TYPE_PASSWORD: { + AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault; + AppDelegate.viewController.keyboardView.textContentType = UITextContentTypePassword; + } break; + case KEYBOARD_TYPE_URL: { + AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeWebSearch; + AppDelegate.viewController.keyboardView.textContentType = UITextContentTypeURL; + } break; + } + [AppDelegate.viewController.keyboardView becomeFirstResponderWithString:existingString - multiline:p_multiline cursorStart:p_cursor_start cursorEnd:p_cursor_end]; } diff --git a/platform/ios/export/export.cpp b/platform/ios/export/export.cpp index 1531c2bde5..6024db2f2c 100644 --- a/platform/ios/export/export.cpp +++ b/platform/ios/export/export.cpp @@ -30,6 +30,7 @@ #include "export.h" +#include "editor/export/editor_export.h" #include "export_plugin.h" void register_ios_exporter() { diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp index a2e80d33fd..2ac44ccf8b 100644 --- a/platform/ios/export/export_plugin.cpp +++ b/platform/ios/export/export_plugin.cpp @@ -30,9 +30,10 @@ #include "export_plugin.h" +#include "core/string/translation.h" #include "editor/editor_node.h" -void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { +void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name"); // Vulkan and OpenGL ES 3.0 both mandate ETC2 support. r_features->push_back("etc2"); @@ -43,7 +44,7 @@ void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> } } -Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_get_supported_architectures() { +Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_get_supported_architectures() const { Vector<ExportArchitecture> archs; archs.push_back(ExportArchitecture("arm64", true)); return archs; @@ -1155,7 +1156,7 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir return OK; } -Vector<String> EditorExportPlatformIOS::_get_preset_architectures(const Ref<EditorExportPreset> &p_preset) { +Vector<String> EditorExportPlatformIOS::_get_preset_architectures(const Ref<EditorExportPreset> &p_preset) const { Vector<ExportArchitecture> all_archs = _get_supported_architectures(); Vector<String> enabled_archs; for (int i = 0; i < all_archs.size(); ++i) { @@ -1527,8 +1528,6 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p //write - file = file.replace_first("ios/", ""); - if (files_to_parse.has(file)) { _fix_config_file(p_preset, data, config_data, p_debug); } else if (file.begins_with("libgodot.ios")) { diff --git a/platform/ios/export/export_plugin.h b/platform/ios/export/export_plugin.h index 91b13419f1..07e30c1d00 100644 --- a/platform/ios/export/export_plugin.h +++ b/platform/ios/export/export_plugin.h @@ -40,8 +40,8 @@ #include "core/os/os.h" #include "core/templates/safe_refcount.h" #include "core/version.h" -#include "editor/editor_export.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export_platform.h" #include "main/splash.gen.h" #include "platform/ios/logo.gen.h" #include "string.h" @@ -106,8 +106,8 @@ class EditorExportPlatformIOS : public EditorExportPlatform { Error _export_loading_screen_file(const Ref<EditorExportPreset> &p_preset, const String &p_dest_dir); Error _export_icons(const Ref<EditorExportPreset> &p_preset, const String &p_iconset_dir); - Vector<ExportArchitecture> _get_supported_architectures(); - Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset); + Vector<ExportArchitecture> _get_supported_architectures() const; + Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset) const; void _add_assets_to_project(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets); Error _export_additional_assets(const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets); @@ -173,7 +173,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform { } protected: - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override; + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; virtual void get_export_options(List<ExportOption> *r_options) override; public: @@ -199,7 +199,7 @@ public: virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; - virtual void get_platform_features(List<String> *r_features) override { + virtual void get_platform_features(List<String> *r_features) const override { r_features->push_back("mobile"); r_features->push_back("ios"); } diff --git a/platform/ios/keyboard_input_view.h b/platform/ios/keyboard_input_view.h index 33fa5d571a..fc34e6a11b 100644 --- a/platform/ios/keyboard_input_view.h +++ b/platform/ios/keyboard_input_view.h @@ -32,6 +32,6 @@ @interface GodotKeyboardInputView : UITextView -- (BOOL)becomeFirstResponderWithString:(NSString *)existingString multiline:(BOOL)flag cursorStart:(NSInteger)start cursorEnd:(NSInteger)end; +- (BOOL)becomeFirstResponderWithString:(NSString *)existingString cursorStart:(NSInteger)start cursorEnd:(NSInteger)end; @end diff --git a/platform/ios/keyboard_input_view.mm b/platform/ios/keyboard_input_view.mm index 76e3f23c9d..f031a1de22 100644 --- a/platform/ios/keyboard_input_view.mm +++ b/platform/ios/keyboard_input_view.mm @@ -84,7 +84,7 @@ return YES; } -- (BOOL)becomeFirstResponderWithString:(NSString *)existingString multiline:(BOOL)flag cursorStart:(NSInteger)start cursorEnd:(NSInteger)end { +- (BOOL)becomeFirstResponderWithString:(NSString *)existingString cursorStart:(NSInteger)start cursorEnd:(NSInteger)end { self.text = existingString; self.previousText = existingString; diff --git a/platform/ios/os_ios.h b/platform/ios/os_ios.h index cfd1771653..3b88f53b6a 100644 --- a/platform/ios/os_ios.h +++ b/platform/ios/os_ios.h @@ -92,6 +92,9 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; + virtual Vector<String> get_system_fonts() const override; + virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override; virtual Error close_dynamic_library(void *p_library_handle) override; virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override; diff --git a/platform/ios/os_ios.mm b/platform/ios/os_ios.mm index 880315209e..b9d186f355 100644 --- a/platform/ios/os_ios.mm +++ b/platform/ios/os_ios.mm @@ -44,6 +44,7 @@ #import "view_controller.h" #import <AudioToolbox/AudioServices.h> +#import <CoreText/CoreText.h> #import <UIKit/UIKit.h> #import <dlfcn.h> #include <sys/sysctl.h> @@ -302,6 +303,80 @@ String OS_IOS::get_processor_name() const { ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name. Returning an empty string.")); } +Vector<String> OS_IOS::get_system_fonts() const { + HashSet<String> font_names; + CFArrayRef fonts = CTFontManagerCopyAvailableFontFamilyNames(); + if (fonts) { + for (CFIndex i = 0; i < CFArrayGetCount(fonts); i++) { + CFStringRef cf_name = (CFStringRef)CFArrayGetValueAtIndex(fonts, i); + if (cf_name && (CFStringGetLength(cf_name) > 0) && (CFStringCompare(cf_name, CFSTR("LastResort"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && (CFStringGetCharacterAtIndex(cf_name, 0) != '.')) { + NSString *ns_name = (__bridge NSString *)cf_name; + font_names.insert(String::utf8([ns_name UTF8String])); + } + } + CFRelease(fonts); + } + + Vector<String> ret; + for (const String &E : font_names) { + ret.push_back(E); + } + return ret; +} + +String OS_IOS::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { + String ret; + + String font_name = p_font_name; + if (font_name.to_lower() == "sans-serif") { + font_name = "Helvetica"; + } else if (font_name.to_lower() == "serif") { + font_name = "Times"; + } else if (font_name.to_lower() == "monospace") { + font_name = "Courier"; + } else if (font_name.to_lower() == "fantasy") { + font_name = "Papyrus"; + } else if (font_name.to_lower() == "cursive") { + font_name = "Apple Chancery"; + }; + + CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8); + + CTFontSymbolicTraits traits = 0; + if (p_bold) { + traits |= kCTFontBoldTrait; + } + if (p_italic) { + traits |= kCTFontItalicTrait; + } + + CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits); + CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits); + + CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name); + CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict); + + CTFontDescriptorRef font = CTFontDescriptorCreateWithAttributes(attributes); + if (font) { + CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(font, kCTFontURLAttribute); + if (url) { + NSString *font_path = [NSString stringWithString:[(__bridge NSURL *)url path]]; + ret = String::utf8([font_path UTF8String]); + CFRelease(url); + } + CFRelease(font); + } + + CFRelease(attributes); + CFRelease(traits_dict); + CFRelease(sym_traits); + CFRelease(name); + + return ret; +} + void OS_IOS::vibrate_handheld(int p_duration_ms) { if (ios->supports_haptic_engine()) { ios->vibrate_haptic_engine((float)p_duration_ms / 1000.f); diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index 4edd6c793a..48f637fcfe 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -83,7 +83,7 @@ void DisplayServerJavaScript::drop_files_js_callback(char **p_filev, int p_filec Variant *vp = &v; Variant ret; Callable::CallError ce; - ds->drop_files_callback.call((const Variant **)&vp, 1, ret, ce); + ds->drop_files_callback.callp((const Variant **)&vp, 1, ret, ce); } // JavaScript quit request callback. @@ -94,7 +94,7 @@ void DisplayServerJavaScript::request_quit_callback() { Variant *eventp = &event; Variant ret; Callable::CallError ce; - ds->window_event_callback.call((const Variant **)&eventp, 1, ret, ce); + ds->window_event_callback.callp((const Variant **)&eventp, 1, ret, ce); } } @@ -586,7 +586,7 @@ void DisplayServerJavaScript::vk_input_text_callback(const char *p_text, int p_c Variant *eventp = &event; Variant ret; Callable::CallError ce; - ds->input_text_callback.call((const Variant **)&eventp, 1, ret, ce); + ds->input_text_callback.callp((const Variant **)&eventp, 1, ret, ce); // Insert key right to reach position. Input *input = Input::get_singleton(); Ref<InputEventKey> k; @@ -604,8 +604,8 @@ void DisplayServerJavaScript::vk_input_text_callback(const char *p_text, int p_c } } -void DisplayServerJavaScript::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { - godot_js_display_vk_show(p_existing_text.utf8().get_data(), p_multiline, p_cursor_start, p_cursor_end); +void DisplayServerJavaScript::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) { + godot_js_display_vk_show(p_existing_text.utf8().get_data(), p_type, p_cursor_start, p_cursor_end); } void DisplayServerJavaScript::virtual_keyboard_hide() { @@ -691,7 +691,7 @@ void DisplayServerJavaScript::send_window_event_callback(int p_notification) { Variant *eventp = &event; Variant ret; Callable::CallError ce; - ds->window_event_callback.call((const Variant **)&eventp, 1, ret, ce); + ds->window_event_callback.callp((const Variant **)&eventp, 1, ret, ce); } } @@ -734,7 +734,7 @@ void DisplayServerJavaScript::_dispatch_input_event(const Ref<InputEvent> &p_eve Variant *evp = &ev; Variant ret; Callable::CallError ce; - cb.call((const Variant **)&evp, 1, ret, ce); + cb.callp((const Variant **)&evp, 1, ret, ce); } } diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h index 79b0fbb652..fb7f5d02a8 100644 --- a/platform/javascript/display_server_javascript.h +++ b/platform/javascript/display_server_javascript.h @@ -157,7 +157,7 @@ public: virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override; + virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), VirtualKeyboardType p_type = KEYBOARD_TYPE_DEFAULT, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override; virtual void virtual_keyboard_hide() override; // windows diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 825c1b6638..ea236f62f7 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -30,6 +30,7 @@ #include "export.h" +#include "editor/editor_settings.h" #include "export_plugin.h" void register_javascript_exporter() { diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp index e2ae45627e..b99f88d067 100644 --- a/platform/javascript/export/export_plugin.cpp +++ b/platform/javascript/export/export_plugin.cpp @@ -31,6 +31,7 @@ #include "export_plugin.h" #include "core/config/project_settings.h" +#include "editor/editor_settings.h" Error EditorExportPlatformJavaScript::_extract_template(const String &p_template, const String &p_dir, const String &p_name, bool pwa) { Ref<FileAccess> io_fa; @@ -302,7 +303,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> & return OK; } -void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { +void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { if (p_preset->get("vram_texture_compression/for_desktop")) { r_features->push_back("s3tc"); } diff --git a/platform/javascript/export/export_plugin.h b/platform/javascript/export/export_plugin.h index a6df8e7094..fbaa3615cb 100644 --- a/platform/javascript/export/export_plugin.h +++ b/platform/javascript/export/export_plugin.h @@ -36,8 +36,8 @@ #include "core/io/stream_peer_ssl.h" #include "core/io/tcp_server.h" #include "core/io/zip_io.h" -#include "editor/editor_export.h" #include "editor/editor_node.h" +#include "editor/export/editor_export_platform.h" #include "main/splash.gen.h" #include "platform/javascript/logo.gen.h" #include "platform/javascript/run_icon.gen.h" @@ -110,7 +110,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform { static void _server_thread_poll(void *data); public: - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override; + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; virtual void get_export_options(List<ExportOption> *r_options) override; @@ -130,7 +130,7 @@ public: virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) override; virtual Ref<Texture2D> get_run_icon() const override; - virtual void get_platform_features(List<String> *r_features) override { + virtual void get_platform_features(List<String> *r_features) const override { r_features->push_back("web"); r_features->push_back(get_os_name().to_lower()); } diff --git a/platform/javascript/export/export_server.h b/platform/javascript/export/export_server.h index 7cdbcec064..ddbe3cca30 100644 --- a/platform/javascript/export/export_server.h +++ b/platform/javascript/export/export_server.h @@ -35,7 +35,6 @@ #include "core/io/stream_peer_ssl.h" #include "core/io/tcp_server.h" #include "core/io/zip_io.h" -#include "editor/editor_export.h" #include "editor/editor_paths.h" class EditorHTTPServer : public RefCounted { diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h index 567b491336..a323f2d157 100644 --- a/platform/javascript/godot_js.h +++ b/platform/javascript/godot_js.h @@ -58,6 +58,7 @@ extern void godot_js_input_mouse_move_cb(void (*p_callback)(double p_x, double p extern void godot_js_input_mouse_wheel_cb(int (*p_callback)(double p_delta_x, double p_delta_y)); extern void godot_js_input_touch_cb(void (*p_callback)(int p_type, int p_count), uint32_t *r_identifiers, double *r_coords); extern void godot_js_input_key_cb(void (*p_callback)(int p_type, int p_repeat, int p_modifiers), char r_code[32], char r_key[32]); +extern void godot_js_input_vibrate_handheld(int p_duration_ms); // Input gamepad extern void godot_js_input_gamepad_cb(void (*p_on_change)(int p_index, int p_connected, const char *p_id, const char *p_guid)); @@ -120,7 +121,7 @@ extern void godot_js_display_notification_cb(void (*p_callback)(int p_notificati extern int godot_js_display_vk_available(); extern int godot_js_display_tts_available(); extern void godot_js_display_vk_cb(void (*p_input)(const char *p_text, int p_cursor)); -extern void godot_js_display_vk_show(const char *p_text, int p_multiline, int p_start, int p_end); +extern void godot_js_display_vk_show(const char *p_text, int p_type, int p_start, int p_end); extern void godot_js_display_vk_hide(); #ifdef __cplusplus diff --git a/platform/javascript/javascript_singleton.cpp b/platform/javascript/javascript_singleton.cpp index 8dc7aba5f8..204e92b82b 100644 --- a/platform/javascript/javascript_singleton.cpp +++ b/platform/javascript/javascript_singleton.cpp @@ -259,7 +259,7 @@ void JavaScriptObjectImpl::_callback(void *p_ref, int p_args_id, int p_argc) { const Variant *argv[1] = { &arg }; Callable::CallError err; Variant ret; - obj->_callable.call(argv, 1, ret, err); + obj->_callable.callp(argv, 1, ret, err); // Set return value godot_js_wrapper_ex exchange; diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js index 5997631bf8..c7729a8c5b 100644 --- a/platform/javascript/js/libs/library_godot_display.js +++ b/platform/javascript/js/libs/library_godot_display.js @@ -73,7 +73,7 @@ const GodotDisplayVK = { GodotDisplayVK.textarea = create('textarea'); GodotDisplayVK.updateSize(); }, - show: function (text, multiline, start, end) { + show: function (text, type, start, end) { if (!GodotDisplayVK.textinput || !GodotDisplayVK.textarea) { return; } @@ -81,7 +81,46 @@ const GodotDisplayVK = { GodotDisplayVK.hide(); } GodotDisplayVK.updateSize(); - const elem = multiline ? GodotDisplayVK.textarea : GodotDisplayVK.textinput; + + let elem = GodotDisplayVK.textinput; + switch (type) { + case 0: // KEYBOARD_TYPE_DEFAULT + elem.type = 'text'; + elem.inputmode = ''; + break; + case 1: // KEYBOARD_TYPE_MULTILINE + elem = GodotDisplayVK.textarea; + break; + case 2: // KEYBOARD_TYPE_NUMBER + elem.type = 'text'; + elem.inputmode = 'numeric'; + break; + case 3: // KEYBOARD_TYPE_NUMBER_DECIMAL + elem.type = 'text'; + elem.inputmode = 'decimal'; + break; + case 4: // KEYBOARD_TYPE_PHONE + elem.type = 'tel'; + elem.inputmode = ''; + break; + case 5: // KEYBOARD_TYPE_EMAIL_ADDRESS + elem.type = 'email'; + elem.inputmode = ''; + break; + case 6: // KEYBOARD_TYPE_PASSWORD + elem.type = 'password'; + elem.inputmode = ''; + break; + case 7: // KEYBOARD_TYPE_URL + elem.type = 'url'; + elem.inputmode = ''; + break; + default: + elem.type = 'text'; + elem.inputmode = ''; + break; + } + elem.readonly = false; elem.disabled = false; elem.value = text; @@ -694,11 +733,11 @@ const GodotDisplay = { * Virtual Keyboard */ godot_js_display_vk_show__sig: 'viiii', - godot_js_display_vk_show: function (p_text, p_multiline, p_start, p_end) { + godot_js_display_vk_show: function (p_text, p_type, p_start, p_end) { const text = GodotRuntime.parseString(p_text); const start = p_start > 0 ? p_start : 0; const end = p_end > 0 ? p_end : start; - GodotDisplayVK.show(text, p_multiline, start, end); + GodotDisplayVK.show(text, p_type, start, end); }, godot_js_display_vk_hide__sig: 'v', diff --git a/platform/javascript/js/libs/library_godot_input.js b/platform/javascript/js/libs/library_godot_input.js index 1e64c260f8..51571d64a2 100644 --- a/platform/javascript/js/libs/library_godot_input.js +++ b/platform/javascript/js/libs/library_godot_input.js @@ -534,6 +534,15 @@ const GodotInput = { GodotRuntime.free(ptr); }, false); }, + + godot_js_input_vibrate_handheld__sig: 'vi', + godot_js_input_vibrate_handheld: function (p_duration_ms) { + if (typeof navigator.vibrate !== 'function') { + GodotRuntime.print('This browser does not support vibration.'); + } else { + navigator.vibrate(p_duration_ms); + } + }, }; autoAddDeps(GodotInput, '$GodotInput'); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 1686353229..dc81b8b4b6 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -177,6 +177,10 @@ String OS_JavaScript::get_name() const { return "HTML5"; } +void OS_JavaScript::vibrate_handheld(int p_duration_ms) { + godot_js_input_vibrate_handheld(p_duration_ms); +} + String OS_JavaScript::get_user_data_dir() const { return "/userfs"; } diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 6900a34ee3..35e13c94fc 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -90,6 +90,8 @@ public: // Implemented in javascript_main.cpp loop callback instead. void add_frame_delay(bool p_can_draw) override {} + void vibrate_handheld(int p_duration_ms) override; + String get_cache_path() const override; String get_config_path() const override; String get_data_path() const override; diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub index 636a3c7db2..35c41556ee 100644 --- a/platform/linuxbsd/SCsub +++ b/platform/linuxbsd/SCsub @@ -26,9 +26,15 @@ if env["x11"]: if env["speechd"]: common_linuxbsd.append(["speechd-so_wrap.c", "tts_linux.cpp"]) +if env["fontconfig"]: + common_linuxbsd.append("fontconfig-so_wrap.c") + if env["udev"]: common_linuxbsd.append("libudev-so_wrap.c") +if env["dbus"]: + common_linuxbsd.append("dbus-so_wrap.c") + prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_linuxbsd) if env["debug_symbols"] and env["separate_debug_symbols"]: diff --git a/platform/linuxbsd/dbus-so_wrap.c b/platform/linuxbsd/dbus-so_wrap.c new file mode 100644 index 0000000000..0876bc88b0 --- /dev/null +++ b/platform/linuxbsd/dbus-so_wrap.c @@ -0,0 +1,2641 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by ./generate-wrapper.py 0.3 on 2022-07-29 07:23:21 +// flags: ./generate-wrapper.py --include /usr/include/dbus-1.0/dbus/dbus.h --sys-include <dbus/dbus.h> --soname libdbus-1.so --init-name dbus --output-header dbus-so_wrap.h --output-implementation dbus-so_wrap.c +// +#include <stdint.h> + +#define dbus_error_init dbus_error_init_dylibloader_orig_dbus +#define dbus_error_free dbus_error_free_dylibloader_orig_dbus +#define dbus_set_error dbus_set_error_dylibloader_orig_dbus +#define dbus_set_error_const dbus_set_error_const_dylibloader_orig_dbus +#define dbus_move_error dbus_move_error_dylibloader_orig_dbus +#define dbus_error_has_name dbus_error_has_name_dylibloader_orig_dbus +#define dbus_error_is_set dbus_error_is_set_dylibloader_orig_dbus +#define dbus_parse_address dbus_parse_address_dylibloader_orig_dbus +#define dbus_address_entry_get_value dbus_address_entry_get_value_dylibloader_orig_dbus +#define dbus_address_entry_get_method dbus_address_entry_get_method_dylibloader_orig_dbus +#define dbus_address_entries_free dbus_address_entries_free_dylibloader_orig_dbus +#define dbus_address_escape_value dbus_address_escape_value_dylibloader_orig_dbus +#define dbus_address_unescape_value dbus_address_unescape_value_dylibloader_orig_dbus +#define dbus_malloc dbus_malloc_dylibloader_orig_dbus +#define dbus_malloc0 dbus_malloc0_dylibloader_orig_dbus +#define dbus_realloc dbus_realloc_dylibloader_orig_dbus +#define dbus_free dbus_free_dylibloader_orig_dbus +#define dbus_free_string_array dbus_free_string_array_dylibloader_orig_dbus +#define dbus_shutdown dbus_shutdown_dylibloader_orig_dbus +#define dbus_message_new dbus_message_new_dylibloader_orig_dbus +#define dbus_message_new_method_call dbus_message_new_method_call_dylibloader_orig_dbus +#define dbus_message_new_method_return dbus_message_new_method_return_dylibloader_orig_dbus +#define dbus_message_new_signal dbus_message_new_signal_dylibloader_orig_dbus +#define dbus_message_new_error dbus_message_new_error_dylibloader_orig_dbus +#define dbus_message_new_error_printf dbus_message_new_error_printf_dylibloader_orig_dbus +#define dbus_message_copy dbus_message_copy_dylibloader_orig_dbus +#define dbus_message_ref dbus_message_ref_dylibloader_orig_dbus +#define dbus_message_unref dbus_message_unref_dylibloader_orig_dbus +#define dbus_message_get_type dbus_message_get_type_dylibloader_orig_dbus +#define dbus_message_set_path dbus_message_set_path_dylibloader_orig_dbus +#define dbus_message_get_path dbus_message_get_path_dylibloader_orig_dbus +#define dbus_message_has_path dbus_message_has_path_dylibloader_orig_dbus +#define dbus_message_set_interface dbus_message_set_interface_dylibloader_orig_dbus +#define dbus_message_get_interface dbus_message_get_interface_dylibloader_orig_dbus +#define dbus_message_has_interface dbus_message_has_interface_dylibloader_orig_dbus +#define dbus_message_set_member dbus_message_set_member_dylibloader_orig_dbus +#define dbus_message_get_member dbus_message_get_member_dylibloader_orig_dbus +#define dbus_message_has_member dbus_message_has_member_dylibloader_orig_dbus +#define dbus_message_set_error_name dbus_message_set_error_name_dylibloader_orig_dbus +#define dbus_message_get_error_name dbus_message_get_error_name_dylibloader_orig_dbus +#define dbus_message_set_destination dbus_message_set_destination_dylibloader_orig_dbus +#define dbus_message_get_destination dbus_message_get_destination_dylibloader_orig_dbus +#define dbus_message_set_sender dbus_message_set_sender_dylibloader_orig_dbus +#define dbus_message_get_sender dbus_message_get_sender_dylibloader_orig_dbus +#define dbus_message_get_signature dbus_message_get_signature_dylibloader_orig_dbus +#define dbus_message_set_no_reply dbus_message_set_no_reply_dylibloader_orig_dbus +#define dbus_message_get_no_reply dbus_message_get_no_reply_dylibloader_orig_dbus +#define dbus_message_is_method_call dbus_message_is_method_call_dylibloader_orig_dbus +#define dbus_message_is_signal dbus_message_is_signal_dylibloader_orig_dbus +#define dbus_message_is_error dbus_message_is_error_dylibloader_orig_dbus +#define dbus_message_has_destination dbus_message_has_destination_dylibloader_orig_dbus +#define dbus_message_has_sender dbus_message_has_sender_dylibloader_orig_dbus +#define dbus_message_has_signature dbus_message_has_signature_dylibloader_orig_dbus +#define dbus_message_get_serial dbus_message_get_serial_dylibloader_orig_dbus +#define dbus_message_set_serial dbus_message_set_serial_dylibloader_orig_dbus +#define dbus_message_set_reply_serial dbus_message_set_reply_serial_dylibloader_orig_dbus +#define dbus_message_get_reply_serial dbus_message_get_reply_serial_dylibloader_orig_dbus +#define dbus_message_set_auto_start dbus_message_set_auto_start_dylibloader_orig_dbus +#define dbus_message_get_auto_start dbus_message_get_auto_start_dylibloader_orig_dbus +#define dbus_message_get_path_decomposed dbus_message_get_path_decomposed_dylibloader_orig_dbus +#define dbus_message_append_args dbus_message_append_args_dylibloader_orig_dbus +#define dbus_message_append_args_valist dbus_message_append_args_valist_dylibloader_orig_dbus +#define dbus_message_get_args dbus_message_get_args_dylibloader_orig_dbus +#define dbus_message_get_args_valist dbus_message_get_args_valist_dylibloader_orig_dbus +#define dbus_message_contains_unix_fds dbus_message_contains_unix_fds_dylibloader_orig_dbus +#define dbus_message_iter_init_closed dbus_message_iter_init_closed_dylibloader_orig_dbus +#define dbus_message_iter_init dbus_message_iter_init_dylibloader_orig_dbus +#define dbus_message_iter_has_next dbus_message_iter_has_next_dylibloader_orig_dbus +#define dbus_message_iter_next dbus_message_iter_next_dylibloader_orig_dbus +#define dbus_message_iter_get_signature dbus_message_iter_get_signature_dylibloader_orig_dbus +#define dbus_message_iter_get_arg_type dbus_message_iter_get_arg_type_dylibloader_orig_dbus +#define dbus_message_iter_get_element_type dbus_message_iter_get_element_type_dylibloader_orig_dbus +#define dbus_message_iter_recurse dbus_message_iter_recurse_dylibloader_orig_dbus +#define dbus_message_iter_get_basic dbus_message_iter_get_basic_dylibloader_orig_dbus +#define dbus_message_iter_get_element_count dbus_message_iter_get_element_count_dylibloader_orig_dbus +#define dbus_message_iter_get_array_len dbus_message_iter_get_array_len_dylibloader_orig_dbus +#define dbus_message_iter_get_fixed_array dbus_message_iter_get_fixed_array_dylibloader_orig_dbus +#define dbus_message_iter_init_append dbus_message_iter_init_append_dylibloader_orig_dbus +#define dbus_message_iter_append_basic dbus_message_iter_append_basic_dylibloader_orig_dbus +#define dbus_message_iter_append_fixed_array dbus_message_iter_append_fixed_array_dylibloader_orig_dbus +#define dbus_message_iter_open_container dbus_message_iter_open_container_dylibloader_orig_dbus +#define dbus_message_iter_close_container dbus_message_iter_close_container_dylibloader_orig_dbus +#define dbus_message_iter_abandon_container dbus_message_iter_abandon_container_dylibloader_orig_dbus +#define dbus_message_iter_abandon_container_if_open dbus_message_iter_abandon_container_if_open_dylibloader_orig_dbus +#define dbus_message_lock dbus_message_lock_dylibloader_orig_dbus +#define dbus_set_error_from_message dbus_set_error_from_message_dylibloader_orig_dbus +#define dbus_message_allocate_data_slot dbus_message_allocate_data_slot_dylibloader_orig_dbus +#define dbus_message_free_data_slot dbus_message_free_data_slot_dylibloader_orig_dbus +#define dbus_message_set_data dbus_message_set_data_dylibloader_orig_dbus +#define dbus_message_get_data dbus_message_get_data_dylibloader_orig_dbus +#define dbus_message_type_from_string dbus_message_type_from_string_dylibloader_orig_dbus +#define dbus_message_type_to_string dbus_message_type_to_string_dylibloader_orig_dbus +#define dbus_message_marshal dbus_message_marshal_dylibloader_orig_dbus +#define dbus_message_demarshal dbus_message_demarshal_dylibloader_orig_dbus +#define dbus_message_demarshal_bytes_needed dbus_message_demarshal_bytes_needed_dylibloader_orig_dbus +#define dbus_message_set_allow_interactive_authorization dbus_message_set_allow_interactive_authorization_dylibloader_orig_dbus +#define dbus_message_get_allow_interactive_authorization dbus_message_get_allow_interactive_authorization_dylibloader_orig_dbus +#define dbus_connection_open dbus_connection_open_dylibloader_orig_dbus +#define dbus_connection_open_private dbus_connection_open_private_dylibloader_orig_dbus +#define dbus_connection_ref dbus_connection_ref_dylibloader_orig_dbus +#define dbus_connection_unref dbus_connection_unref_dylibloader_orig_dbus +#define dbus_connection_close dbus_connection_close_dylibloader_orig_dbus +#define dbus_connection_get_is_connected dbus_connection_get_is_connected_dylibloader_orig_dbus +#define dbus_connection_get_is_authenticated dbus_connection_get_is_authenticated_dylibloader_orig_dbus +#define dbus_connection_get_is_anonymous dbus_connection_get_is_anonymous_dylibloader_orig_dbus +#define dbus_connection_get_server_id dbus_connection_get_server_id_dylibloader_orig_dbus +#define dbus_connection_can_send_type dbus_connection_can_send_type_dylibloader_orig_dbus +#define dbus_connection_set_exit_on_disconnect dbus_connection_set_exit_on_disconnect_dylibloader_orig_dbus +#define dbus_connection_flush dbus_connection_flush_dylibloader_orig_dbus +#define dbus_connection_read_write_dispatch dbus_connection_read_write_dispatch_dylibloader_orig_dbus +#define dbus_connection_read_write dbus_connection_read_write_dylibloader_orig_dbus +#define dbus_connection_borrow_message dbus_connection_borrow_message_dylibloader_orig_dbus +#define dbus_connection_return_message dbus_connection_return_message_dylibloader_orig_dbus +#define dbus_connection_steal_borrowed_message dbus_connection_steal_borrowed_message_dylibloader_orig_dbus +#define dbus_connection_pop_message dbus_connection_pop_message_dylibloader_orig_dbus +#define dbus_connection_get_dispatch_status dbus_connection_get_dispatch_status_dylibloader_orig_dbus +#define dbus_connection_dispatch dbus_connection_dispatch_dylibloader_orig_dbus +#define dbus_connection_has_messages_to_send dbus_connection_has_messages_to_send_dylibloader_orig_dbus +#define dbus_connection_send dbus_connection_send_dylibloader_orig_dbus +#define dbus_connection_send_with_reply dbus_connection_send_with_reply_dylibloader_orig_dbus +#define dbus_connection_send_with_reply_and_block dbus_connection_send_with_reply_and_block_dylibloader_orig_dbus +#define dbus_connection_set_watch_functions dbus_connection_set_watch_functions_dylibloader_orig_dbus +#define dbus_connection_set_timeout_functions dbus_connection_set_timeout_functions_dylibloader_orig_dbus +#define dbus_connection_set_wakeup_main_function dbus_connection_set_wakeup_main_function_dylibloader_orig_dbus +#define dbus_connection_set_dispatch_status_function dbus_connection_set_dispatch_status_function_dylibloader_orig_dbus +#define dbus_connection_get_unix_user dbus_connection_get_unix_user_dylibloader_orig_dbus +#define dbus_connection_get_unix_process_id dbus_connection_get_unix_process_id_dylibloader_orig_dbus +#define dbus_connection_get_adt_audit_session_data dbus_connection_get_adt_audit_session_data_dylibloader_orig_dbus +#define dbus_connection_set_unix_user_function dbus_connection_set_unix_user_function_dylibloader_orig_dbus +#define dbus_connection_get_windows_user dbus_connection_get_windows_user_dylibloader_orig_dbus +#define dbus_connection_set_windows_user_function dbus_connection_set_windows_user_function_dylibloader_orig_dbus +#define dbus_connection_set_allow_anonymous dbus_connection_set_allow_anonymous_dylibloader_orig_dbus +#define dbus_connection_set_route_peer_messages dbus_connection_set_route_peer_messages_dylibloader_orig_dbus +#define dbus_connection_add_filter dbus_connection_add_filter_dylibloader_orig_dbus +#define dbus_connection_remove_filter dbus_connection_remove_filter_dylibloader_orig_dbus +#define dbus_connection_allocate_data_slot dbus_connection_allocate_data_slot_dylibloader_orig_dbus +#define dbus_connection_free_data_slot dbus_connection_free_data_slot_dylibloader_orig_dbus +#define dbus_connection_set_data dbus_connection_set_data_dylibloader_orig_dbus +#define dbus_connection_get_data dbus_connection_get_data_dylibloader_orig_dbus +#define dbus_connection_set_change_sigpipe dbus_connection_set_change_sigpipe_dylibloader_orig_dbus +#define dbus_connection_set_max_message_size dbus_connection_set_max_message_size_dylibloader_orig_dbus +#define dbus_connection_get_max_message_size dbus_connection_get_max_message_size_dylibloader_orig_dbus +#define dbus_connection_set_max_received_size dbus_connection_set_max_received_size_dylibloader_orig_dbus +#define dbus_connection_get_max_received_size dbus_connection_get_max_received_size_dylibloader_orig_dbus +#define dbus_connection_set_max_message_unix_fds dbus_connection_set_max_message_unix_fds_dylibloader_orig_dbus +#define dbus_connection_get_max_message_unix_fds dbus_connection_get_max_message_unix_fds_dylibloader_orig_dbus +#define dbus_connection_set_max_received_unix_fds dbus_connection_set_max_received_unix_fds_dylibloader_orig_dbus +#define dbus_connection_get_max_received_unix_fds dbus_connection_get_max_received_unix_fds_dylibloader_orig_dbus +#define dbus_connection_get_outgoing_size dbus_connection_get_outgoing_size_dylibloader_orig_dbus +#define dbus_connection_get_outgoing_unix_fds dbus_connection_get_outgoing_unix_fds_dylibloader_orig_dbus +#define dbus_connection_preallocate_send dbus_connection_preallocate_send_dylibloader_orig_dbus +#define dbus_connection_free_preallocated_send dbus_connection_free_preallocated_send_dylibloader_orig_dbus +#define dbus_connection_send_preallocated dbus_connection_send_preallocated_dylibloader_orig_dbus +#define dbus_connection_try_register_object_path dbus_connection_try_register_object_path_dylibloader_orig_dbus +#define dbus_connection_register_object_path dbus_connection_register_object_path_dylibloader_orig_dbus +#define dbus_connection_try_register_fallback dbus_connection_try_register_fallback_dylibloader_orig_dbus +#define dbus_connection_register_fallback dbus_connection_register_fallback_dylibloader_orig_dbus +#define dbus_connection_unregister_object_path dbus_connection_unregister_object_path_dylibloader_orig_dbus +#define dbus_connection_get_object_path_data dbus_connection_get_object_path_data_dylibloader_orig_dbus +#define dbus_connection_list_registered dbus_connection_list_registered_dylibloader_orig_dbus +#define dbus_connection_get_unix_fd dbus_connection_get_unix_fd_dylibloader_orig_dbus +#define dbus_connection_get_socket dbus_connection_get_socket_dylibloader_orig_dbus +#define dbus_watch_get_fd dbus_watch_get_fd_dylibloader_orig_dbus +#define dbus_watch_get_unix_fd dbus_watch_get_unix_fd_dylibloader_orig_dbus +#define dbus_watch_get_socket dbus_watch_get_socket_dylibloader_orig_dbus +#define dbus_watch_get_flags dbus_watch_get_flags_dylibloader_orig_dbus +#define dbus_watch_get_data dbus_watch_get_data_dylibloader_orig_dbus +#define dbus_watch_set_data dbus_watch_set_data_dylibloader_orig_dbus +#define dbus_watch_handle dbus_watch_handle_dylibloader_orig_dbus +#define dbus_watch_get_enabled dbus_watch_get_enabled_dylibloader_orig_dbus +#define dbus_timeout_get_interval dbus_timeout_get_interval_dylibloader_orig_dbus +#define dbus_timeout_get_data dbus_timeout_get_data_dylibloader_orig_dbus +#define dbus_timeout_set_data dbus_timeout_set_data_dylibloader_orig_dbus +#define dbus_timeout_handle dbus_timeout_handle_dylibloader_orig_dbus +#define dbus_timeout_get_enabled dbus_timeout_get_enabled_dylibloader_orig_dbus +#define dbus_bus_get dbus_bus_get_dylibloader_orig_dbus +#define dbus_bus_get_private dbus_bus_get_private_dylibloader_orig_dbus +#define dbus_bus_register dbus_bus_register_dylibloader_orig_dbus +#define dbus_bus_set_unique_name dbus_bus_set_unique_name_dylibloader_orig_dbus +#define dbus_bus_get_unique_name dbus_bus_get_unique_name_dylibloader_orig_dbus +#define dbus_bus_get_unix_user dbus_bus_get_unix_user_dylibloader_orig_dbus +#define dbus_bus_get_id dbus_bus_get_id_dylibloader_orig_dbus +#define dbus_bus_request_name dbus_bus_request_name_dylibloader_orig_dbus +#define dbus_bus_release_name dbus_bus_release_name_dylibloader_orig_dbus +#define dbus_bus_name_has_owner dbus_bus_name_has_owner_dylibloader_orig_dbus +#define dbus_bus_start_service_by_name dbus_bus_start_service_by_name_dylibloader_orig_dbus +#define dbus_bus_add_match dbus_bus_add_match_dylibloader_orig_dbus +#define dbus_bus_remove_match dbus_bus_remove_match_dylibloader_orig_dbus +#define dbus_get_local_machine_id dbus_get_local_machine_id_dylibloader_orig_dbus +#define dbus_get_version dbus_get_version_dylibloader_orig_dbus +#define dbus_setenv dbus_setenv_dylibloader_orig_dbus +#define dbus_try_get_local_machine_id dbus_try_get_local_machine_id_dylibloader_orig_dbus +#define dbus_pending_call_ref dbus_pending_call_ref_dylibloader_orig_dbus +#define dbus_pending_call_unref dbus_pending_call_unref_dylibloader_orig_dbus +#define dbus_pending_call_set_notify dbus_pending_call_set_notify_dylibloader_orig_dbus +#define dbus_pending_call_cancel dbus_pending_call_cancel_dylibloader_orig_dbus +#define dbus_pending_call_get_completed dbus_pending_call_get_completed_dylibloader_orig_dbus +#define dbus_pending_call_steal_reply dbus_pending_call_steal_reply_dylibloader_orig_dbus +#define dbus_pending_call_block dbus_pending_call_block_dylibloader_orig_dbus +#define dbus_pending_call_allocate_data_slot dbus_pending_call_allocate_data_slot_dylibloader_orig_dbus +#define dbus_pending_call_free_data_slot dbus_pending_call_free_data_slot_dylibloader_orig_dbus +#define dbus_pending_call_set_data dbus_pending_call_set_data_dylibloader_orig_dbus +#define dbus_pending_call_get_data dbus_pending_call_get_data_dylibloader_orig_dbus +#define dbus_server_listen dbus_server_listen_dylibloader_orig_dbus +#define dbus_server_ref dbus_server_ref_dylibloader_orig_dbus +#define dbus_server_unref dbus_server_unref_dylibloader_orig_dbus +#define dbus_server_disconnect dbus_server_disconnect_dylibloader_orig_dbus +#define dbus_server_get_is_connected dbus_server_get_is_connected_dylibloader_orig_dbus +#define dbus_server_get_address dbus_server_get_address_dylibloader_orig_dbus +#define dbus_server_get_id dbus_server_get_id_dylibloader_orig_dbus +#define dbus_server_set_new_connection_function dbus_server_set_new_connection_function_dylibloader_orig_dbus +#define dbus_server_set_watch_functions dbus_server_set_watch_functions_dylibloader_orig_dbus +#define dbus_server_set_timeout_functions dbus_server_set_timeout_functions_dylibloader_orig_dbus +#define dbus_server_set_auth_mechanisms dbus_server_set_auth_mechanisms_dylibloader_orig_dbus +#define dbus_server_allocate_data_slot dbus_server_allocate_data_slot_dylibloader_orig_dbus +#define dbus_server_free_data_slot dbus_server_free_data_slot_dylibloader_orig_dbus +#define dbus_server_set_data dbus_server_set_data_dylibloader_orig_dbus +#define dbus_server_get_data dbus_server_get_data_dylibloader_orig_dbus +#define dbus_signature_iter_init dbus_signature_iter_init_dylibloader_orig_dbus +#define dbus_signature_iter_get_current_type dbus_signature_iter_get_current_type_dylibloader_orig_dbus +#define dbus_signature_iter_get_signature dbus_signature_iter_get_signature_dylibloader_orig_dbus +#define dbus_signature_iter_get_element_type dbus_signature_iter_get_element_type_dylibloader_orig_dbus +#define dbus_signature_iter_next dbus_signature_iter_next_dylibloader_orig_dbus +#define dbus_signature_iter_recurse dbus_signature_iter_recurse_dylibloader_orig_dbus +#define dbus_signature_validate dbus_signature_validate_dylibloader_orig_dbus +#define dbus_signature_validate_single dbus_signature_validate_single_dylibloader_orig_dbus +#define dbus_type_is_valid dbus_type_is_valid_dylibloader_orig_dbus +#define dbus_type_is_basic dbus_type_is_basic_dylibloader_orig_dbus +#define dbus_type_is_container dbus_type_is_container_dylibloader_orig_dbus +#define dbus_type_is_fixed dbus_type_is_fixed_dylibloader_orig_dbus +#define dbus_validate_path dbus_validate_path_dylibloader_orig_dbus +#define dbus_validate_interface dbus_validate_interface_dylibloader_orig_dbus +#define dbus_validate_member dbus_validate_member_dylibloader_orig_dbus +#define dbus_validate_error_name dbus_validate_error_name_dylibloader_orig_dbus +#define dbus_validate_bus_name dbus_validate_bus_name_dylibloader_orig_dbus +#define dbus_validate_utf8 dbus_validate_utf8_dylibloader_orig_dbus +#define dbus_threads_init dbus_threads_init_dylibloader_orig_dbus +#define dbus_threads_init_default dbus_threads_init_default_dylibloader_orig_dbus +#include <dbus/dbus.h> +#undef dbus_error_init +#undef dbus_error_free +#undef dbus_set_error +#undef dbus_set_error_const +#undef dbus_move_error +#undef dbus_error_has_name +#undef dbus_error_is_set +#undef dbus_parse_address +#undef dbus_address_entry_get_value +#undef dbus_address_entry_get_method +#undef dbus_address_entries_free +#undef dbus_address_escape_value +#undef dbus_address_unescape_value +#undef dbus_malloc +#undef dbus_malloc0 +#undef dbus_realloc +#undef dbus_free +#undef dbus_free_string_array +#undef dbus_shutdown +#undef dbus_message_new +#undef dbus_message_new_method_call +#undef dbus_message_new_method_return +#undef dbus_message_new_signal +#undef dbus_message_new_error +#undef dbus_message_new_error_printf +#undef dbus_message_copy +#undef dbus_message_ref +#undef dbus_message_unref +#undef dbus_message_get_type +#undef dbus_message_set_path +#undef dbus_message_get_path +#undef dbus_message_has_path +#undef dbus_message_set_interface +#undef dbus_message_get_interface +#undef dbus_message_has_interface +#undef dbus_message_set_member +#undef dbus_message_get_member +#undef dbus_message_has_member +#undef dbus_message_set_error_name +#undef dbus_message_get_error_name +#undef dbus_message_set_destination +#undef dbus_message_get_destination +#undef dbus_message_set_sender +#undef dbus_message_get_sender +#undef dbus_message_get_signature +#undef dbus_message_set_no_reply +#undef dbus_message_get_no_reply +#undef dbus_message_is_method_call +#undef dbus_message_is_signal +#undef dbus_message_is_error +#undef dbus_message_has_destination +#undef dbus_message_has_sender +#undef dbus_message_has_signature +#undef dbus_message_get_serial +#undef dbus_message_set_serial +#undef dbus_message_set_reply_serial +#undef dbus_message_get_reply_serial +#undef dbus_message_set_auto_start +#undef dbus_message_get_auto_start +#undef dbus_message_get_path_decomposed +#undef dbus_message_append_args +#undef dbus_message_append_args_valist +#undef dbus_message_get_args +#undef dbus_message_get_args_valist +#undef dbus_message_contains_unix_fds +#undef dbus_message_iter_init_closed +#undef dbus_message_iter_init +#undef dbus_message_iter_has_next +#undef dbus_message_iter_next +#undef dbus_message_iter_get_signature +#undef dbus_message_iter_get_arg_type +#undef dbus_message_iter_get_element_type +#undef dbus_message_iter_recurse +#undef dbus_message_iter_get_basic +#undef dbus_message_iter_get_element_count +#undef dbus_message_iter_get_array_len +#undef dbus_message_iter_get_fixed_array +#undef dbus_message_iter_init_append +#undef dbus_message_iter_append_basic +#undef dbus_message_iter_append_fixed_array +#undef dbus_message_iter_open_container +#undef dbus_message_iter_close_container +#undef dbus_message_iter_abandon_container +#undef dbus_message_iter_abandon_container_if_open +#undef dbus_message_lock +#undef dbus_set_error_from_message +#undef dbus_message_allocate_data_slot +#undef dbus_message_free_data_slot +#undef dbus_message_set_data +#undef dbus_message_get_data +#undef dbus_message_type_from_string +#undef dbus_message_type_to_string +#undef dbus_message_marshal +#undef dbus_message_demarshal +#undef dbus_message_demarshal_bytes_needed +#undef dbus_message_set_allow_interactive_authorization +#undef dbus_message_get_allow_interactive_authorization +#undef dbus_connection_open +#undef dbus_connection_open_private +#undef dbus_connection_ref +#undef dbus_connection_unref +#undef dbus_connection_close +#undef dbus_connection_get_is_connected +#undef dbus_connection_get_is_authenticated +#undef dbus_connection_get_is_anonymous +#undef dbus_connection_get_server_id +#undef dbus_connection_can_send_type +#undef dbus_connection_set_exit_on_disconnect +#undef dbus_connection_flush +#undef dbus_connection_read_write_dispatch +#undef dbus_connection_read_write +#undef dbus_connection_borrow_message +#undef dbus_connection_return_message +#undef dbus_connection_steal_borrowed_message +#undef dbus_connection_pop_message +#undef dbus_connection_get_dispatch_status +#undef dbus_connection_dispatch +#undef dbus_connection_has_messages_to_send +#undef dbus_connection_send +#undef dbus_connection_send_with_reply +#undef dbus_connection_send_with_reply_and_block +#undef dbus_connection_set_watch_functions +#undef dbus_connection_set_timeout_functions +#undef dbus_connection_set_wakeup_main_function +#undef dbus_connection_set_dispatch_status_function +#undef dbus_connection_get_unix_user +#undef dbus_connection_get_unix_process_id +#undef dbus_connection_get_adt_audit_session_data +#undef dbus_connection_set_unix_user_function +#undef dbus_connection_get_windows_user +#undef dbus_connection_set_windows_user_function +#undef dbus_connection_set_allow_anonymous +#undef dbus_connection_set_route_peer_messages +#undef dbus_connection_add_filter +#undef dbus_connection_remove_filter +#undef dbus_connection_allocate_data_slot +#undef dbus_connection_free_data_slot +#undef dbus_connection_set_data +#undef dbus_connection_get_data +#undef dbus_connection_set_change_sigpipe +#undef dbus_connection_set_max_message_size +#undef dbus_connection_get_max_message_size +#undef dbus_connection_set_max_received_size +#undef dbus_connection_get_max_received_size +#undef dbus_connection_set_max_message_unix_fds +#undef dbus_connection_get_max_message_unix_fds +#undef dbus_connection_set_max_received_unix_fds +#undef dbus_connection_get_max_received_unix_fds +#undef dbus_connection_get_outgoing_size +#undef dbus_connection_get_outgoing_unix_fds +#undef dbus_connection_preallocate_send +#undef dbus_connection_free_preallocated_send +#undef dbus_connection_send_preallocated +#undef dbus_connection_try_register_object_path +#undef dbus_connection_register_object_path +#undef dbus_connection_try_register_fallback +#undef dbus_connection_register_fallback +#undef dbus_connection_unregister_object_path +#undef dbus_connection_get_object_path_data +#undef dbus_connection_list_registered +#undef dbus_connection_get_unix_fd +#undef dbus_connection_get_socket +#undef dbus_watch_get_fd +#undef dbus_watch_get_unix_fd +#undef dbus_watch_get_socket +#undef dbus_watch_get_flags +#undef dbus_watch_get_data +#undef dbus_watch_set_data +#undef dbus_watch_handle +#undef dbus_watch_get_enabled +#undef dbus_timeout_get_interval +#undef dbus_timeout_get_data +#undef dbus_timeout_set_data +#undef dbus_timeout_handle +#undef dbus_timeout_get_enabled +#undef dbus_bus_get +#undef dbus_bus_get_private +#undef dbus_bus_register +#undef dbus_bus_set_unique_name +#undef dbus_bus_get_unique_name +#undef dbus_bus_get_unix_user +#undef dbus_bus_get_id +#undef dbus_bus_request_name +#undef dbus_bus_release_name +#undef dbus_bus_name_has_owner +#undef dbus_bus_start_service_by_name +#undef dbus_bus_add_match +#undef dbus_bus_remove_match +#undef dbus_get_local_machine_id +#undef dbus_get_version +#undef dbus_setenv +#undef dbus_try_get_local_machine_id +#undef dbus_pending_call_ref +#undef dbus_pending_call_unref +#undef dbus_pending_call_set_notify +#undef dbus_pending_call_cancel +#undef dbus_pending_call_get_completed +#undef dbus_pending_call_steal_reply +#undef dbus_pending_call_block +#undef dbus_pending_call_allocate_data_slot +#undef dbus_pending_call_free_data_slot +#undef dbus_pending_call_set_data +#undef dbus_pending_call_get_data +#undef dbus_server_listen +#undef dbus_server_ref +#undef dbus_server_unref +#undef dbus_server_disconnect +#undef dbus_server_get_is_connected +#undef dbus_server_get_address +#undef dbus_server_get_id +#undef dbus_server_set_new_connection_function +#undef dbus_server_set_watch_functions +#undef dbus_server_set_timeout_functions +#undef dbus_server_set_auth_mechanisms +#undef dbus_server_allocate_data_slot +#undef dbus_server_free_data_slot +#undef dbus_server_set_data +#undef dbus_server_get_data +#undef dbus_signature_iter_init +#undef dbus_signature_iter_get_current_type +#undef dbus_signature_iter_get_signature +#undef dbus_signature_iter_get_element_type +#undef dbus_signature_iter_next +#undef dbus_signature_iter_recurse +#undef dbus_signature_validate +#undef dbus_signature_validate_single +#undef dbus_type_is_valid +#undef dbus_type_is_basic +#undef dbus_type_is_container +#undef dbus_type_is_fixed +#undef dbus_validate_path +#undef dbus_validate_interface +#undef dbus_validate_member +#undef dbus_validate_error_name +#undef dbus_validate_bus_name +#undef dbus_validate_utf8 +#undef dbus_threads_init +#undef dbus_threads_init_default +#include <dlfcn.h> +#include <stdio.h> +void (*dbus_error_init_dylibloader_wrapper_dbus)( DBusError*); +void (*dbus_error_free_dylibloader_wrapper_dbus)( DBusError*); +void (*dbus_set_error_dylibloader_wrapper_dbus)( DBusError*,const char*,const char*,...); +void (*dbus_set_error_const_dylibloader_wrapper_dbus)( DBusError*,const char*,const char*); +void (*dbus_move_error_dylibloader_wrapper_dbus)( DBusError*, DBusError*); +dbus_bool_t (*dbus_error_has_name_dylibloader_wrapper_dbus)(const DBusError*,const char*); +dbus_bool_t (*dbus_error_is_set_dylibloader_wrapper_dbus)(const DBusError*); +dbus_bool_t (*dbus_parse_address_dylibloader_wrapper_dbus)(const char*, DBusAddressEntry***, int*, DBusError*); +const char* (*dbus_address_entry_get_value_dylibloader_wrapper_dbus)( DBusAddressEntry*,const char*); +const char* (*dbus_address_entry_get_method_dylibloader_wrapper_dbus)( DBusAddressEntry*); +void (*dbus_address_entries_free_dylibloader_wrapper_dbus)( DBusAddressEntry**); +char* (*dbus_address_escape_value_dylibloader_wrapper_dbus)(const char*); +char* (*dbus_address_unescape_value_dylibloader_wrapper_dbus)(const char*, DBusError*); +void* (*dbus_malloc_dylibloader_wrapper_dbus)( size_t); +void* (*dbus_malloc0_dylibloader_wrapper_dbus)( size_t); +void* (*dbus_realloc_dylibloader_wrapper_dbus)( void*, size_t); +void (*dbus_free_dylibloader_wrapper_dbus)( void*); +void (*dbus_free_string_array_dylibloader_wrapper_dbus)( char**); +void (*dbus_shutdown_dylibloader_wrapper_dbus)( void); +DBusMessage* (*dbus_message_new_dylibloader_wrapper_dbus)( int); +DBusMessage* (*dbus_message_new_method_call_dylibloader_wrapper_dbus)(const char*,const char*,const char*,const char*); +DBusMessage* (*dbus_message_new_method_return_dylibloader_wrapper_dbus)( DBusMessage*); +DBusMessage* (*dbus_message_new_signal_dylibloader_wrapper_dbus)(const char*,const char*,const char*); +DBusMessage* (*dbus_message_new_error_dylibloader_wrapper_dbus)( DBusMessage*,const char*,const char*); +DBusMessage* (*dbus_message_new_error_printf_dylibloader_wrapper_dbus)( DBusMessage*,const char*,const char*,...); +DBusMessage* (*dbus_message_copy_dylibloader_wrapper_dbus)(const DBusMessage*); +DBusMessage* (*dbus_message_ref_dylibloader_wrapper_dbus)( DBusMessage*); +void (*dbus_message_unref_dylibloader_wrapper_dbus)( DBusMessage*); +int (*dbus_message_get_type_dylibloader_wrapper_dbus)( DBusMessage*); +dbus_bool_t (*dbus_message_set_path_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +const char* (*dbus_message_get_path_dylibloader_wrapper_dbus)( DBusMessage*); +dbus_bool_t (*dbus_message_has_path_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +dbus_bool_t (*dbus_message_set_interface_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +const char* (*dbus_message_get_interface_dylibloader_wrapper_dbus)( DBusMessage*); +dbus_bool_t (*dbus_message_has_interface_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +dbus_bool_t (*dbus_message_set_member_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +const char* (*dbus_message_get_member_dylibloader_wrapper_dbus)( DBusMessage*); +dbus_bool_t (*dbus_message_has_member_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +dbus_bool_t (*dbus_message_set_error_name_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +const char* (*dbus_message_get_error_name_dylibloader_wrapper_dbus)( DBusMessage*); +dbus_bool_t (*dbus_message_set_destination_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +const char* (*dbus_message_get_destination_dylibloader_wrapper_dbus)( DBusMessage*); +dbus_bool_t (*dbus_message_set_sender_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +const char* (*dbus_message_get_sender_dylibloader_wrapper_dbus)( DBusMessage*); +const char* (*dbus_message_get_signature_dylibloader_wrapper_dbus)( DBusMessage*); +void (*dbus_message_set_no_reply_dylibloader_wrapper_dbus)( DBusMessage*, dbus_bool_t); +dbus_bool_t (*dbus_message_get_no_reply_dylibloader_wrapper_dbus)( DBusMessage*); +dbus_bool_t (*dbus_message_is_method_call_dylibloader_wrapper_dbus)( DBusMessage*,const char*,const char*); +dbus_bool_t (*dbus_message_is_signal_dylibloader_wrapper_dbus)( DBusMessage*,const char*,const char*); +dbus_bool_t (*dbus_message_is_error_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +dbus_bool_t (*dbus_message_has_destination_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +dbus_bool_t (*dbus_message_has_sender_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +dbus_bool_t (*dbus_message_has_signature_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +dbus_uint32_t (*dbus_message_get_serial_dylibloader_wrapper_dbus)( DBusMessage*); +void (*dbus_message_set_serial_dylibloader_wrapper_dbus)( DBusMessage*, dbus_uint32_t); +dbus_bool_t (*dbus_message_set_reply_serial_dylibloader_wrapper_dbus)( DBusMessage*, dbus_uint32_t); +dbus_uint32_t (*dbus_message_get_reply_serial_dylibloader_wrapper_dbus)( DBusMessage*); +void (*dbus_message_set_auto_start_dylibloader_wrapper_dbus)( DBusMessage*, dbus_bool_t); +dbus_bool_t (*dbus_message_get_auto_start_dylibloader_wrapper_dbus)( DBusMessage*); +dbus_bool_t (*dbus_message_get_path_decomposed_dylibloader_wrapper_dbus)( DBusMessage*, char***); +dbus_bool_t (*dbus_message_append_args_dylibloader_wrapper_dbus)( DBusMessage*, int,...); +dbus_bool_t (*dbus_message_append_args_valist_dylibloader_wrapper_dbus)( DBusMessage*, int, va_list); +dbus_bool_t (*dbus_message_get_args_dylibloader_wrapper_dbus)( DBusMessage*, DBusError*, int,...); +dbus_bool_t (*dbus_message_get_args_valist_dylibloader_wrapper_dbus)( DBusMessage*, DBusError*, int, va_list); +dbus_bool_t (*dbus_message_contains_unix_fds_dylibloader_wrapper_dbus)( DBusMessage*); +void (*dbus_message_iter_init_closed_dylibloader_wrapper_dbus)( DBusMessageIter*); +dbus_bool_t (*dbus_message_iter_init_dylibloader_wrapper_dbus)( DBusMessage*, DBusMessageIter*); +dbus_bool_t (*dbus_message_iter_has_next_dylibloader_wrapper_dbus)( DBusMessageIter*); +dbus_bool_t (*dbus_message_iter_next_dylibloader_wrapper_dbus)( DBusMessageIter*); +char* (*dbus_message_iter_get_signature_dylibloader_wrapper_dbus)( DBusMessageIter*); +int (*dbus_message_iter_get_arg_type_dylibloader_wrapper_dbus)( DBusMessageIter*); +int (*dbus_message_iter_get_element_type_dylibloader_wrapper_dbus)( DBusMessageIter*); +void (*dbus_message_iter_recurse_dylibloader_wrapper_dbus)( DBusMessageIter*, DBusMessageIter*); +void (*dbus_message_iter_get_basic_dylibloader_wrapper_dbus)( DBusMessageIter*, void*); +int (*dbus_message_iter_get_element_count_dylibloader_wrapper_dbus)( DBusMessageIter*); +int (*dbus_message_iter_get_array_len_dylibloader_wrapper_dbus)( DBusMessageIter*); +void (*dbus_message_iter_get_fixed_array_dylibloader_wrapper_dbus)( DBusMessageIter*, void*, int*); +void (*dbus_message_iter_init_append_dylibloader_wrapper_dbus)( DBusMessage*, DBusMessageIter*); +dbus_bool_t (*dbus_message_iter_append_basic_dylibloader_wrapper_dbus)( DBusMessageIter*, int,const void*); +dbus_bool_t (*dbus_message_iter_append_fixed_array_dylibloader_wrapper_dbus)( DBusMessageIter*, int,const void*, int); +dbus_bool_t (*dbus_message_iter_open_container_dylibloader_wrapper_dbus)( DBusMessageIter*, int,const char*, DBusMessageIter*); +dbus_bool_t (*dbus_message_iter_close_container_dylibloader_wrapper_dbus)( DBusMessageIter*, DBusMessageIter*); +void (*dbus_message_iter_abandon_container_dylibloader_wrapper_dbus)( DBusMessageIter*, DBusMessageIter*); +void (*dbus_message_iter_abandon_container_if_open_dylibloader_wrapper_dbus)( DBusMessageIter*, DBusMessageIter*); +void (*dbus_message_lock_dylibloader_wrapper_dbus)( DBusMessage*); +dbus_bool_t (*dbus_set_error_from_message_dylibloader_wrapper_dbus)( DBusError*, DBusMessage*); +dbus_bool_t (*dbus_message_allocate_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +void (*dbus_message_free_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +dbus_bool_t (*dbus_message_set_data_dylibloader_wrapper_dbus)( DBusMessage*, dbus_int32_t, void*, DBusFreeFunction); +void* (*dbus_message_get_data_dylibloader_wrapper_dbus)( DBusMessage*, dbus_int32_t); +int (*dbus_message_type_from_string_dylibloader_wrapper_dbus)(const char*); +const char* (*dbus_message_type_to_string_dylibloader_wrapper_dbus)( int); +dbus_bool_t (*dbus_message_marshal_dylibloader_wrapper_dbus)( DBusMessage*, char**, int*); +DBusMessage* (*dbus_message_demarshal_dylibloader_wrapper_dbus)(const char*, int, DBusError*); +int (*dbus_message_demarshal_bytes_needed_dylibloader_wrapper_dbus)(const char*, int); +void (*dbus_message_set_allow_interactive_authorization_dylibloader_wrapper_dbus)( DBusMessage*, dbus_bool_t); +dbus_bool_t (*dbus_message_get_allow_interactive_authorization_dylibloader_wrapper_dbus)( DBusMessage*); +DBusConnection* (*dbus_connection_open_dylibloader_wrapper_dbus)(const char*, DBusError*); +DBusConnection* (*dbus_connection_open_private_dylibloader_wrapper_dbus)(const char*, DBusError*); +DBusConnection* (*dbus_connection_ref_dylibloader_wrapper_dbus)( DBusConnection*); +void (*dbus_connection_unref_dylibloader_wrapper_dbus)( DBusConnection*); +void (*dbus_connection_close_dylibloader_wrapper_dbus)( DBusConnection*); +dbus_bool_t (*dbus_connection_get_is_connected_dylibloader_wrapper_dbus)( DBusConnection*); +dbus_bool_t (*dbus_connection_get_is_authenticated_dylibloader_wrapper_dbus)( DBusConnection*); +dbus_bool_t (*dbus_connection_get_is_anonymous_dylibloader_wrapper_dbus)( DBusConnection*); +char* (*dbus_connection_get_server_id_dylibloader_wrapper_dbus)( DBusConnection*); +dbus_bool_t (*dbus_connection_can_send_type_dylibloader_wrapper_dbus)( DBusConnection*, int); +void (*dbus_connection_set_exit_on_disconnect_dylibloader_wrapper_dbus)( DBusConnection*, dbus_bool_t); +void (*dbus_connection_flush_dylibloader_wrapper_dbus)( DBusConnection*); +dbus_bool_t (*dbus_connection_read_write_dispatch_dylibloader_wrapper_dbus)( DBusConnection*, int); +dbus_bool_t (*dbus_connection_read_write_dylibloader_wrapper_dbus)( DBusConnection*, int); +DBusMessage* (*dbus_connection_borrow_message_dylibloader_wrapper_dbus)( DBusConnection*); +void (*dbus_connection_return_message_dylibloader_wrapper_dbus)( DBusConnection*, DBusMessage*); +void (*dbus_connection_steal_borrowed_message_dylibloader_wrapper_dbus)( DBusConnection*, DBusMessage*); +DBusMessage* (*dbus_connection_pop_message_dylibloader_wrapper_dbus)( DBusConnection*); +DBusDispatchStatus (*dbus_connection_get_dispatch_status_dylibloader_wrapper_dbus)( DBusConnection*); +DBusDispatchStatus (*dbus_connection_dispatch_dylibloader_wrapper_dbus)( DBusConnection*); +dbus_bool_t (*dbus_connection_has_messages_to_send_dylibloader_wrapper_dbus)( DBusConnection*); +dbus_bool_t (*dbus_connection_send_dylibloader_wrapper_dbus)( DBusConnection*, DBusMessage*, dbus_uint32_t*); +dbus_bool_t (*dbus_connection_send_with_reply_dylibloader_wrapper_dbus)( DBusConnection*, DBusMessage*, DBusPendingCall**, int); +DBusMessage* (*dbus_connection_send_with_reply_and_block_dylibloader_wrapper_dbus)( DBusConnection*, DBusMessage*, int, DBusError*); +dbus_bool_t (*dbus_connection_set_watch_functions_dylibloader_wrapper_dbus)( DBusConnection*, DBusAddWatchFunction, DBusRemoveWatchFunction, DBusWatchToggledFunction, void*, DBusFreeFunction); +dbus_bool_t (*dbus_connection_set_timeout_functions_dylibloader_wrapper_dbus)( DBusConnection*, DBusAddTimeoutFunction, DBusRemoveTimeoutFunction, DBusTimeoutToggledFunction, void*, DBusFreeFunction); +void (*dbus_connection_set_wakeup_main_function_dylibloader_wrapper_dbus)( DBusConnection*, DBusWakeupMainFunction, void*, DBusFreeFunction); +void (*dbus_connection_set_dispatch_status_function_dylibloader_wrapper_dbus)( DBusConnection*, DBusDispatchStatusFunction, void*, DBusFreeFunction); +dbus_bool_t (*dbus_connection_get_unix_user_dylibloader_wrapper_dbus)( DBusConnection*, unsigned long*); +dbus_bool_t (*dbus_connection_get_unix_process_id_dylibloader_wrapper_dbus)( DBusConnection*, unsigned long*); +dbus_bool_t (*dbus_connection_get_adt_audit_session_data_dylibloader_wrapper_dbus)( DBusConnection*, void**, dbus_int32_t*); +void (*dbus_connection_set_unix_user_function_dylibloader_wrapper_dbus)( DBusConnection*, DBusAllowUnixUserFunction, void*, DBusFreeFunction); +dbus_bool_t (*dbus_connection_get_windows_user_dylibloader_wrapper_dbus)( DBusConnection*, char**); +void (*dbus_connection_set_windows_user_function_dylibloader_wrapper_dbus)( DBusConnection*, DBusAllowWindowsUserFunction, void*, DBusFreeFunction); +void (*dbus_connection_set_allow_anonymous_dylibloader_wrapper_dbus)( DBusConnection*, dbus_bool_t); +void (*dbus_connection_set_route_peer_messages_dylibloader_wrapper_dbus)( DBusConnection*, dbus_bool_t); +dbus_bool_t (*dbus_connection_add_filter_dylibloader_wrapper_dbus)( DBusConnection*, DBusHandleMessageFunction, void*, DBusFreeFunction); +void (*dbus_connection_remove_filter_dylibloader_wrapper_dbus)( DBusConnection*, DBusHandleMessageFunction, void*); +dbus_bool_t (*dbus_connection_allocate_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +void (*dbus_connection_free_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +dbus_bool_t (*dbus_connection_set_data_dylibloader_wrapper_dbus)( DBusConnection*, dbus_int32_t, void*, DBusFreeFunction); +void* (*dbus_connection_get_data_dylibloader_wrapper_dbus)( DBusConnection*, dbus_int32_t); +void (*dbus_connection_set_change_sigpipe_dylibloader_wrapper_dbus)( dbus_bool_t); +void (*dbus_connection_set_max_message_size_dylibloader_wrapper_dbus)( DBusConnection*, long); +long (*dbus_connection_get_max_message_size_dylibloader_wrapper_dbus)( DBusConnection*); +void (*dbus_connection_set_max_received_size_dylibloader_wrapper_dbus)( DBusConnection*, long); +long (*dbus_connection_get_max_received_size_dylibloader_wrapper_dbus)( DBusConnection*); +void (*dbus_connection_set_max_message_unix_fds_dylibloader_wrapper_dbus)( DBusConnection*, long); +long (*dbus_connection_get_max_message_unix_fds_dylibloader_wrapper_dbus)( DBusConnection*); +void (*dbus_connection_set_max_received_unix_fds_dylibloader_wrapper_dbus)( DBusConnection*, long); +long (*dbus_connection_get_max_received_unix_fds_dylibloader_wrapper_dbus)( DBusConnection*); +long (*dbus_connection_get_outgoing_size_dylibloader_wrapper_dbus)( DBusConnection*); +long (*dbus_connection_get_outgoing_unix_fds_dylibloader_wrapper_dbus)( DBusConnection*); +DBusPreallocatedSend* (*dbus_connection_preallocate_send_dylibloader_wrapper_dbus)( DBusConnection*); +void (*dbus_connection_free_preallocated_send_dylibloader_wrapper_dbus)( DBusConnection*, DBusPreallocatedSend*); +void (*dbus_connection_send_preallocated_dylibloader_wrapper_dbus)( DBusConnection*, DBusPreallocatedSend*, DBusMessage*, dbus_uint32_t*); +dbus_bool_t (*dbus_connection_try_register_object_path_dylibloader_wrapper_dbus)( DBusConnection*,const char*,const DBusObjectPathVTable*, void*, DBusError*); +dbus_bool_t (*dbus_connection_register_object_path_dylibloader_wrapper_dbus)( DBusConnection*,const char*,const DBusObjectPathVTable*, void*); +dbus_bool_t (*dbus_connection_try_register_fallback_dylibloader_wrapper_dbus)( DBusConnection*,const char*,const DBusObjectPathVTable*, void*, DBusError*); +dbus_bool_t (*dbus_connection_register_fallback_dylibloader_wrapper_dbus)( DBusConnection*,const char*,const DBusObjectPathVTable*, void*); +dbus_bool_t (*dbus_connection_unregister_object_path_dylibloader_wrapper_dbus)( DBusConnection*,const char*); +dbus_bool_t (*dbus_connection_get_object_path_data_dylibloader_wrapper_dbus)( DBusConnection*,const char*, void**); +dbus_bool_t (*dbus_connection_list_registered_dylibloader_wrapper_dbus)( DBusConnection*,const char*, char***); +dbus_bool_t (*dbus_connection_get_unix_fd_dylibloader_wrapper_dbus)( DBusConnection*, int*); +dbus_bool_t (*dbus_connection_get_socket_dylibloader_wrapper_dbus)( DBusConnection*, int*); +int (*dbus_watch_get_fd_dylibloader_wrapper_dbus)( DBusWatch*); +int (*dbus_watch_get_unix_fd_dylibloader_wrapper_dbus)( DBusWatch*); +int (*dbus_watch_get_socket_dylibloader_wrapper_dbus)( DBusWatch*); +unsigned int (*dbus_watch_get_flags_dylibloader_wrapper_dbus)( DBusWatch*); +void* (*dbus_watch_get_data_dylibloader_wrapper_dbus)( DBusWatch*); +void (*dbus_watch_set_data_dylibloader_wrapper_dbus)( DBusWatch*, void*, DBusFreeFunction); +dbus_bool_t (*dbus_watch_handle_dylibloader_wrapper_dbus)( DBusWatch*, unsigned int); +dbus_bool_t (*dbus_watch_get_enabled_dylibloader_wrapper_dbus)( DBusWatch*); +int (*dbus_timeout_get_interval_dylibloader_wrapper_dbus)( DBusTimeout*); +void* (*dbus_timeout_get_data_dylibloader_wrapper_dbus)( DBusTimeout*); +void (*dbus_timeout_set_data_dylibloader_wrapper_dbus)( DBusTimeout*, void*, DBusFreeFunction); +dbus_bool_t (*dbus_timeout_handle_dylibloader_wrapper_dbus)( DBusTimeout*); +dbus_bool_t (*dbus_timeout_get_enabled_dylibloader_wrapper_dbus)( DBusTimeout*); +DBusConnection* (*dbus_bus_get_dylibloader_wrapper_dbus)( DBusBusType, DBusError*); +DBusConnection* (*dbus_bus_get_private_dylibloader_wrapper_dbus)( DBusBusType, DBusError*); +dbus_bool_t (*dbus_bus_register_dylibloader_wrapper_dbus)( DBusConnection*, DBusError*); +dbus_bool_t (*dbus_bus_set_unique_name_dylibloader_wrapper_dbus)( DBusConnection*,const char*); +const char* (*dbus_bus_get_unique_name_dylibloader_wrapper_dbus)( DBusConnection*); +unsigned long (*dbus_bus_get_unix_user_dylibloader_wrapper_dbus)( DBusConnection*,const char*, DBusError*); +char* (*dbus_bus_get_id_dylibloader_wrapper_dbus)( DBusConnection*, DBusError*); +int (*dbus_bus_request_name_dylibloader_wrapper_dbus)( DBusConnection*,const char*, unsigned int, DBusError*); +int (*dbus_bus_release_name_dylibloader_wrapper_dbus)( DBusConnection*,const char*, DBusError*); +dbus_bool_t (*dbus_bus_name_has_owner_dylibloader_wrapper_dbus)( DBusConnection*,const char*, DBusError*); +dbus_bool_t (*dbus_bus_start_service_by_name_dylibloader_wrapper_dbus)( DBusConnection*,const char*, dbus_uint32_t, dbus_uint32_t*, DBusError*); +void (*dbus_bus_add_match_dylibloader_wrapper_dbus)( DBusConnection*,const char*, DBusError*); +void (*dbus_bus_remove_match_dylibloader_wrapper_dbus)( DBusConnection*,const char*, DBusError*); +char* (*dbus_get_local_machine_id_dylibloader_wrapper_dbus)( void); +void (*dbus_get_version_dylibloader_wrapper_dbus)( int*, int*, int*); +dbus_bool_t (*dbus_setenv_dylibloader_wrapper_dbus)(const char*,const char*); +char* (*dbus_try_get_local_machine_id_dylibloader_wrapper_dbus)( DBusError*); +DBusPendingCall* (*dbus_pending_call_ref_dylibloader_wrapper_dbus)( DBusPendingCall*); +void (*dbus_pending_call_unref_dylibloader_wrapper_dbus)( DBusPendingCall*); +dbus_bool_t (*dbus_pending_call_set_notify_dylibloader_wrapper_dbus)( DBusPendingCall*, DBusPendingCallNotifyFunction, void*, DBusFreeFunction); +void (*dbus_pending_call_cancel_dylibloader_wrapper_dbus)( DBusPendingCall*); +dbus_bool_t (*dbus_pending_call_get_completed_dylibloader_wrapper_dbus)( DBusPendingCall*); +DBusMessage* (*dbus_pending_call_steal_reply_dylibloader_wrapper_dbus)( DBusPendingCall*); +void (*dbus_pending_call_block_dylibloader_wrapper_dbus)( DBusPendingCall*); +dbus_bool_t (*dbus_pending_call_allocate_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +void (*dbus_pending_call_free_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +dbus_bool_t (*dbus_pending_call_set_data_dylibloader_wrapper_dbus)( DBusPendingCall*, dbus_int32_t, void*, DBusFreeFunction); +void* (*dbus_pending_call_get_data_dylibloader_wrapper_dbus)( DBusPendingCall*, dbus_int32_t); +DBusServer* (*dbus_server_listen_dylibloader_wrapper_dbus)(const char*, DBusError*); +DBusServer* (*dbus_server_ref_dylibloader_wrapper_dbus)( DBusServer*); +void (*dbus_server_unref_dylibloader_wrapper_dbus)( DBusServer*); +void (*dbus_server_disconnect_dylibloader_wrapper_dbus)( DBusServer*); +dbus_bool_t (*dbus_server_get_is_connected_dylibloader_wrapper_dbus)( DBusServer*); +char* (*dbus_server_get_address_dylibloader_wrapper_dbus)( DBusServer*); +char* (*dbus_server_get_id_dylibloader_wrapper_dbus)( DBusServer*); +void (*dbus_server_set_new_connection_function_dylibloader_wrapper_dbus)( DBusServer*, DBusNewConnectionFunction, void*, DBusFreeFunction); +dbus_bool_t (*dbus_server_set_watch_functions_dylibloader_wrapper_dbus)( DBusServer*, DBusAddWatchFunction, DBusRemoveWatchFunction, DBusWatchToggledFunction, void*, DBusFreeFunction); +dbus_bool_t (*dbus_server_set_timeout_functions_dylibloader_wrapper_dbus)( DBusServer*, DBusAddTimeoutFunction, DBusRemoveTimeoutFunction, DBusTimeoutToggledFunction, void*, DBusFreeFunction); +dbus_bool_t (*dbus_server_set_auth_mechanisms_dylibloader_wrapper_dbus)( DBusServer*,const char**); +dbus_bool_t (*dbus_server_allocate_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +void (*dbus_server_free_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +dbus_bool_t (*dbus_server_set_data_dylibloader_wrapper_dbus)( DBusServer*, int, void*, DBusFreeFunction); +void* (*dbus_server_get_data_dylibloader_wrapper_dbus)( DBusServer*, int); +void (*dbus_signature_iter_init_dylibloader_wrapper_dbus)( DBusSignatureIter*,const char*); +int (*dbus_signature_iter_get_current_type_dylibloader_wrapper_dbus)(const DBusSignatureIter*); +char* (*dbus_signature_iter_get_signature_dylibloader_wrapper_dbus)(const DBusSignatureIter*); +int (*dbus_signature_iter_get_element_type_dylibloader_wrapper_dbus)(const DBusSignatureIter*); +dbus_bool_t (*dbus_signature_iter_next_dylibloader_wrapper_dbus)( DBusSignatureIter*); +void (*dbus_signature_iter_recurse_dylibloader_wrapper_dbus)(const DBusSignatureIter*, DBusSignatureIter*); +dbus_bool_t (*dbus_signature_validate_dylibloader_wrapper_dbus)(const char*, DBusError*); +dbus_bool_t (*dbus_signature_validate_single_dylibloader_wrapper_dbus)(const char*, DBusError*); +dbus_bool_t (*dbus_type_is_valid_dylibloader_wrapper_dbus)( int); +dbus_bool_t (*dbus_type_is_basic_dylibloader_wrapper_dbus)( int); +dbus_bool_t (*dbus_type_is_container_dylibloader_wrapper_dbus)( int); +dbus_bool_t (*dbus_type_is_fixed_dylibloader_wrapper_dbus)( int); +dbus_bool_t (*dbus_validate_path_dylibloader_wrapper_dbus)(const char*, DBusError*); +dbus_bool_t (*dbus_validate_interface_dylibloader_wrapper_dbus)(const char*, DBusError*); +dbus_bool_t (*dbus_validate_member_dylibloader_wrapper_dbus)(const char*, DBusError*); +dbus_bool_t (*dbus_validate_error_name_dylibloader_wrapper_dbus)(const char*, DBusError*); +dbus_bool_t (*dbus_validate_bus_name_dylibloader_wrapper_dbus)(const char*, DBusError*); +dbus_bool_t (*dbus_validate_utf8_dylibloader_wrapper_dbus)(const char*, DBusError*); +dbus_bool_t (*dbus_threads_init_dylibloader_wrapper_dbus)(const DBusThreadFunctions*); +dbus_bool_t (*dbus_threads_init_default_dylibloader_wrapper_dbus)( void); +int initialize_dbus(int verbose) { + void *handle; + char *error; + handle = dlopen("libdbus-1.so", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// dbus_error_init + *(void **) (&dbus_error_init_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_error_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_error_free + *(void **) (&dbus_error_free_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_error_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_set_error + *(void **) (&dbus_set_error_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_set_error"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_set_error_const + *(void **) (&dbus_set_error_const_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_set_error_const"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_move_error + *(void **) (&dbus_move_error_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_move_error"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_error_has_name + *(void **) (&dbus_error_has_name_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_error_has_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_error_is_set + *(void **) (&dbus_error_is_set_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_error_is_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_parse_address + *(void **) (&dbus_parse_address_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_parse_address"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_address_entry_get_value + *(void **) (&dbus_address_entry_get_value_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_address_entry_get_value"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_address_entry_get_method + *(void **) (&dbus_address_entry_get_method_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_address_entry_get_method"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_address_entries_free + *(void **) (&dbus_address_entries_free_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_address_entries_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_address_escape_value + *(void **) (&dbus_address_escape_value_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_address_escape_value"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_address_unescape_value + *(void **) (&dbus_address_unescape_value_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_address_unescape_value"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_malloc + *(void **) (&dbus_malloc_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_malloc0 + *(void **) (&dbus_malloc0_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_malloc0"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_realloc + *(void **) (&dbus_realloc_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_realloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_free + *(void **) (&dbus_free_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_free_string_array + *(void **) (&dbus_free_string_array_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_free_string_array"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_shutdown + *(void **) (&dbus_shutdown_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_shutdown"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_new + *(void **) (&dbus_message_new_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_new_method_call + *(void **) (&dbus_message_new_method_call_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_new_method_call"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_new_method_return + *(void **) (&dbus_message_new_method_return_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_new_method_return"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_new_signal + *(void **) (&dbus_message_new_signal_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_new_signal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_new_error + *(void **) (&dbus_message_new_error_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_new_error"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_new_error_printf + *(void **) (&dbus_message_new_error_printf_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_new_error_printf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_copy + *(void **) (&dbus_message_copy_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_ref + *(void **) (&dbus_message_ref_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_unref + *(void **) (&dbus_message_unref_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_type + *(void **) (&dbus_message_get_type_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_path + *(void **) (&dbus_message_set_path_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_path"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_path + *(void **) (&dbus_message_get_path_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_path"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_has_path + *(void **) (&dbus_message_has_path_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_has_path"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_interface + *(void **) (&dbus_message_set_interface_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_interface + *(void **) (&dbus_message_get_interface_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_has_interface + *(void **) (&dbus_message_has_interface_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_has_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_member + *(void **) (&dbus_message_set_member_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_member"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_member + *(void **) (&dbus_message_get_member_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_member"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_has_member + *(void **) (&dbus_message_has_member_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_has_member"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_error_name + *(void **) (&dbus_message_set_error_name_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_error_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_error_name + *(void **) (&dbus_message_get_error_name_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_error_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_destination + *(void **) (&dbus_message_set_destination_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_destination"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_destination + *(void **) (&dbus_message_get_destination_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_destination"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_sender + *(void **) (&dbus_message_set_sender_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_sender"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_sender + *(void **) (&dbus_message_get_sender_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_sender"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_signature + *(void **) (&dbus_message_get_signature_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_signature"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_no_reply + *(void **) (&dbus_message_set_no_reply_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_no_reply"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_no_reply + *(void **) (&dbus_message_get_no_reply_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_no_reply"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_is_method_call + *(void **) (&dbus_message_is_method_call_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_is_method_call"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_is_signal + *(void **) (&dbus_message_is_signal_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_is_signal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_is_error + *(void **) (&dbus_message_is_error_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_is_error"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_has_destination + *(void **) (&dbus_message_has_destination_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_has_destination"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_has_sender + *(void **) (&dbus_message_has_sender_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_has_sender"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_has_signature + *(void **) (&dbus_message_has_signature_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_has_signature"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_serial + *(void **) (&dbus_message_get_serial_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_serial"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_serial + *(void **) (&dbus_message_set_serial_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_serial"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_reply_serial + *(void **) (&dbus_message_set_reply_serial_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_reply_serial"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_reply_serial + *(void **) (&dbus_message_get_reply_serial_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_reply_serial"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_auto_start + *(void **) (&dbus_message_set_auto_start_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_auto_start"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_auto_start + *(void **) (&dbus_message_get_auto_start_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_auto_start"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_path_decomposed + *(void **) (&dbus_message_get_path_decomposed_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_path_decomposed"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_append_args + *(void **) (&dbus_message_append_args_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_append_args"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_append_args_valist + *(void **) (&dbus_message_append_args_valist_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_append_args_valist"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_args + *(void **) (&dbus_message_get_args_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_args"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_args_valist + *(void **) (&dbus_message_get_args_valist_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_args_valist"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_contains_unix_fds + *(void **) (&dbus_message_contains_unix_fds_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_contains_unix_fds"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_init_closed + *(void **) (&dbus_message_iter_init_closed_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_init_closed"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_init + *(void **) (&dbus_message_iter_init_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_has_next + *(void **) (&dbus_message_iter_has_next_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_has_next"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_next + *(void **) (&dbus_message_iter_next_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_next"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_get_signature + *(void **) (&dbus_message_iter_get_signature_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_get_signature"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_get_arg_type + *(void **) (&dbus_message_iter_get_arg_type_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_get_arg_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_get_element_type + *(void **) (&dbus_message_iter_get_element_type_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_get_element_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_recurse + *(void **) (&dbus_message_iter_recurse_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_recurse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_get_basic + *(void **) (&dbus_message_iter_get_basic_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_get_basic"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_get_element_count + *(void **) (&dbus_message_iter_get_element_count_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_get_element_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_get_array_len + *(void **) (&dbus_message_iter_get_array_len_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_get_array_len"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_get_fixed_array + *(void **) (&dbus_message_iter_get_fixed_array_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_get_fixed_array"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_init_append + *(void **) (&dbus_message_iter_init_append_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_init_append"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_append_basic + *(void **) (&dbus_message_iter_append_basic_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_append_basic"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_append_fixed_array + *(void **) (&dbus_message_iter_append_fixed_array_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_append_fixed_array"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_open_container + *(void **) (&dbus_message_iter_open_container_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_open_container"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_close_container + *(void **) (&dbus_message_iter_close_container_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_close_container"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_abandon_container + *(void **) (&dbus_message_iter_abandon_container_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_abandon_container"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_iter_abandon_container_if_open + *(void **) (&dbus_message_iter_abandon_container_if_open_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_iter_abandon_container_if_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_lock + *(void **) (&dbus_message_lock_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_lock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_set_error_from_message + *(void **) (&dbus_set_error_from_message_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_set_error_from_message"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_allocate_data_slot + *(void **) (&dbus_message_allocate_data_slot_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_allocate_data_slot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_free_data_slot + *(void **) (&dbus_message_free_data_slot_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_free_data_slot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_data + *(void **) (&dbus_message_set_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_data + *(void **) (&dbus_message_get_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_type_from_string + *(void **) (&dbus_message_type_from_string_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_type_from_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_type_to_string + *(void **) (&dbus_message_type_to_string_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_type_to_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_marshal + *(void **) (&dbus_message_marshal_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_marshal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_demarshal + *(void **) (&dbus_message_demarshal_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_demarshal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_demarshal_bytes_needed + *(void **) (&dbus_message_demarshal_bytes_needed_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_demarshal_bytes_needed"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_set_allow_interactive_authorization + *(void **) (&dbus_message_set_allow_interactive_authorization_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_set_allow_interactive_authorization"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_message_get_allow_interactive_authorization + *(void **) (&dbus_message_get_allow_interactive_authorization_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_message_get_allow_interactive_authorization"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_open + *(void **) (&dbus_connection_open_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_open_private + *(void **) (&dbus_connection_open_private_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_open_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_ref + *(void **) (&dbus_connection_ref_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_unref + *(void **) (&dbus_connection_unref_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_close + *(void **) (&dbus_connection_close_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_is_connected + *(void **) (&dbus_connection_get_is_connected_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_is_connected"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_is_authenticated + *(void **) (&dbus_connection_get_is_authenticated_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_is_authenticated"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_is_anonymous + *(void **) (&dbus_connection_get_is_anonymous_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_is_anonymous"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_server_id + *(void **) (&dbus_connection_get_server_id_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_server_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_can_send_type + *(void **) (&dbus_connection_can_send_type_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_can_send_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_exit_on_disconnect + *(void **) (&dbus_connection_set_exit_on_disconnect_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_exit_on_disconnect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_flush + *(void **) (&dbus_connection_flush_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_flush"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_read_write_dispatch + *(void **) (&dbus_connection_read_write_dispatch_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_read_write_dispatch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_read_write + *(void **) (&dbus_connection_read_write_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_read_write"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_borrow_message + *(void **) (&dbus_connection_borrow_message_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_borrow_message"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_return_message + *(void **) (&dbus_connection_return_message_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_return_message"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_steal_borrowed_message + *(void **) (&dbus_connection_steal_borrowed_message_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_steal_borrowed_message"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_pop_message + *(void **) (&dbus_connection_pop_message_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_pop_message"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_dispatch_status + *(void **) (&dbus_connection_get_dispatch_status_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_dispatch_status"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_dispatch + *(void **) (&dbus_connection_dispatch_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_dispatch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_has_messages_to_send + *(void **) (&dbus_connection_has_messages_to_send_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_has_messages_to_send"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_send + *(void **) (&dbus_connection_send_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_send"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_send_with_reply + *(void **) (&dbus_connection_send_with_reply_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_send_with_reply"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_send_with_reply_and_block + *(void **) (&dbus_connection_send_with_reply_and_block_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_send_with_reply_and_block"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_watch_functions + *(void **) (&dbus_connection_set_watch_functions_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_watch_functions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_timeout_functions + *(void **) (&dbus_connection_set_timeout_functions_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_timeout_functions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_wakeup_main_function + *(void **) (&dbus_connection_set_wakeup_main_function_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_wakeup_main_function"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_dispatch_status_function + *(void **) (&dbus_connection_set_dispatch_status_function_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_dispatch_status_function"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_unix_user + *(void **) (&dbus_connection_get_unix_user_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_unix_user"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_unix_process_id + *(void **) (&dbus_connection_get_unix_process_id_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_unix_process_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_adt_audit_session_data + *(void **) (&dbus_connection_get_adt_audit_session_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_adt_audit_session_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_unix_user_function + *(void **) (&dbus_connection_set_unix_user_function_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_unix_user_function"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_windows_user + *(void **) (&dbus_connection_get_windows_user_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_windows_user"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_windows_user_function + *(void **) (&dbus_connection_set_windows_user_function_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_windows_user_function"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_allow_anonymous + *(void **) (&dbus_connection_set_allow_anonymous_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_allow_anonymous"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_route_peer_messages + *(void **) (&dbus_connection_set_route_peer_messages_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_route_peer_messages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_add_filter + *(void **) (&dbus_connection_add_filter_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_add_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_remove_filter + *(void **) (&dbus_connection_remove_filter_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_remove_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_allocate_data_slot + *(void **) (&dbus_connection_allocate_data_slot_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_allocate_data_slot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_free_data_slot + *(void **) (&dbus_connection_free_data_slot_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_free_data_slot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_data + *(void **) (&dbus_connection_set_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_data + *(void **) (&dbus_connection_get_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_change_sigpipe + *(void **) (&dbus_connection_set_change_sigpipe_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_change_sigpipe"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_max_message_size + *(void **) (&dbus_connection_set_max_message_size_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_max_message_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_max_message_size + *(void **) (&dbus_connection_get_max_message_size_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_max_message_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_max_received_size + *(void **) (&dbus_connection_set_max_received_size_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_max_received_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_max_received_size + *(void **) (&dbus_connection_get_max_received_size_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_max_received_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_max_message_unix_fds + *(void **) (&dbus_connection_set_max_message_unix_fds_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_max_message_unix_fds"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_max_message_unix_fds + *(void **) (&dbus_connection_get_max_message_unix_fds_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_max_message_unix_fds"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_set_max_received_unix_fds + *(void **) (&dbus_connection_set_max_received_unix_fds_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_set_max_received_unix_fds"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_max_received_unix_fds + *(void **) (&dbus_connection_get_max_received_unix_fds_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_max_received_unix_fds"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_outgoing_size + *(void **) (&dbus_connection_get_outgoing_size_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_outgoing_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_outgoing_unix_fds + *(void **) (&dbus_connection_get_outgoing_unix_fds_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_outgoing_unix_fds"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_preallocate_send + *(void **) (&dbus_connection_preallocate_send_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_preallocate_send"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_free_preallocated_send + *(void **) (&dbus_connection_free_preallocated_send_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_free_preallocated_send"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_send_preallocated + *(void **) (&dbus_connection_send_preallocated_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_send_preallocated"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_try_register_object_path + *(void **) (&dbus_connection_try_register_object_path_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_try_register_object_path"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_register_object_path + *(void **) (&dbus_connection_register_object_path_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_register_object_path"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_try_register_fallback + *(void **) (&dbus_connection_try_register_fallback_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_try_register_fallback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_register_fallback + *(void **) (&dbus_connection_register_fallback_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_register_fallback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_unregister_object_path + *(void **) (&dbus_connection_unregister_object_path_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_unregister_object_path"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_object_path_data + *(void **) (&dbus_connection_get_object_path_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_object_path_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_list_registered + *(void **) (&dbus_connection_list_registered_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_list_registered"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_unix_fd + *(void **) (&dbus_connection_get_unix_fd_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_unix_fd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_connection_get_socket + *(void **) (&dbus_connection_get_socket_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_connection_get_socket"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_watch_get_fd + *(void **) (&dbus_watch_get_fd_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_watch_get_fd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_watch_get_unix_fd + *(void **) (&dbus_watch_get_unix_fd_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_watch_get_unix_fd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_watch_get_socket + *(void **) (&dbus_watch_get_socket_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_watch_get_socket"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_watch_get_flags + *(void **) (&dbus_watch_get_flags_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_watch_get_flags"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_watch_get_data + *(void **) (&dbus_watch_get_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_watch_get_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_watch_set_data + *(void **) (&dbus_watch_set_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_watch_set_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_watch_handle + *(void **) (&dbus_watch_handle_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_watch_handle"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_watch_get_enabled + *(void **) (&dbus_watch_get_enabled_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_watch_get_enabled"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_timeout_get_interval + *(void **) (&dbus_timeout_get_interval_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_timeout_get_interval"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_timeout_get_data + *(void **) (&dbus_timeout_get_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_timeout_get_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_timeout_set_data + *(void **) (&dbus_timeout_set_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_timeout_set_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_timeout_handle + *(void **) (&dbus_timeout_handle_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_timeout_handle"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_timeout_get_enabled + *(void **) (&dbus_timeout_get_enabled_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_timeout_get_enabled"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_get + *(void **) (&dbus_bus_get_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_get"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_get_private + *(void **) (&dbus_bus_get_private_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_get_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_register + *(void **) (&dbus_bus_register_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_register"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_set_unique_name + *(void **) (&dbus_bus_set_unique_name_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_set_unique_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_get_unique_name + *(void **) (&dbus_bus_get_unique_name_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_get_unique_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_get_unix_user + *(void **) (&dbus_bus_get_unix_user_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_get_unix_user"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_get_id + *(void **) (&dbus_bus_get_id_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_request_name + *(void **) (&dbus_bus_request_name_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_request_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_release_name + *(void **) (&dbus_bus_release_name_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_release_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_name_has_owner + *(void **) (&dbus_bus_name_has_owner_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_name_has_owner"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_start_service_by_name + *(void **) (&dbus_bus_start_service_by_name_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_start_service_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_add_match + *(void **) (&dbus_bus_add_match_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_add_match"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_bus_remove_match + *(void **) (&dbus_bus_remove_match_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_bus_remove_match"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_get_local_machine_id + *(void **) (&dbus_get_local_machine_id_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_get_local_machine_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_get_version + *(void **) (&dbus_get_version_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_get_version"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_setenv + *(void **) (&dbus_setenv_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_setenv"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_try_get_local_machine_id + *(void **) (&dbus_try_get_local_machine_id_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_try_get_local_machine_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_ref + *(void **) (&dbus_pending_call_ref_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_unref + *(void **) (&dbus_pending_call_unref_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_set_notify + *(void **) (&dbus_pending_call_set_notify_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_set_notify"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_cancel + *(void **) (&dbus_pending_call_cancel_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_cancel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_get_completed + *(void **) (&dbus_pending_call_get_completed_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_get_completed"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_steal_reply + *(void **) (&dbus_pending_call_steal_reply_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_steal_reply"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_block + *(void **) (&dbus_pending_call_block_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_block"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_allocate_data_slot + *(void **) (&dbus_pending_call_allocate_data_slot_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_allocate_data_slot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_free_data_slot + *(void **) (&dbus_pending_call_free_data_slot_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_free_data_slot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_set_data + *(void **) (&dbus_pending_call_set_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_set_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_pending_call_get_data + *(void **) (&dbus_pending_call_get_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_pending_call_get_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_listen + *(void **) (&dbus_server_listen_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_listen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_ref + *(void **) (&dbus_server_ref_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_unref + *(void **) (&dbus_server_unref_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_disconnect + *(void **) (&dbus_server_disconnect_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_disconnect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_get_is_connected + *(void **) (&dbus_server_get_is_connected_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_get_is_connected"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_get_address + *(void **) (&dbus_server_get_address_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_get_address"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_get_id + *(void **) (&dbus_server_get_id_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_set_new_connection_function + *(void **) (&dbus_server_set_new_connection_function_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_set_new_connection_function"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_set_watch_functions + *(void **) (&dbus_server_set_watch_functions_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_set_watch_functions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_set_timeout_functions + *(void **) (&dbus_server_set_timeout_functions_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_set_timeout_functions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_set_auth_mechanisms + *(void **) (&dbus_server_set_auth_mechanisms_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_set_auth_mechanisms"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_allocate_data_slot + *(void **) (&dbus_server_allocate_data_slot_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_allocate_data_slot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_free_data_slot + *(void **) (&dbus_server_free_data_slot_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_free_data_slot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_set_data + *(void **) (&dbus_server_set_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_set_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_server_get_data + *(void **) (&dbus_server_get_data_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_server_get_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_signature_iter_init + *(void **) (&dbus_signature_iter_init_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_signature_iter_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_signature_iter_get_current_type + *(void **) (&dbus_signature_iter_get_current_type_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_signature_iter_get_current_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_signature_iter_get_signature + *(void **) (&dbus_signature_iter_get_signature_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_signature_iter_get_signature"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_signature_iter_get_element_type + *(void **) (&dbus_signature_iter_get_element_type_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_signature_iter_get_element_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_signature_iter_next + *(void **) (&dbus_signature_iter_next_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_signature_iter_next"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_signature_iter_recurse + *(void **) (&dbus_signature_iter_recurse_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_signature_iter_recurse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_signature_validate + *(void **) (&dbus_signature_validate_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_signature_validate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_signature_validate_single + *(void **) (&dbus_signature_validate_single_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_signature_validate_single"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_type_is_valid + *(void **) (&dbus_type_is_valid_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_type_is_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_type_is_basic + *(void **) (&dbus_type_is_basic_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_type_is_basic"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_type_is_container + *(void **) (&dbus_type_is_container_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_type_is_container"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_type_is_fixed + *(void **) (&dbus_type_is_fixed_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_type_is_fixed"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_validate_path + *(void **) (&dbus_validate_path_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_validate_path"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_validate_interface + *(void **) (&dbus_validate_interface_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_validate_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_validate_member + *(void **) (&dbus_validate_member_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_validate_member"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_validate_error_name + *(void **) (&dbus_validate_error_name_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_validate_error_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_validate_bus_name + *(void **) (&dbus_validate_bus_name_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_validate_bus_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_validate_utf8 + *(void **) (&dbus_validate_utf8_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_validate_utf8"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_threads_init + *(void **) (&dbus_threads_init_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_threads_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// dbus_threads_init_default + *(void **) (&dbus_threads_init_default_dylibloader_wrapper_dbus) = dlsym(handle, "dbus_threads_init_default"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/dbus-so_wrap.h b/platform/linuxbsd/dbus-so_wrap.h new file mode 100644 index 0000000000..52e1dd300c --- /dev/null +++ b/platform/linuxbsd/dbus-so_wrap.h @@ -0,0 +1,970 @@ +#ifndef DYLIBLOAD_WRAPPER_DBUS +#define DYLIBLOAD_WRAPPER_DBUS +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by ./generate-wrapper.py 0.3 on 2022-07-29 07:23:21 +// flags: ./generate-wrapper.py --include /usr/include/dbus-1.0/dbus/dbus.h --sys-include <dbus/dbus.h> --soname libdbus-1.so --init-name dbus --output-header dbus-so_wrap.h --output-implementation dbus-so_wrap.c +// +#include <stdint.h> + +#define dbus_error_init dbus_error_init_dylibloader_orig_dbus +#define dbus_error_free dbus_error_free_dylibloader_orig_dbus +#define dbus_set_error dbus_set_error_dylibloader_orig_dbus +#define dbus_set_error_const dbus_set_error_const_dylibloader_orig_dbus +#define dbus_move_error dbus_move_error_dylibloader_orig_dbus +#define dbus_error_has_name dbus_error_has_name_dylibloader_orig_dbus +#define dbus_error_is_set dbus_error_is_set_dylibloader_orig_dbus +#define dbus_parse_address dbus_parse_address_dylibloader_orig_dbus +#define dbus_address_entry_get_value dbus_address_entry_get_value_dylibloader_orig_dbus +#define dbus_address_entry_get_method dbus_address_entry_get_method_dylibloader_orig_dbus +#define dbus_address_entries_free dbus_address_entries_free_dylibloader_orig_dbus +#define dbus_address_escape_value dbus_address_escape_value_dylibloader_orig_dbus +#define dbus_address_unescape_value dbus_address_unescape_value_dylibloader_orig_dbus +#define dbus_malloc dbus_malloc_dylibloader_orig_dbus +#define dbus_malloc0 dbus_malloc0_dylibloader_orig_dbus +#define dbus_realloc dbus_realloc_dylibloader_orig_dbus +#define dbus_free dbus_free_dylibloader_orig_dbus +#define dbus_free_string_array dbus_free_string_array_dylibloader_orig_dbus +#define dbus_shutdown dbus_shutdown_dylibloader_orig_dbus +#define dbus_message_new dbus_message_new_dylibloader_orig_dbus +#define dbus_message_new_method_call dbus_message_new_method_call_dylibloader_orig_dbus +#define dbus_message_new_method_return dbus_message_new_method_return_dylibloader_orig_dbus +#define dbus_message_new_signal dbus_message_new_signal_dylibloader_orig_dbus +#define dbus_message_new_error dbus_message_new_error_dylibloader_orig_dbus +#define dbus_message_new_error_printf dbus_message_new_error_printf_dylibloader_orig_dbus +#define dbus_message_copy dbus_message_copy_dylibloader_orig_dbus +#define dbus_message_ref dbus_message_ref_dylibloader_orig_dbus +#define dbus_message_unref dbus_message_unref_dylibloader_orig_dbus +#define dbus_message_get_type dbus_message_get_type_dylibloader_orig_dbus +#define dbus_message_set_path dbus_message_set_path_dylibloader_orig_dbus +#define dbus_message_get_path dbus_message_get_path_dylibloader_orig_dbus +#define dbus_message_has_path dbus_message_has_path_dylibloader_orig_dbus +#define dbus_message_set_interface dbus_message_set_interface_dylibloader_orig_dbus +#define dbus_message_get_interface dbus_message_get_interface_dylibloader_orig_dbus +#define dbus_message_has_interface dbus_message_has_interface_dylibloader_orig_dbus +#define dbus_message_set_member dbus_message_set_member_dylibloader_orig_dbus +#define dbus_message_get_member dbus_message_get_member_dylibloader_orig_dbus +#define dbus_message_has_member dbus_message_has_member_dylibloader_orig_dbus +#define dbus_message_set_error_name dbus_message_set_error_name_dylibloader_orig_dbus +#define dbus_message_get_error_name dbus_message_get_error_name_dylibloader_orig_dbus +#define dbus_message_set_destination dbus_message_set_destination_dylibloader_orig_dbus +#define dbus_message_get_destination dbus_message_get_destination_dylibloader_orig_dbus +#define dbus_message_set_sender dbus_message_set_sender_dylibloader_orig_dbus +#define dbus_message_get_sender dbus_message_get_sender_dylibloader_orig_dbus +#define dbus_message_get_signature dbus_message_get_signature_dylibloader_orig_dbus +#define dbus_message_set_no_reply dbus_message_set_no_reply_dylibloader_orig_dbus +#define dbus_message_get_no_reply dbus_message_get_no_reply_dylibloader_orig_dbus +#define dbus_message_is_method_call dbus_message_is_method_call_dylibloader_orig_dbus +#define dbus_message_is_signal dbus_message_is_signal_dylibloader_orig_dbus +#define dbus_message_is_error dbus_message_is_error_dylibloader_orig_dbus +#define dbus_message_has_destination dbus_message_has_destination_dylibloader_orig_dbus +#define dbus_message_has_sender dbus_message_has_sender_dylibloader_orig_dbus +#define dbus_message_has_signature dbus_message_has_signature_dylibloader_orig_dbus +#define dbus_message_get_serial dbus_message_get_serial_dylibloader_orig_dbus +#define dbus_message_set_serial dbus_message_set_serial_dylibloader_orig_dbus +#define dbus_message_set_reply_serial dbus_message_set_reply_serial_dylibloader_orig_dbus +#define dbus_message_get_reply_serial dbus_message_get_reply_serial_dylibloader_orig_dbus +#define dbus_message_set_auto_start dbus_message_set_auto_start_dylibloader_orig_dbus +#define dbus_message_get_auto_start dbus_message_get_auto_start_dylibloader_orig_dbus +#define dbus_message_get_path_decomposed dbus_message_get_path_decomposed_dylibloader_orig_dbus +#define dbus_message_append_args dbus_message_append_args_dylibloader_orig_dbus +#define dbus_message_append_args_valist dbus_message_append_args_valist_dylibloader_orig_dbus +#define dbus_message_get_args dbus_message_get_args_dylibloader_orig_dbus +#define dbus_message_get_args_valist dbus_message_get_args_valist_dylibloader_orig_dbus +#define dbus_message_contains_unix_fds dbus_message_contains_unix_fds_dylibloader_orig_dbus +#define dbus_message_iter_init_closed dbus_message_iter_init_closed_dylibloader_orig_dbus +#define dbus_message_iter_init dbus_message_iter_init_dylibloader_orig_dbus +#define dbus_message_iter_has_next dbus_message_iter_has_next_dylibloader_orig_dbus +#define dbus_message_iter_next dbus_message_iter_next_dylibloader_orig_dbus +#define dbus_message_iter_get_signature dbus_message_iter_get_signature_dylibloader_orig_dbus +#define dbus_message_iter_get_arg_type dbus_message_iter_get_arg_type_dylibloader_orig_dbus +#define dbus_message_iter_get_element_type dbus_message_iter_get_element_type_dylibloader_orig_dbus +#define dbus_message_iter_recurse dbus_message_iter_recurse_dylibloader_orig_dbus +#define dbus_message_iter_get_basic dbus_message_iter_get_basic_dylibloader_orig_dbus +#define dbus_message_iter_get_element_count dbus_message_iter_get_element_count_dylibloader_orig_dbus +#define dbus_message_iter_get_array_len dbus_message_iter_get_array_len_dylibloader_orig_dbus +#define dbus_message_iter_get_fixed_array dbus_message_iter_get_fixed_array_dylibloader_orig_dbus +#define dbus_message_iter_init_append dbus_message_iter_init_append_dylibloader_orig_dbus +#define dbus_message_iter_append_basic dbus_message_iter_append_basic_dylibloader_orig_dbus +#define dbus_message_iter_append_fixed_array dbus_message_iter_append_fixed_array_dylibloader_orig_dbus +#define dbus_message_iter_open_container dbus_message_iter_open_container_dylibloader_orig_dbus +#define dbus_message_iter_close_container dbus_message_iter_close_container_dylibloader_orig_dbus +#define dbus_message_iter_abandon_container dbus_message_iter_abandon_container_dylibloader_orig_dbus +#define dbus_message_iter_abandon_container_if_open dbus_message_iter_abandon_container_if_open_dylibloader_orig_dbus +#define dbus_message_lock dbus_message_lock_dylibloader_orig_dbus +#define dbus_set_error_from_message dbus_set_error_from_message_dylibloader_orig_dbus +#define dbus_message_allocate_data_slot dbus_message_allocate_data_slot_dylibloader_orig_dbus +#define dbus_message_free_data_slot dbus_message_free_data_slot_dylibloader_orig_dbus +#define dbus_message_set_data dbus_message_set_data_dylibloader_orig_dbus +#define dbus_message_get_data dbus_message_get_data_dylibloader_orig_dbus +#define dbus_message_type_from_string dbus_message_type_from_string_dylibloader_orig_dbus +#define dbus_message_type_to_string dbus_message_type_to_string_dylibloader_orig_dbus +#define dbus_message_marshal dbus_message_marshal_dylibloader_orig_dbus +#define dbus_message_demarshal dbus_message_demarshal_dylibloader_orig_dbus +#define dbus_message_demarshal_bytes_needed dbus_message_demarshal_bytes_needed_dylibloader_orig_dbus +#define dbus_message_set_allow_interactive_authorization dbus_message_set_allow_interactive_authorization_dylibloader_orig_dbus +#define dbus_message_get_allow_interactive_authorization dbus_message_get_allow_interactive_authorization_dylibloader_orig_dbus +#define dbus_connection_open dbus_connection_open_dylibloader_orig_dbus +#define dbus_connection_open_private dbus_connection_open_private_dylibloader_orig_dbus +#define dbus_connection_ref dbus_connection_ref_dylibloader_orig_dbus +#define dbus_connection_unref dbus_connection_unref_dylibloader_orig_dbus +#define dbus_connection_close dbus_connection_close_dylibloader_orig_dbus +#define dbus_connection_get_is_connected dbus_connection_get_is_connected_dylibloader_orig_dbus +#define dbus_connection_get_is_authenticated dbus_connection_get_is_authenticated_dylibloader_orig_dbus +#define dbus_connection_get_is_anonymous dbus_connection_get_is_anonymous_dylibloader_orig_dbus +#define dbus_connection_get_server_id dbus_connection_get_server_id_dylibloader_orig_dbus +#define dbus_connection_can_send_type dbus_connection_can_send_type_dylibloader_orig_dbus +#define dbus_connection_set_exit_on_disconnect dbus_connection_set_exit_on_disconnect_dylibloader_orig_dbus +#define dbus_connection_flush dbus_connection_flush_dylibloader_orig_dbus +#define dbus_connection_read_write_dispatch dbus_connection_read_write_dispatch_dylibloader_orig_dbus +#define dbus_connection_read_write dbus_connection_read_write_dylibloader_orig_dbus +#define dbus_connection_borrow_message dbus_connection_borrow_message_dylibloader_orig_dbus +#define dbus_connection_return_message dbus_connection_return_message_dylibloader_orig_dbus +#define dbus_connection_steal_borrowed_message dbus_connection_steal_borrowed_message_dylibloader_orig_dbus +#define dbus_connection_pop_message dbus_connection_pop_message_dylibloader_orig_dbus +#define dbus_connection_get_dispatch_status dbus_connection_get_dispatch_status_dylibloader_orig_dbus +#define dbus_connection_dispatch dbus_connection_dispatch_dylibloader_orig_dbus +#define dbus_connection_has_messages_to_send dbus_connection_has_messages_to_send_dylibloader_orig_dbus +#define dbus_connection_send dbus_connection_send_dylibloader_orig_dbus +#define dbus_connection_send_with_reply dbus_connection_send_with_reply_dylibloader_orig_dbus +#define dbus_connection_send_with_reply_and_block dbus_connection_send_with_reply_and_block_dylibloader_orig_dbus +#define dbus_connection_set_watch_functions dbus_connection_set_watch_functions_dylibloader_orig_dbus +#define dbus_connection_set_timeout_functions dbus_connection_set_timeout_functions_dylibloader_orig_dbus +#define dbus_connection_set_wakeup_main_function dbus_connection_set_wakeup_main_function_dylibloader_orig_dbus +#define dbus_connection_set_dispatch_status_function dbus_connection_set_dispatch_status_function_dylibloader_orig_dbus +#define dbus_connection_get_unix_user dbus_connection_get_unix_user_dylibloader_orig_dbus +#define dbus_connection_get_unix_process_id dbus_connection_get_unix_process_id_dylibloader_orig_dbus +#define dbus_connection_get_adt_audit_session_data dbus_connection_get_adt_audit_session_data_dylibloader_orig_dbus +#define dbus_connection_set_unix_user_function dbus_connection_set_unix_user_function_dylibloader_orig_dbus +#define dbus_connection_get_windows_user dbus_connection_get_windows_user_dylibloader_orig_dbus +#define dbus_connection_set_windows_user_function dbus_connection_set_windows_user_function_dylibloader_orig_dbus +#define dbus_connection_set_allow_anonymous dbus_connection_set_allow_anonymous_dylibloader_orig_dbus +#define dbus_connection_set_route_peer_messages dbus_connection_set_route_peer_messages_dylibloader_orig_dbus +#define dbus_connection_add_filter dbus_connection_add_filter_dylibloader_orig_dbus +#define dbus_connection_remove_filter dbus_connection_remove_filter_dylibloader_orig_dbus +#define dbus_connection_allocate_data_slot dbus_connection_allocate_data_slot_dylibloader_orig_dbus +#define dbus_connection_free_data_slot dbus_connection_free_data_slot_dylibloader_orig_dbus +#define dbus_connection_set_data dbus_connection_set_data_dylibloader_orig_dbus +#define dbus_connection_get_data dbus_connection_get_data_dylibloader_orig_dbus +#define dbus_connection_set_change_sigpipe dbus_connection_set_change_sigpipe_dylibloader_orig_dbus +#define dbus_connection_set_max_message_size dbus_connection_set_max_message_size_dylibloader_orig_dbus +#define dbus_connection_get_max_message_size dbus_connection_get_max_message_size_dylibloader_orig_dbus +#define dbus_connection_set_max_received_size dbus_connection_set_max_received_size_dylibloader_orig_dbus +#define dbus_connection_get_max_received_size dbus_connection_get_max_received_size_dylibloader_orig_dbus +#define dbus_connection_set_max_message_unix_fds dbus_connection_set_max_message_unix_fds_dylibloader_orig_dbus +#define dbus_connection_get_max_message_unix_fds dbus_connection_get_max_message_unix_fds_dylibloader_orig_dbus +#define dbus_connection_set_max_received_unix_fds dbus_connection_set_max_received_unix_fds_dylibloader_orig_dbus +#define dbus_connection_get_max_received_unix_fds dbus_connection_get_max_received_unix_fds_dylibloader_orig_dbus +#define dbus_connection_get_outgoing_size dbus_connection_get_outgoing_size_dylibloader_orig_dbus +#define dbus_connection_get_outgoing_unix_fds dbus_connection_get_outgoing_unix_fds_dylibloader_orig_dbus +#define dbus_connection_preallocate_send dbus_connection_preallocate_send_dylibloader_orig_dbus +#define dbus_connection_free_preallocated_send dbus_connection_free_preallocated_send_dylibloader_orig_dbus +#define dbus_connection_send_preallocated dbus_connection_send_preallocated_dylibloader_orig_dbus +#define dbus_connection_try_register_object_path dbus_connection_try_register_object_path_dylibloader_orig_dbus +#define dbus_connection_register_object_path dbus_connection_register_object_path_dylibloader_orig_dbus +#define dbus_connection_try_register_fallback dbus_connection_try_register_fallback_dylibloader_orig_dbus +#define dbus_connection_register_fallback dbus_connection_register_fallback_dylibloader_orig_dbus +#define dbus_connection_unregister_object_path dbus_connection_unregister_object_path_dylibloader_orig_dbus +#define dbus_connection_get_object_path_data dbus_connection_get_object_path_data_dylibloader_orig_dbus +#define dbus_connection_list_registered dbus_connection_list_registered_dylibloader_orig_dbus +#define dbus_connection_get_unix_fd dbus_connection_get_unix_fd_dylibloader_orig_dbus +#define dbus_connection_get_socket dbus_connection_get_socket_dylibloader_orig_dbus +#define dbus_watch_get_fd dbus_watch_get_fd_dylibloader_orig_dbus +#define dbus_watch_get_unix_fd dbus_watch_get_unix_fd_dylibloader_orig_dbus +#define dbus_watch_get_socket dbus_watch_get_socket_dylibloader_orig_dbus +#define dbus_watch_get_flags dbus_watch_get_flags_dylibloader_orig_dbus +#define dbus_watch_get_data dbus_watch_get_data_dylibloader_orig_dbus +#define dbus_watch_set_data dbus_watch_set_data_dylibloader_orig_dbus +#define dbus_watch_handle dbus_watch_handle_dylibloader_orig_dbus +#define dbus_watch_get_enabled dbus_watch_get_enabled_dylibloader_orig_dbus +#define dbus_timeout_get_interval dbus_timeout_get_interval_dylibloader_orig_dbus +#define dbus_timeout_get_data dbus_timeout_get_data_dylibloader_orig_dbus +#define dbus_timeout_set_data dbus_timeout_set_data_dylibloader_orig_dbus +#define dbus_timeout_handle dbus_timeout_handle_dylibloader_orig_dbus +#define dbus_timeout_get_enabled dbus_timeout_get_enabled_dylibloader_orig_dbus +#define dbus_bus_get dbus_bus_get_dylibloader_orig_dbus +#define dbus_bus_get_private dbus_bus_get_private_dylibloader_orig_dbus +#define dbus_bus_register dbus_bus_register_dylibloader_orig_dbus +#define dbus_bus_set_unique_name dbus_bus_set_unique_name_dylibloader_orig_dbus +#define dbus_bus_get_unique_name dbus_bus_get_unique_name_dylibloader_orig_dbus +#define dbus_bus_get_unix_user dbus_bus_get_unix_user_dylibloader_orig_dbus +#define dbus_bus_get_id dbus_bus_get_id_dylibloader_orig_dbus +#define dbus_bus_request_name dbus_bus_request_name_dylibloader_orig_dbus +#define dbus_bus_release_name dbus_bus_release_name_dylibloader_orig_dbus +#define dbus_bus_name_has_owner dbus_bus_name_has_owner_dylibloader_orig_dbus +#define dbus_bus_start_service_by_name dbus_bus_start_service_by_name_dylibloader_orig_dbus +#define dbus_bus_add_match dbus_bus_add_match_dylibloader_orig_dbus +#define dbus_bus_remove_match dbus_bus_remove_match_dylibloader_orig_dbus +#define dbus_get_local_machine_id dbus_get_local_machine_id_dylibloader_orig_dbus +#define dbus_get_version dbus_get_version_dylibloader_orig_dbus +#define dbus_setenv dbus_setenv_dylibloader_orig_dbus +#define dbus_try_get_local_machine_id dbus_try_get_local_machine_id_dylibloader_orig_dbus +#define dbus_pending_call_ref dbus_pending_call_ref_dylibloader_orig_dbus +#define dbus_pending_call_unref dbus_pending_call_unref_dylibloader_orig_dbus +#define dbus_pending_call_set_notify dbus_pending_call_set_notify_dylibloader_orig_dbus +#define dbus_pending_call_cancel dbus_pending_call_cancel_dylibloader_orig_dbus +#define dbus_pending_call_get_completed dbus_pending_call_get_completed_dylibloader_orig_dbus +#define dbus_pending_call_steal_reply dbus_pending_call_steal_reply_dylibloader_orig_dbus +#define dbus_pending_call_block dbus_pending_call_block_dylibloader_orig_dbus +#define dbus_pending_call_allocate_data_slot dbus_pending_call_allocate_data_slot_dylibloader_orig_dbus +#define dbus_pending_call_free_data_slot dbus_pending_call_free_data_slot_dylibloader_orig_dbus +#define dbus_pending_call_set_data dbus_pending_call_set_data_dylibloader_orig_dbus +#define dbus_pending_call_get_data dbus_pending_call_get_data_dylibloader_orig_dbus +#define dbus_server_listen dbus_server_listen_dylibloader_orig_dbus +#define dbus_server_ref dbus_server_ref_dylibloader_orig_dbus +#define dbus_server_unref dbus_server_unref_dylibloader_orig_dbus +#define dbus_server_disconnect dbus_server_disconnect_dylibloader_orig_dbus +#define dbus_server_get_is_connected dbus_server_get_is_connected_dylibloader_orig_dbus +#define dbus_server_get_address dbus_server_get_address_dylibloader_orig_dbus +#define dbus_server_get_id dbus_server_get_id_dylibloader_orig_dbus +#define dbus_server_set_new_connection_function dbus_server_set_new_connection_function_dylibloader_orig_dbus +#define dbus_server_set_watch_functions dbus_server_set_watch_functions_dylibloader_orig_dbus +#define dbus_server_set_timeout_functions dbus_server_set_timeout_functions_dylibloader_orig_dbus +#define dbus_server_set_auth_mechanisms dbus_server_set_auth_mechanisms_dylibloader_orig_dbus +#define dbus_server_allocate_data_slot dbus_server_allocate_data_slot_dylibloader_orig_dbus +#define dbus_server_free_data_slot dbus_server_free_data_slot_dylibloader_orig_dbus +#define dbus_server_set_data dbus_server_set_data_dylibloader_orig_dbus +#define dbus_server_get_data dbus_server_get_data_dylibloader_orig_dbus +#define dbus_signature_iter_init dbus_signature_iter_init_dylibloader_orig_dbus +#define dbus_signature_iter_get_current_type dbus_signature_iter_get_current_type_dylibloader_orig_dbus +#define dbus_signature_iter_get_signature dbus_signature_iter_get_signature_dylibloader_orig_dbus +#define dbus_signature_iter_get_element_type dbus_signature_iter_get_element_type_dylibloader_orig_dbus +#define dbus_signature_iter_next dbus_signature_iter_next_dylibloader_orig_dbus +#define dbus_signature_iter_recurse dbus_signature_iter_recurse_dylibloader_orig_dbus +#define dbus_signature_validate dbus_signature_validate_dylibloader_orig_dbus +#define dbus_signature_validate_single dbus_signature_validate_single_dylibloader_orig_dbus +#define dbus_type_is_valid dbus_type_is_valid_dylibloader_orig_dbus +#define dbus_type_is_basic dbus_type_is_basic_dylibloader_orig_dbus +#define dbus_type_is_container dbus_type_is_container_dylibloader_orig_dbus +#define dbus_type_is_fixed dbus_type_is_fixed_dylibloader_orig_dbus +#define dbus_validate_path dbus_validate_path_dylibloader_orig_dbus +#define dbus_validate_interface dbus_validate_interface_dylibloader_orig_dbus +#define dbus_validate_member dbus_validate_member_dylibloader_orig_dbus +#define dbus_validate_error_name dbus_validate_error_name_dylibloader_orig_dbus +#define dbus_validate_bus_name dbus_validate_bus_name_dylibloader_orig_dbus +#define dbus_validate_utf8 dbus_validate_utf8_dylibloader_orig_dbus +#define dbus_threads_init dbus_threads_init_dylibloader_orig_dbus +#define dbus_threads_init_default dbus_threads_init_default_dylibloader_orig_dbus +#include <dbus/dbus.h> +#undef dbus_error_init +#undef dbus_error_free +#undef dbus_set_error +#undef dbus_set_error_const +#undef dbus_move_error +#undef dbus_error_has_name +#undef dbus_error_is_set +#undef dbus_parse_address +#undef dbus_address_entry_get_value +#undef dbus_address_entry_get_method +#undef dbus_address_entries_free +#undef dbus_address_escape_value +#undef dbus_address_unescape_value +#undef dbus_malloc +#undef dbus_malloc0 +#undef dbus_realloc +#undef dbus_free +#undef dbus_free_string_array +#undef dbus_shutdown +#undef dbus_message_new +#undef dbus_message_new_method_call +#undef dbus_message_new_method_return +#undef dbus_message_new_signal +#undef dbus_message_new_error +#undef dbus_message_new_error_printf +#undef dbus_message_copy +#undef dbus_message_ref +#undef dbus_message_unref +#undef dbus_message_get_type +#undef dbus_message_set_path +#undef dbus_message_get_path +#undef dbus_message_has_path +#undef dbus_message_set_interface +#undef dbus_message_get_interface +#undef dbus_message_has_interface +#undef dbus_message_set_member +#undef dbus_message_get_member +#undef dbus_message_has_member +#undef dbus_message_set_error_name +#undef dbus_message_get_error_name +#undef dbus_message_set_destination +#undef dbus_message_get_destination +#undef dbus_message_set_sender +#undef dbus_message_get_sender +#undef dbus_message_get_signature +#undef dbus_message_set_no_reply +#undef dbus_message_get_no_reply +#undef dbus_message_is_method_call +#undef dbus_message_is_signal +#undef dbus_message_is_error +#undef dbus_message_has_destination +#undef dbus_message_has_sender +#undef dbus_message_has_signature +#undef dbus_message_get_serial +#undef dbus_message_set_serial +#undef dbus_message_set_reply_serial +#undef dbus_message_get_reply_serial +#undef dbus_message_set_auto_start +#undef dbus_message_get_auto_start +#undef dbus_message_get_path_decomposed +#undef dbus_message_append_args +#undef dbus_message_append_args_valist +#undef dbus_message_get_args +#undef dbus_message_get_args_valist +#undef dbus_message_contains_unix_fds +#undef dbus_message_iter_init_closed +#undef dbus_message_iter_init +#undef dbus_message_iter_has_next +#undef dbus_message_iter_next +#undef dbus_message_iter_get_signature +#undef dbus_message_iter_get_arg_type +#undef dbus_message_iter_get_element_type +#undef dbus_message_iter_recurse +#undef dbus_message_iter_get_basic +#undef dbus_message_iter_get_element_count +#undef dbus_message_iter_get_array_len +#undef dbus_message_iter_get_fixed_array +#undef dbus_message_iter_init_append +#undef dbus_message_iter_append_basic +#undef dbus_message_iter_append_fixed_array +#undef dbus_message_iter_open_container +#undef dbus_message_iter_close_container +#undef dbus_message_iter_abandon_container +#undef dbus_message_iter_abandon_container_if_open +#undef dbus_message_lock +#undef dbus_set_error_from_message +#undef dbus_message_allocate_data_slot +#undef dbus_message_free_data_slot +#undef dbus_message_set_data +#undef dbus_message_get_data +#undef dbus_message_type_from_string +#undef dbus_message_type_to_string +#undef dbus_message_marshal +#undef dbus_message_demarshal +#undef dbus_message_demarshal_bytes_needed +#undef dbus_message_set_allow_interactive_authorization +#undef dbus_message_get_allow_interactive_authorization +#undef dbus_connection_open +#undef dbus_connection_open_private +#undef dbus_connection_ref +#undef dbus_connection_unref +#undef dbus_connection_close +#undef dbus_connection_get_is_connected +#undef dbus_connection_get_is_authenticated +#undef dbus_connection_get_is_anonymous +#undef dbus_connection_get_server_id +#undef dbus_connection_can_send_type +#undef dbus_connection_set_exit_on_disconnect +#undef dbus_connection_flush +#undef dbus_connection_read_write_dispatch +#undef dbus_connection_read_write +#undef dbus_connection_borrow_message +#undef dbus_connection_return_message +#undef dbus_connection_steal_borrowed_message +#undef dbus_connection_pop_message +#undef dbus_connection_get_dispatch_status +#undef dbus_connection_dispatch +#undef dbus_connection_has_messages_to_send +#undef dbus_connection_send +#undef dbus_connection_send_with_reply +#undef dbus_connection_send_with_reply_and_block +#undef dbus_connection_set_watch_functions +#undef dbus_connection_set_timeout_functions +#undef dbus_connection_set_wakeup_main_function +#undef dbus_connection_set_dispatch_status_function +#undef dbus_connection_get_unix_user +#undef dbus_connection_get_unix_process_id +#undef dbus_connection_get_adt_audit_session_data +#undef dbus_connection_set_unix_user_function +#undef dbus_connection_get_windows_user +#undef dbus_connection_set_windows_user_function +#undef dbus_connection_set_allow_anonymous +#undef dbus_connection_set_route_peer_messages +#undef dbus_connection_add_filter +#undef dbus_connection_remove_filter +#undef dbus_connection_allocate_data_slot +#undef dbus_connection_free_data_slot +#undef dbus_connection_set_data +#undef dbus_connection_get_data +#undef dbus_connection_set_change_sigpipe +#undef dbus_connection_set_max_message_size +#undef dbus_connection_get_max_message_size +#undef dbus_connection_set_max_received_size +#undef dbus_connection_get_max_received_size +#undef dbus_connection_set_max_message_unix_fds +#undef dbus_connection_get_max_message_unix_fds +#undef dbus_connection_set_max_received_unix_fds +#undef dbus_connection_get_max_received_unix_fds +#undef dbus_connection_get_outgoing_size +#undef dbus_connection_get_outgoing_unix_fds +#undef dbus_connection_preallocate_send +#undef dbus_connection_free_preallocated_send +#undef dbus_connection_send_preallocated +#undef dbus_connection_try_register_object_path +#undef dbus_connection_register_object_path +#undef dbus_connection_try_register_fallback +#undef dbus_connection_register_fallback +#undef dbus_connection_unregister_object_path +#undef dbus_connection_get_object_path_data +#undef dbus_connection_list_registered +#undef dbus_connection_get_unix_fd +#undef dbus_connection_get_socket +#undef dbus_watch_get_fd +#undef dbus_watch_get_unix_fd +#undef dbus_watch_get_socket +#undef dbus_watch_get_flags +#undef dbus_watch_get_data +#undef dbus_watch_set_data +#undef dbus_watch_handle +#undef dbus_watch_get_enabled +#undef dbus_timeout_get_interval +#undef dbus_timeout_get_data +#undef dbus_timeout_set_data +#undef dbus_timeout_handle +#undef dbus_timeout_get_enabled +#undef dbus_bus_get +#undef dbus_bus_get_private +#undef dbus_bus_register +#undef dbus_bus_set_unique_name +#undef dbus_bus_get_unique_name +#undef dbus_bus_get_unix_user +#undef dbus_bus_get_id +#undef dbus_bus_request_name +#undef dbus_bus_release_name +#undef dbus_bus_name_has_owner +#undef dbus_bus_start_service_by_name +#undef dbus_bus_add_match +#undef dbus_bus_remove_match +#undef dbus_get_local_machine_id +#undef dbus_get_version +#undef dbus_setenv +#undef dbus_try_get_local_machine_id +#undef dbus_pending_call_ref +#undef dbus_pending_call_unref +#undef dbus_pending_call_set_notify +#undef dbus_pending_call_cancel +#undef dbus_pending_call_get_completed +#undef dbus_pending_call_steal_reply +#undef dbus_pending_call_block +#undef dbus_pending_call_allocate_data_slot +#undef dbus_pending_call_free_data_slot +#undef dbus_pending_call_set_data +#undef dbus_pending_call_get_data +#undef dbus_server_listen +#undef dbus_server_ref +#undef dbus_server_unref +#undef dbus_server_disconnect +#undef dbus_server_get_is_connected +#undef dbus_server_get_address +#undef dbus_server_get_id +#undef dbus_server_set_new_connection_function +#undef dbus_server_set_watch_functions +#undef dbus_server_set_timeout_functions +#undef dbus_server_set_auth_mechanisms +#undef dbus_server_allocate_data_slot +#undef dbus_server_free_data_slot +#undef dbus_server_set_data +#undef dbus_server_get_data +#undef dbus_signature_iter_init +#undef dbus_signature_iter_get_current_type +#undef dbus_signature_iter_get_signature +#undef dbus_signature_iter_get_element_type +#undef dbus_signature_iter_next +#undef dbus_signature_iter_recurse +#undef dbus_signature_validate +#undef dbus_signature_validate_single +#undef dbus_type_is_valid +#undef dbus_type_is_basic +#undef dbus_type_is_container +#undef dbus_type_is_fixed +#undef dbus_validate_path +#undef dbus_validate_interface +#undef dbus_validate_member +#undef dbus_validate_error_name +#undef dbus_validate_bus_name +#undef dbus_validate_utf8 +#undef dbus_threads_init +#undef dbus_threads_init_default +#ifdef __cplusplus +extern "C" { +#endif +#define dbus_error_init dbus_error_init_dylibloader_wrapper_dbus +#define dbus_error_free dbus_error_free_dylibloader_wrapper_dbus +#define dbus_set_error dbus_set_error_dylibloader_wrapper_dbus +#define dbus_set_error_const dbus_set_error_const_dylibloader_wrapper_dbus +#define dbus_move_error dbus_move_error_dylibloader_wrapper_dbus +#define dbus_error_has_name dbus_error_has_name_dylibloader_wrapper_dbus +#define dbus_error_is_set dbus_error_is_set_dylibloader_wrapper_dbus +#define dbus_parse_address dbus_parse_address_dylibloader_wrapper_dbus +#define dbus_address_entry_get_value dbus_address_entry_get_value_dylibloader_wrapper_dbus +#define dbus_address_entry_get_method dbus_address_entry_get_method_dylibloader_wrapper_dbus +#define dbus_address_entries_free dbus_address_entries_free_dylibloader_wrapper_dbus +#define dbus_address_escape_value dbus_address_escape_value_dylibloader_wrapper_dbus +#define dbus_address_unescape_value dbus_address_unescape_value_dylibloader_wrapper_dbus +#define dbus_malloc dbus_malloc_dylibloader_wrapper_dbus +#define dbus_malloc0 dbus_malloc0_dylibloader_wrapper_dbus +#define dbus_realloc dbus_realloc_dylibloader_wrapper_dbus +#define dbus_free dbus_free_dylibloader_wrapper_dbus +#define dbus_free_string_array dbus_free_string_array_dylibloader_wrapper_dbus +#define dbus_shutdown dbus_shutdown_dylibloader_wrapper_dbus +#define dbus_message_new dbus_message_new_dylibloader_wrapper_dbus +#define dbus_message_new_method_call dbus_message_new_method_call_dylibloader_wrapper_dbus +#define dbus_message_new_method_return dbus_message_new_method_return_dylibloader_wrapper_dbus +#define dbus_message_new_signal dbus_message_new_signal_dylibloader_wrapper_dbus +#define dbus_message_new_error dbus_message_new_error_dylibloader_wrapper_dbus +#define dbus_message_new_error_printf dbus_message_new_error_printf_dylibloader_wrapper_dbus +#define dbus_message_copy dbus_message_copy_dylibloader_wrapper_dbus +#define dbus_message_ref dbus_message_ref_dylibloader_wrapper_dbus +#define dbus_message_unref dbus_message_unref_dylibloader_wrapper_dbus +#define dbus_message_get_type dbus_message_get_type_dylibloader_wrapper_dbus +#define dbus_message_set_path dbus_message_set_path_dylibloader_wrapper_dbus +#define dbus_message_get_path dbus_message_get_path_dylibloader_wrapper_dbus +#define dbus_message_has_path dbus_message_has_path_dylibloader_wrapper_dbus +#define dbus_message_set_interface dbus_message_set_interface_dylibloader_wrapper_dbus +#define dbus_message_get_interface dbus_message_get_interface_dylibloader_wrapper_dbus +#define dbus_message_has_interface dbus_message_has_interface_dylibloader_wrapper_dbus +#define dbus_message_set_member dbus_message_set_member_dylibloader_wrapper_dbus +#define dbus_message_get_member dbus_message_get_member_dylibloader_wrapper_dbus +#define dbus_message_has_member dbus_message_has_member_dylibloader_wrapper_dbus +#define dbus_message_set_error_name dbus_message_set_error_name_dylibloader_wrapper_dbus +#define dbus_message_get_error_name dbus_message_get_error_name_dylibloader_wrapper_dbus +#define dbus_message_set_destination dbus_message_set_destination_dylibloader_wrapper_dbus +#define dbus_message_get_destination dbus_message_get_destination_dylibloader_wrapper_dbus +#define dbus_message_set_sender dbus_message_set_sender_dylibloader_wrapper_dbus +#define dbus_message_get_sender dbus_message_get_sender_dylibloader_wrapper_dbus +#define dbus_message_get_signature dbus_message_get_signature_dylibloader_wrapper_dbus +#define dbus_message_set_no_reply dbus_message_set_no_reply_dylibloader_wrapper_dbus +#define dbus_message_get_no_reply dbus_message_get_no_reply_dylibloader_wrapper_dbus +#define dbus_message_is_method_call dbus_message_is_method_call_dylibloader_wrapper_dbus +#define dbus_message_is_signal dbus_message_is_signal_dylibloader_wrapper_dbus +#define dbus_message_is_error dbus_message_is_error_dylibloader_wrapper_dbus +#define dbus_message_has_destination dbus_message_has_destination_dylibloader_wrapper_dbus +#define dbus_message_has_sender dbus_message_has_sender_dylibloader_wrapper_dbus +#define dbus_message_has_signature dbus_message_has_signature_dylibloader_wrapper_dbus +#define dbus_message_get_serial dbus_message_get_serial_dylibloader_wrapper_dbus +#define dbus_message_set_serial dbus_message_set_serial_dylibloader_wrapper_dbus +#define dbus_message_set_reply_serial dbus_message_set_reply_serial_dylibloader_wrapper_dbus +#define dbus_message_get_reply_serial dbus_message_get_reply_serial_dylibloader_wrapper_dbus +#define dbus_message_set_auto_start dbus_message_set_auto_start_dylibloader_wrapper_dbus +#define dbus_message_get_auto_start dbus_message_get_auto_start_dylibloader_wrapper_dbus +#define dbus_message_get_path_decomposed dbus_message_get_path_decomposed_dylibloader_wrapper_dbus +#define dbus_message_append_args dbus_message_append_args_dylibloader_wrapper_dbus +#define dbus_message_append_args_valist dbus_message_append_args_valist_dylibloader_wrapper_dbus +#define dbus_message_get_args dbus_message_get_args_dylibloader_wrapper_dbus +#define dbus_message_get_args_valist dbus_message_get_args_valist_dylibloader_wrapper_dbus +#define dbus_message_contains_unix_fds dbus_message_contains_unix_fds_dylibloader_wrapper_dbus +#define dbus_message_iter_init_closed dbus_message_iter_init_closed_dylibloader_wrapper_dbus +#define dbus_message_iter_init dbus_message_iter_init_dylibloader_wrapper_dbus +#define dbus_message_iter_has_next dbus_message_iter_has_next_dylibloader_wrapper_dbus +#define dbus_message_iter_next dbus_message_iter_next_dylibloader_wrapper_dbus +#define dbus_message_iter_get_signature dbus_message_iter_get_signature_dylibloader_wrapper_dbus +#define dbus_message_iter_get_arg_type dbus_message_iter_get_arg_type_dylibloader_wrapper_dbus +#define dbus_message_iter_get_element_type dbus_message_iter_get_element_type_dylibloader_wrapper_dbus +#define dbus_message_iter_recurse dbus_message_iter_recurse_dylibloader_wrapper_dbus +#define dbus_message_iter_get_basic dbus_message_iter_get_basic_dylibloader_wrapper_dbus +#define dbus_message_iter_get_element_count dbus_message_iter_get_element_count_dylibloader_wrapper_dbus +#define dbus_message_iter_get_array_len dbus_message_iter_get_array_len_dylibloader_wrapper_dbus +#define dbus_message_iter_get_fixed_array dbus_message_iter_get_fixed_array_dylibloader_wrapper_dbus +#define dbus_message_iter_init_append dbus_message_iter_init_append_dylibloader_wrapper_dbus +#define dbus_message_iter_append_basic dbus_message_iter_append_basic_dylibloader_wrapper_dbus +#define dbus_message_iter_append_fixed_array dbus_message_iter_append_fixed_array_dylibloader_wrapper_dbus +#define dbus_message_iter_open_container dbus_message_iter_open_container_dylibloader_wrapper_dbus +#define dbus_message_iter_close_container dbus_message_iter_close_container_dylibloader_wrapper_dbus +#define dbus_message_iter_abandon_container dbus_message_iter_abandon_container_dylibloader_wrapper_dbus +#define dbus_message_iter_abandon_container_if_open dbus_message_iter_abandon_container_if_open_dylibloader_wrapper_dbus +#define dbus_message_lock dbus_message_lock_dylibloader_wrapper_dbus +#define dbus_set_error_from_message dbus_set_error_from_message_dylibloader_wrapper_dbus +#define dbus_message_allocate_data_slot dbus_message_allocate_data_slot_dylibloader_wrapper_dbus +#define dbus_message_free_data_slot dbus_message_free_data_slot_dylibloader_wrapper_dbus +#define dbus_message_set_data dbus_message_set_data_dylibloader_wrapper_dbus +#define dbus_message_get_data dbus_message_get_data_dylibloader_wrapper_dbus +#define dbus_message_type_from_string dbus_message_type_from_string_dylibloader_wrapper_dbus +#define dbus_message_type_to_string dbus_message_type_to_string_dylibloader_wrapper_dbus +#define dbus_message_marshal dbus_message_marshal_dylibloader_wrapper_dbus +#define dbus_message_demarshal dbus_message_demarshal_dylibloader_wrapper_dbus +#define dbus_message_demarshal_bytes_needed dbus_message_demarshal_bytes_needed_dylibloader_wrapper_dbus +#define dbus_message_set_allow_interactive_authorization dbus_message_set_allow_interactive_authorization_dylibloader_wrapper_dbus +#define dbus_message_get_allow_interactive_authorization dbus_message_get_allow_interactive_authorization_dylibloader_wrapper_dbus +#define dbus_connection_open dbus_connection_open_dylibloader_wrapper_dbus +#define dbus_connection_open_private dbus_connection_open_private_dylibloader_wrapper_dbus +#define dbus_connection_ref dbus_connection_ref_dylibloader_wrapper_dbus +#define dbus_connection_unref dbus_connection_unref_dylibloader_wrapper_dbus +#define dbus_connection_close dbus_connection_close_dylibloader_wrapper_dbus +#define dbus_connection_get_is_connected dbus_connection_get_is_connected_dylibloader_wrapper_dbus +#define dbus_connection_get_is_authenticated dbus_connection_get_is_authenticated_dylibloader_wrapper_dbus +#define dbus_connection_get_is_anonymous dbus_connection_get_is_anonymous_dylibloader_wrapper_dbus +#define dbus_connection_get_server_id dbus_connection_get_server_id_dylibloader_wrapper_dbus +#define dbus_connection_can_send_type dbus_connection_can_send_type_dylibloader_wrapper_dbus +#define dbus_connection_set_exit_on_disconnect dbus_connection_set_exit_on_disconnect_dylibloader_wrapper_dbus +#define dbus_connection_flush dbus_connection_flush_dylibloader_wrapper_dbus +#define dbus_connection_read_write_dispatch dbus_connection_read_write_dispatch_dylibloader_wrapper_dbus +#define dbus_connection_read_write dbus_connection_read_write_dylibloader_wrapper_dbus +#define dbus_connection_borrow_message dbus_connection_borrow_message_dylibloader_wrapper_dbus +#define dbus_connection_return_message dbus_connection_return_message_dylibloader_wrapper_dbus +#define dbus_connection_steal_borrowed_message dbus_connection_steal_borrowed_message_dylibloader_wrapper_dbus +#define dbus_connection_pop_message dbus_connection_pop_message_dylibloader_wrapper_dbus +#define dbus_connection_get_dispatch_status dbus_connection_get_dispatch_status_dylibloader_wrapper_dbus +#define dbus_connection_dispatch dbus_connection_dispatch_dylibloader_wrapper_dbus +#define dbus_connection_has_messages_to_send dbus_connection_has_messages_to_send_dylibloader_wrapper_dbus +#define dbus_connection_send dbus_connection_send_dylibloader_wrapper_dbus +#define dbus_connection_send_with_reply dbus_connection_send_with_reply_dylibloader_wrapper_dbus +#define dbus_connection_send_with_reply_and_block dbus_connection_send_with_reply_and_block_dylibloader_wrapper_dbus +#define dbus_connection_set_watch_functions dbus_connection_set_watch_functions_dylibloader_wrapper_dbus +#define dbus_connection_set_timeout_functions dbus_connection_set_timeout_functions_dylibloader_wrapper_dbus +#define dbus_connection_set_wakeup_main_function dbus_connection_set_wakeup_main_function_dylibloader_wrapper_dbus +#define dbus_connection_set_dispatch_status_function dbus_connection_set_dispatch_status_function_dylibloader_wrapper_dbus +#define dbus_connection_get_unix_user dbus_connection_get_unix_user_dylibloader_wrapper_dbus +#define dbus_connection_get_unix_process_id dbus_connection_get_unix_process_id_dylibloader_wrapper_dbus +#define dbus_connection_get_adt_audit_session_data dbus_connection_get_adt_audit_session_data_dylibloader_wrapper_dbus +#define dbus_connection_set_unix_user_function dbus_connection_set_unix_user_function_dylibloader_wrapper_dbus +#define dbus_connection_get_windows_user dbus_connection_get_windows_user_dylibloader_wrapper_dbus +#define dbus_connection_set_windows_user_function dbus_connection_set_windows_user_function_dylibloader_wrapper_dbus +#define dbus_connection_set_allow_anonymous dbus_connection_set_allow_anonymous_dylibloader_wrapper_dbus +#define dbus_connection_set_route_peer_messages dbus_connection_set_route_peer_messages_dylibloader_wrapper_dbus +#define dbus_connection_add_filter dbus_connection_add_filter_dylibloader_wrapper_dbus +#define dbus_connection_remove_filter dbus_connection_remove_filter_dylibloader_wrapper_dbus +#define dbus_connection_allocate_data_slot dbus_connection_allocate_data_slot_dylibloader_wrapper_dbus +#define dbus_connection_free_data_slot dbus_connection_free_data_slot_dylibloader_wrapper_dbus +#define dbus_connection_set_data dbus_connection_set_data_dylibloader_wrapper_dbus +#define dbus_connection_get_data dbus_connection_get_data_dylibloader_wrapper_dbus +#define dbus_connection_set_change_sigpipe dbus_connection_set_change_sigpipe_dylibloader_wrapper_dbus +#define dbus_connection_set_max_message_size dbus_connection_set_max_message_size_dylibloader_wrapper_dbus +#define dbus_connection_get_max_message_size dbus_connection_get_max_message_size_dylibloader_wrapper_dbus +#define dbus_connection_set_max_received_size dbus_connection_set_max_received_size_dylibloader_wrapper_dbus +#define dbus_connection_get_max_received_size dbus_connection_get_max_received_size_dylibloader_wrapper_dbus +#define dbus_connection_set_max_message_unix_fds dbus_connection_set_max_message_unix_fds_dylibloader_wrapper_dbus +#define dbus_connection_get_max_message_unix_fds dbus_connection_get_max_message_unix_fds_dylibloader_wrapper_dbus +#define dbus_connection_set_max_received_unix_fds dbus_connection_set_max_received_unix_fds_dylibloader_wrapper_dbus +#define dbus_connection_get_max_received_unix_fds dbus_connection_get_max_received_unix_fds_dylibloader_wrapper_dbus +#define dbus_connection_get_outgoing_size dbus_connection_get_outgoing_size_dylibloader_wrapper_dbus +#define dbus_connection_get_outgoing_unix_fds dbus_connection_get_outgoing_unix_fds_dylibloader_wrapper_dbus +#define dbus_connection_preallocate_send dbus_connection_preallocate_send_dylibloader_wrapper_dbus +#define dbus_connection_free_preallocated_send dbus_connection_free_preallocated_send_dylibloader_wrapper_dbus +#define dbus_connection_send_preallocated dbus_connection_send_preallocated_dylibloader_wrapper_dbus +#define dbus_connection_try_register_object_path dbus_connection_try_register_object_path_dylibloader_wrapper_dbus +#define dbus_connection_register_object_path dbus_connection_register_object_path_dylibloader_wrapper_dbus +#define dbus_connection_try_register_fallback dbus_connection_try_register_fallback_dylibloader_wrapper_dbus +#define dbus_connection_register_fallback dbus_connection_register_fallback_dylibloader_wrapper_dbus +#define dbus_connection_unregister_object_path dbus_connection_unregister_object_path_dylibloader_wrapper_dbus +#define dbus_connection_get_object_path_data dbus_connection_get_object_path_data_dylibloader_wrapper_dbus +#define dbus_connection_list_registered dbus_connection_list_registered_dylibloader_wrapper_dbus +#define dbus_connection_get_unix_fd dbus_connection_get_unix_fd_dylibloader_wrapper_dbus +#define dbus_connection_get_socket dbus_connection_get_socket_dylibloader_wrapper_dbus +#define dbus_watch_get_fd dbus_watch_get_fd_dylibloader_wrapper_dbus +#define dbus_watch_get_unix_fd dbus_watch_get_unix_fd_dylibloader_wrapper_dbus +#define dbus_watch_get_socket dbus_watch_get_socket_dylibloader_wrapper_dbus +#define dbus_watch_get_flags dbus_watch_get_flags_dylibloader_wrapper_dbus +#define dbus_watch_get_data dbus_watch_get_data_dylibloader_wrapper_dbus +#define dbus_watch_set_data dbus_watch_set_data_dylibloader_wrapper_dbus +#define dbus_watch_handle dbus_watch_handle_dylibloader_wrapper_dbus +#define dbus_watch_get_enabled dbus_watch_get_enabled_dylibloader_wrapper_dbus +#define dbus_timeout_get_interval dbus_timeout_get_interval_dylibloader_wrapper_dbus +#define dbus_timeout_get_data dbus_timeout_get_data_dylibloader_wrapper_dbus +#define dbus_timeout_set_data dbus_timeout_set_data_dylibloader_wrapper_dbus +#define dbus_timeout_handle dbus_timeout_handle_dylibloader_wrapper_dbus +#define dbus_timeout_get_enabled dbus_timeout_get_enabled_dylibloader_wrapper_dbus +#define dbus_bus_get dbus_bus_get_dylibloader_wrapper_dbus +#define dbus_bus_get_private dbus_bus_get_private_dylibloader_wrapper_dbus +#define dbus_bus_register dbus_bus_register_dylibloader_wrapper_dbus +#define dbus_bus_set_unique_name dbus_bus_set_unique_name_dylibloader_wrapper_dbus +#define dbus_bus_get_unique_name dbus_bus_get_unique_name_dylibloader_wrapper_dbus +#define dbus_bus_get_unix_user dbus_bus_get_unix_user_dylibloader_wrapper_dbus +#define dbus_bus_get_id dbus_bus_get_id_dylibloader_wrapper_dbus +#define dbus_bus_request_name dbus_bus_request_name_dylibloader_wrapper_dbus +#define dbus_bus_release_name dbus_bus_release_name_dylibloader_wrapper_dbus +#define dbus_bus_name_has_owner dbus_bus_name_has_owner_dylibloader_wrapper_dbus +#define dbus_bus_start_service_by_name dbus_bus_start_service_by_name_dylibloader_wrapper_dbus +#define dbus_bus_add_match dbus_bus_add_match_dylibloader_wrapper_dbus +#define dbus_bus_remove_match dbus_bus_remove_match_dylibloader_wrapper_dbus +#define dbus_get_local_machine_id dbus_get_local_machine_id_dylibloader_wrapper_dbus +#define dbus_get_version dbus_get_version_dylibloader_wrapper_dbus +#define dbus_setenv dbus_setenv_dylibloader_wrapper_dbus +#define dbus_try_get_local_machine_id dbus_try_get_local_machine_id_dylibloader_wrapper_dbus +#define dbus_pending_call_ref dbus_pending_call_ref_dylibloader_wrapper_dbus +#define dbus_pending_call_unref dbus_pending_call_unref_dylibloader_wrapper_dbus +#define dbus_pending_call_set_notify dbus_pending_call_set_notify_dylibloader_wrapper_dbus +#define dbus_pending_call_cancel dbus_pending_call_cancel_dylibloader_wrapper_dbus +#define dbus_pending_call_get_completed dbus_pending_call_get_completed_dylibloader_wrapper_dbus +#define dbus_pending_call_steal_reply dbus_pending_call_steal_reply_dylibloader_wrapper_dbus +#define dbus_pending_call_block dbus_pending_call_block_dylibloader_wrapper_dbus +#define dbus_pending_call_allocate_data_slot dbus_pending_call_allocate_data_slot_dylibloader_wrapper_dbus +#define dbus_pending_call_free_data_slot dbus_pending_call_free_data_slot_dylibloader_wrapper_dbus +#define dbus_pending_call_set_data dbus_pending_call_set_data_dylibloader_wrapper_dbus +#define dbus_pending_call_get_data dbus_pending_call_get_data_dylibloader_wrapper_dbus +#define dbus_server_listen dbus_server_listen_dylibloader_wrapper_dbus +#define dbus_server_ref dbus_server_ref_dylibloader_wrapper_dbus +#define dbus_server_unref dbus_server_unref_dylibloader_wrapper_dbus +#define dbus_server_disconnect dbus_server_disconnect_dylibloader_wrapper_dbus +#define dbus_server_get_is_connected dbus_server_get_is_connected_dylibloader_wrapper_dbus +#define dbus_server_get_address dbus_server_get_address_dylibloader_wrapper_dbus +#define dbus_server_get_id dbus_server_get_id_dylibloader_wrapper_dbus +#define dbus_server_set_new_connection_function dbus_server_set_new_connection_function_dylibloader_wrapper_dbus +#define dbus_server_set_watch_functions dbus_server_set_watch_functions_dylibloader_wrapper_dbus +#define dbus_server_set_timeout_functions dbus_server_set_timeout_functions_dylibloader_wrapper_dbus +#define dbus_server_set_auth_mechanisms dbus_server_set_auth_mechanisms_dylibloader_wrapper_dbus +#define dbus_server_allocate_data_slot dbus_server_allocate_data_slot_dylibloader_wrapper_dbus +#define dbus_server_free_data_slot dbus_server_free_data_slot_dylibloader_wrapper_dbus +#define dbus_server_set_data dbus_server_set_data_dylibloader_wrapper_dbus +#define dbus_server_get_data dbus_server_get_data_dylibloader_wrapper_dbus +#define dbus_signature_iter_init dbus_signature_iter_init_dylibloader_wrapper_dbus +#define dbus_signature_iter_get_current_type dbus_signature_iter_get_current_type_dylibloader_wrapper_dbus +#define dbus_signature_iter_get_signature dbus_signature_iter_get_signature_dylibloader_wrapper_dbus +#define dbus_signature_iter_get_element_type dbus_signature_iter_get_element_type_dylibloader_wrapper_dbus +#define dbus_signature_iter_next dbus_signature_iter_next_dylibloader_wrapper_dbus +#define dbus_signature_iter_recurse dbus_signature_iter_recurse_dylibloader_wrapper_dbus +#define dbus_signature_validate dbus_signature_validate_dylibloader_wrapper_dbus +#define dbus_signature_validate_single dbus_signature_validate_single_dylibloader_wrapper_dbus +#define dbus_type_is_valid dbus_type_is_valid_dylibloader_wrapper_dbus +#define dbus_type_is_basic dbus_type_is_basic_dylibloader_wrapper_dbus +#define dbus_type_is_container dbus_type_is_container_dylibloader_wrapper_dbus +#define dbus_type_is_fixed dbus_type_is_fixed_dylibloader_wrapper_dbus +#define dbus_validate_path dbus_validate_path_dylibloader_wrapper_dbus +#define dbus_validate_interface dbus_validate_interface_dylibloader_wrapper_dbus +#define dbus_validate_member dbus_validate_member_dylibloader_wrapper_dbus +#define dbus_validate_error_name dbus_validate_error_name_dylibloader_wrapper_dbus +#define dbus_validate_bus_name dbus_validate_bus_name_dylibloader_wrapper_dbus +#define dbus_validate_utf8 dbus_validate_utf8_dylibloader_wrapper_dbus +#define dbus_threads_init dbus_threads_init_dylibloader_wrapper_dbus +#define dbus_threads_init_default dbus_threads_init_default_dylibloader_wrapper_dbus +extern void (*dbus_error_init_dylibloader_wrapper_dbus)( DBusError*); +extern void (*dbus_error_free_dylibloader_wrapper_dbus)( DBusError*); +extern void (*dbus_set_error_dylibloader_wrapper_dbus)( DBusError*,const char*,const char*,...); +extern void (*dbus_set_error_const_dylibloader_wrapper_dbus)( DBusError*,const char*,const char*); +extern void (*dbus_move_error_dylibloader_wrapper_dbus)( DBusError*, DBusError*); +extern dbus_bool_t (*dbus_error_has_name_dylibloader_wrapper_dbus)(const DBusError*,const char*); +extern dbus_bool_t (*dbus_error_is_set_dylibloader_wrapper_dbus)(const DBusError*); +extern dbus_bool_t (*dbus_parse_address_dylibloader_wrapper_dbus)(const char*, DBusAddressEntry***, int*, DBusError*); +extern const char* (*dbus_address_entry_get_value_dylibloader_wrapper_dbus)( DBusAddressEntry*,const char*); +extern const char* (*dbus_address_entry_get_method_dylibloader_wrapper_dbus)( DBusAddressEntry*); +extern void (*dbus_address_entries_free_dylibloader_wrapper_dbus)( DBusAddressEntry**); +extern char* (*dbus_address_escape_value_dylibloader_wrapper_dbus)(const char*); +extern char* (*dbus_address_unescape_value_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern void* (*dbus_malloc_dylibloader_wrapper_dbus)( size_t); +extern void* (*dbus_malloc0_dylibloader_wrapper_dbus)( size_t); +extern void* (*dbus_realloc_dylibloader_wrapper_dbus)( void*, size_t); +extern void (*dbus_free_dylibloader_wrapper_dbus)( void*); +extern void (*dbus_free_string_array_dylibloader_wrapper_dbus)( char**); +extern void (*dbus_shutdown_dylibloader_wrapper_dbus)( void); +extern DBusMessage* (*dbus_message_new_dylibloader_wrapper_dbus)( int); +extern DBusMessage* (*dbus_message_new_method_call_dylibloader_wrapper_dbus)(const char*,const char*,const char*,const char*); +extern DBusMessage* (*dbus_message_new_method_return_dylibloader_wrapper_dbus)( DBusMessage*); +extern DBusMessage* (*dbus_message_new_signal_dylibloader_wrapper_dbus)(const char*,const char*,const char*); +extern DBusMessage* (*dbus_message_new_error_dylibloader_wrapper_dbus)( DBusMessage*,const char*,const char*); +extern DBusMessage* (*dbus_message_new_error_printf_dylibloader_wrapper_dbus)( DBusMessage*,const char*,const char*,...); +extern DBusMessage* (*dbus_message_copy_dylibloader_wrapper_dbus)(const DBusMessage*); +extern DBusMessage* (*dbus_message_ref_dylibloader_wrapper_dbus)( DBusMessage*); +extern void (*dbus_message_unref_dylibloader_wrapper_dbus)( DBusMessage*); +extern int (*dbus_message_get_type_dylibloader_wrapper_dbus)( DBusMessage*); +extern dbus_bool_t (*dbus_message_set_path_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern const char* (*dbus_message_get_path_dylibloader_wrapper_dbus)( DBusMessage*); +extern dbus_bool_t (*dbus_message_has_path_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern dbus_bool_t (*dbus_message_set_interface_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern const char* (*dbus_message_get_interface_dylibloader_wrapper_dbus)( DBusMessage*); +extern dbus_bool_t (*dbus_message_has_interface_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern dbus_bool_t (*dbus_message_set_member_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern const char* (*dbus_message_get_member_dylibloader_wrapper_dbus)( DBusMessage*); +extern dbus_bool_t (*dbus_message_has_member_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern dbus_bool_t (*dbus_message_set_error_name_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern const char* (*dbus_message_get_error_name_dylibloader_wrapper_dbus)( DBusMessage*); +extern dbus_bool_t (*dbus_message_set_destination_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern const char* (*dbus_message_get_destination_dylibloader_wrapper_dbus)( DBusMessage*); +extern dbus_bool_t (*dbus_message_set_sender_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern const char* (*dbus_message_get_sender_dylibloader_wrapper_dbus)( DBusMessage*); +extern const char* (*dbus_message_get_signature_dylibloader_wrapper_dbus)( DBusMessage*); +extern void (*dbus_message_set_no_reply_dylibloader_wrapper_dbus)( DBusMessage*, dbus_bool_t); +extern dbus_bool_t (*dbus_message_get_no_reply_dylibloader_wrapper_dbus)( DBusMessage*); +extern dbus_bool_t (*dbus_message_is_method_call_dylibloader_wrapper_dbus)( DBusMessage*,const char*,const char*); +extern dbus_bool_t (*dbus_message_is_signal_dylibloader_wrapper_dbus)( DBusMessage*,const char*,const char*); +extern dbus_bool_t (*dbus_message_is_error_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern dbus_bool_t (*dbus_message_has_destination_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern dbus_bool_t (*dbus_message_has_sender_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern dbus_bool_t (*dbus_message_has_signature_dylibloader_wrapper_dbus)( DBusMessage*,const char*); +extern dbus_uint32_t (*dbus_message_get_serial_dylibloader_wrapper_dbus)( DBusMessage*); +extern void (*dbus_message_set_serial_dylibloader_wrapper_dbus)( DBusMessage*, dbus_uint32_t); +extern dbus_bool_t (*dbus_message_set_reply_serial_dylibloader_wrapper_dbus)( DBusMessage*, dbus_uint32_t); +extern dbus_uint32_t (*dbus_message_get_reply_serial_dylibloader_wrapper_dbus)( DBusMessage*); +extern void (*dbus_message_set_auto_start_dylibloader_wrapper_dbus)( DBusMessage*, dbus_bool_t); +extern dbus_bool_t (*dbus_message_get_auto_start_dylibloader_wrapper_dbus)( DBusMessage*); +extern dbus_bool_t (*dbus_message_get_path_decomposed_dylibloader_wrapper_dbus)( DBusMessage*, char***); +extern dbus_bool_t (*dbus_message_append_args_dylibloader_wrapper_dbus)( DBusMessage*, int,...); +extern dbus_bool_t (*dbus_message_append_args_valist_dylibloader_wrapper_dbus)( DBusMessage*, int, va_list); +extern dbus_bool_t (*dbus_message_get_args_dylibloader_wrapper_dbus)( DBusMessage*, DBusError*, int,...); +extern dbus_bool_t (*dbus_message_get_args_valist_dylibloader_wrapper_dbus)( DBusMessage*, DBusError*, int, va_list); +extern dbus_bool_t (*dbus_message_contains_unix_fds_dylibloader_wrapper_dbus)( DBusMessage*); +extern void (*dbus_message_iter_init_closed_dylibloader_wrapper_dbus)( DBusMessageIter*); +extern dbus_bool_t (*dbus_message_iter_init_dylibloader_wrapper_dbus)( DBusMessage*, DBusMessageIter*); +extern dbus_bool_t (*dbus_message_iter_has_next_dylibloader_wrapper_dbus)( DBusMessageIter*); +extern dbus_bool_t (*dbus_message_iter_next_dylibloader_wrapper_dbus)( DBusMessageIter*); +extern char* (*dbus_message_iter_get_signature_dylibloader_wrapper_dbus)( DBusMessageIter*); +extern int (*dbus_message_iter_get_arg_type_dylibloader_wrapper_dbus)( DBusMessageIter*); +extern int (*dbus_message_iter_get_element_type_dylibloader_wrapper_dbus)( DBusMessageIter*); +extern void (*dbus_message_iter_recurse_dylibloader_wrapper_dbus)( DBusMessageIter*, DBusMessageIter*); +extern void (*dbus_message_iter_get_basic_dylibloader_wrapper_dbus)( DBusMessageIter*, void*); +extern int (*dbus_message_iter_get_element_count_dylibloader_wrapper_dbus)( DBusMessageIter*); +extern int (*dbus_message_iter_get_array_len_dylibloader_wrapper_dbus)( DBusMessageIter*); +extern void (*dbus_message_iter_get_fixed_array_dylibloader_wrapper_dbus)( DBusMessageIter*, void*, int*); +extern void (*dbus_message_iter_init_append_dylibloader_wrapper_dbus)( DBusMessage*, DBusMessageIter*); +extern dbus_bool_t (*dbus_message_iter_append_basic_dylibloader_wrapper_dbus)( DBusMessageIter*, int,const void*); +extern dbus_bool_t (*dbus_message_iter_append_fixed_array_dylibloader_wrapper_dbus)( DBusMessageIter*, int,const void*, int); +extern dbus_bool_t (*dbus_message_iter_open_container_dylibloader_wrapper_dbus)( DBusMessageIter*, int,const char*, DBusMessageIter*); +extern dbus_bool_t (*dbus_message_iter_close_container_dylibloader_wrapper_dbus)( DBusMessageIter*, DBusMessageIter*); +extern void (*dbus_message_iter_abandon_container_dylibloader_wrapper_dbus)( DBusMessageIter*, DBusMessageIter*); +extern void (*dbus_message_iter_abandon_container_if_open_dylibloader_wrapper_dbus)( DBusMessageIter*, DBusMessageIter*); +extern void (*dbus_message_lock_dylibloader_wrapper_dbus)( DBusMessage*); +extern dbus_bool_t (*dbus_set_error_from_message_dylibloader_wrapper_dbus)( DBusError*, DBusMessage*); +extern dbus_bool_t (*dbus_message_allocate_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +extern void (*dbus_message_free_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +extern dbus_bool_t (*dbus_message_set_data_dylibloader_wrapper_dbus)( DBusMessage*, dbus_int32_t, void*, DBusFreeFunction); +extern void* (*dbus_message_get_data_dylibloader_wrapper_dbus)( DBusMessage*, dbus_int32_t); +extern int (*dbus_message_type_from_string_dylibloader_wrapper_dbus)(const char*); +extern const char* (*dbus_message_type_to_string_dylibloader_wrapper_dbus)( int); +extern dbus_bool_t (*dbus_message_marshal_dylibloader_wrapper_dbus)( DBusMessage*, char**, int*); +extern DBusMessage* (*dbus_message_demarshal_dylibloader_wrapper_dbus)(const char*, int, DBusError*); +extern int (*dbus_message_demarshal_bytes_needed_dylibloader_wrapper_dbus)(const char*, int); +extern void (*dbus_message_set_allow_interactive_authorization_dylibloader_wrapper_dbus)( DBusMessage*, dbus_bool_t); +extern dbus_bool_t (*dbus_message_get_allow_interactive_authorization_dylibloader_wrapper_dbus)( DBusMessage*); +extern DBusConnection* (*dbus_connection_open_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern DBusConnection* (*dbus_connection_open_private_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern DBusConnection* (*dbus_connection_ref_dylibloader_wrapper_dbus)( DBusConnection*); +extern void (*dbus_connection_unref_dylibloader_wrapper_dbus)( DBusConnection*); +extern void (*dbus_connection_close_dylibloader_wrapper_dbus)( DBusConnection*); +extern dbus_bool_t (*dbus_connection_get_is_connected_dylibloader_wrapper_dbus)( DBusConnection*); +extern dbus_bool_t (*dbus_connection_get_is_authenticated_dylibloader_wrapper_dbus)( DBusConnection*); +extern dbus_bool_t (*dbus_connection_get_is_anonymous_dylibloader_wrapper_dbus)( DBusConnection*); +extern char* (*dbus_connection_get_server_id_dylibloader_wrapper_dbus)( DBusConnection*); +extern dbus_bool_t (*dbus_connection_can_send_type_dylibloader_wrapper_dbus)( DBusConnection*, int); +extern void (*dbus_connection_set_exit_on_disconnect_dylibloader_wrapper_dbus)( DBusConnection*, dbus_bool_t); +extern void (*dbus_connection_flush_dylibloader_wrapper_dbus)( DBusConnection*); +extern dbus_bool_t (*dbus_connection_read_write_dispatch_dylibloader_wrapper_dbus)( DBusConnection*, int); +extern dbus_bool_t (*dbus_connection_read_write_dylibloader_wrapper_dbus)( DBusConnection*, int); +extern DBusMessage* (*dbus_connection_borrow_message_dylibloader_wrapper_dbus)( DBusConnection*); +extern void (*dbus_connection_return_message_dylibloader_wrapper_dbus)( DBusConnection*, DBusMessage*); +extern void (*dbus_connection_steal_borrowed_message_dylibloader_wrapper_dbus)( DBusConnection*, DBusMessage*); +extern DBusMessage* (*dbus_connection_pop_message_dylibloader_wrapper_dbus)( DBusConnection*); +extern DBusDispatchStatus (*dbus_connection_get_dispatch_status_dylibloader_wrapper_dbus)( DBusConnection*); +extern DBusDispatchStatus (*dbus_connection_dispatch_dylibloader_wrapper_dbus)( DBusConnection*); +extern dbus_bool_t (*dbus_connection_has_messages_to_send_dylibloader_wrapper_dbus)( DBusConnection*); +extern dbus_bool_t (*dbus_connection_send_dylibloader_wrapper_dbus)( DBusConnection*, DBusMessage*, dbus_uint32_t*); +extern dbus_bool_t (*dbus_connection_send_with_reply_dylibloader_wrapper_dbus)( DBusConnection*, DBusMessage*, DBusPendingCall**, int); +extern DBusMessage* (*dbus_connection_send_with_reply_and_block_dylibloader_wrapper_dbus)( DBusConnection*, DBusMessage*, int, DBusError*); +extern dbus_bool_t (*dbus_connection_set_watch_functions_dylibloader_wrapper_dbus)( DBusConnection*, DBusAddWatchFunction, DBusRemoveWatchFunction, DBusWatchToggledFunction, void*, DBusFreeFunction); +extern dbus_bool_t (*dbus_connection_set_timeout_functions_dylibloader_wrapper_dbus)( DBusConnection*, DBusAddTimeoutFunction, DBusRemoveTimeoutFunction, DBusTimeoutToggledFunction, void*, DBusFreeFunction); +extern void (*dbus_connection_set_wakeup_main_function_dylibloader_wrapper_dbus)( DBusConnection*, DBusWakeupMainFunction, void*, DBusFreeFunction); +extern void (*dbus_connection_set_dispatch_status_function_dylibloader_wrapper_dbus)( DBusConnection*, DBusDispatchStatusFunction, void*, DBusFreeFunction); +extern dbus_bool_t (*dbus_connection_get_unix_user_dylibloader_wrapper_dbus)( DBusConnection*, unsigned long*); +extern dbus_bool_t (*dbus_connection_get_unix_process_id_dylibloader_wrapper_dbus)( DBusConnection*, unsigned long*); +extern dbus_bool_t (*dbus_connection_get_adt_audit_session_data_dylibloader_wrapper_dbus)( DBusConnection*, void**, dbus_int32_t*); +extern void (*dbus_connection_set_unix_user_function_dylibloader_wrapper_dbus)( DBusConnection*, DBusAllowUnixUserFunction, void*, DBusFreeFunction); +extern dbus_bool_t (*dbus_connection_get_windows_user_dylibloader_wrapper_dbus)( DBusConnection*, char**); +extern void (*dbus_connection_set_windows_user_function_dylibloader_wrapper_dbus)( DBusConnection*, DBusAllowWindowsUserFunction, void*, DBusFreeFunction); +extern void (*dbus_connection_set_allow_anonymous_dylibloader_wrapper_dbus)( DBusConnection*, dbus_bool_t); +extern void (*dbus_connection_set_route_peer_messages_dylibloader_wrapper_dbus)( DBusConnection*, dbus_bool_t); +extern dbus_bool_t (*dbus_connection_add_filter_dylibloader_wrapper_dbus)( DBusConnection*, DBusHandleMessageFunction, void*, DBusFreeFunction); +extern void (*dbus_connection_remove_filter_dylibloader_wrapper_dbus)( DBusConnection*, DBusHandleMessageFunction, void*); +extern dbus_bool_t (*dbus_connection_allocate_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +extern void (*dbus_connection_free_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +extern dbus_bool_t (*dbus_connection_set_data_dylibloader_wrapper_dbus)( DBusConnection*, dbus_int32_t, void*, DBusFreeFunction); +extern void* (*dbus_connection_get_data_dylibloader_wrapper_dbus)( DBusConnection*, dbus_int32_t); +extern void (*dbus_connection_set_change_sigpipe_dylibloader_wrapper_dbus)( dbus_bool_t); +extern void (*dbus_connection_set_max_message_size_dylibloader_wrapper_dbus)( DBusConnection*, long); +extern long (*dbus_connection_get_max_message_size_dylibloader_wrapper_dbus)( DBusConnection*); +extern void (*dbus_connection_set_max_received_size_dylibloader_wrapper_dbus)( DBusConnection*, long); +extern long (*dbus_connection_get_max_received_size_dylibloader_wrapper_dbus)( DBusConnection*); +extern void (*dbus_connection_set_max_message_unix_fds_dylibloader_wrapper_dbus)( DBusConnection*, long); +extern long (*dbus_connection_get_max_message_unix_fds_dylibloader_wrapper_dbus)( DBusConnection*); +extern void (*dbus_connection_set_max_received_unix_fds_dylibloader_wrapper_dbus)( DBusConnection*, long); +extern long (*dbus_connection_get_max_received_unix_fds_dylibloader_wrapper_dbus)( DBusConnection*); +extern long (*dbus_connection_get_outgoing_size_dylibloader_wrapper_dbus)( DBusConnection*); +extern long (*dbus_connection_get_outgoing_unix_fds_dylibloader_wrapper_dbus)( DBusConnection*); +extern DBusPreallocatedSend* (*dbus_connection_preallocate_send_dylibloader_wrapper_dbus)( DBusConnection*); +extern void (*dbus_connection_free_preallocated_send_dylibloader_wrapper_dbus)( DBusConnection*, DBusPreallocatedSend*); +extern void (*dbus_connection_send_preallocated_dylibloader_wrapper_dbus)( DBusConnection*, DBusPreallocatedSend*, DBusMessage*, dbus_uint32_t*); +extern dbus_bool_t (*dbus_connection_try_register_object_path_dylibloader_wrapper_dbus)( DBusConnection*,const char*,const DBusObjectPathVTable*, void*, DBusError*); +extern dbus_bool_t (*dbus_connection_register_object_path_dylibloader_wrapper_dbus)( DBusConnection*,const char*,const DBusObjectPathVTable*, void*); +extern dbus_bool_t (*dbus_connection_try_register_fallback_dylibloader_wrapper_dbus)( DBusConnection*,const char*,const DBusObjectPathVTable*, void*, DBusError*); +extern dbus_bool_t (*dbus_connection_register_fallback_dylibloader_wrapper_dbus)( DBusConnection*,const char*,const DBusObjectPathVTable*, void*); +extern dbus_bool_t (*dbus_connection_unregister_object_path_dylibloader_wrapper_dbus)( DBusConnection*,const char*); +extern dbus_bool_t (*dbus_connection_get_object_path_data_dylibloader_wrapper_dbus)( DBusConnection*,const char*, void**); +extern dbus_bool_t (*dbus_connection_list_registered_dylibloader_wrapper_dbus)( DBusConnection*,const char*, char***); +extern dbus_bool_t (*dbus_connection_get_unix_fd_dylibloader_wrapper_dbus)( DBusConnection*, int*); +extern dbus_bool_t (*dbus_connection_get_socket_dylibloader_wrapper_dbus)( DBusConnection*, int*); +extern int (*dbus_watch_get_fd_dylibloader_wrapper_dbus)( DBusWatch*); +extern int (*dbus_watch_get_unix_fd_dylibloader_wrapper_dbus)( DBusWatch*); +extern int (*dbus_watch_get_socket_dylibloader_wrapper_dbus)( DBusWatch*); +extern unsigned int (*dbus_watch_get_flags_dylibloader_wrapper_dbus)( DBusWatch*); +extern void* (*dbus_watch_get_data_dylibloader_wrapper_dbus)( DBusWatch*); +extern void (*dbus_watch_set_data_dylibloader_wrapper_dbus)( DBusWatch*, void*, DBusFreeFunction); +extern dbus_bool_t (*dbus_watch_handle_dylibloader_wrapper_dbus)( DBusWatch*, unsigned int); +extern dbus_bool_t (*dbus_watch_get_enabled_dylibloader_wrapper_dbus)( DBusWatch*); +extern int (*dbus_timeout_get_interval_dylibloader_wrapper_dbus)( DBusTimeout*); +extern void* (*dbus_timeout_get_data_dylibloader_wrapper_dbus)( DBusTimeout*); +extern void (*dbus_timeout_set_data_dylibloader_wrapper_dbus)( DBusTimeout*, void*, DBusFreeFunction); +extern dbus_bool_t (*dbus_timeout_handle_dylibloader_wrapper_dbus)( DBusTimeout*); +extern dbus_bool_t (*dbus_timeout_get_enabled_dylibloader_wrapper_dbus)( DBusTimeout*); +extern DBusConnection* (*dbus_bus_get_dylibloader_wrapper_dbus)( DBusBusType, DBusError*); +extern DBusConnection* (*dbus_bus_get_private_dylibloader_wrapper_dbus)( DBusBusType, DBusError*); +extern dbus_bool_t (*dbus_bus_register_dylibloader_wrapper_dbus)( DBusConnection*, DBusError*); +extern dbus_bool_t (*dbus_bus_set_unique_name_dylibloader_wrapper_dbus)( DBusConnection*,const char*); +extern const char* (*dbus_bus_get_unique_name_dylibloader_wrapper_dbus)( DBusConnection*); +extern unsigned long (*dbus_bus_get_unix_user_dylibloader_wrapper_dbus)( DBusConnection*,const char*, DBusError*); +extern char* (*dbus_bus_get_id_dylibloader_wrapper_dbus)( DBusConnection*, DBusError*); +extern int (*dbus_bus_request_name_dylibloader_wrapper_dbus)( DBusConnection*,const char*, unsigned int, DBusError*); +extern int (*dbus_bus_release_name_dylibloader_wrapper_dbus)( DBusConnection*,const char*, DBusError*); +extern dbus_bool_t (*dbus_bus_name_has_owner_dylibloader_wrapper_dbus)( DBusConnection*,const char*, DBusError*); +extern dbus_bool_t (*dbus_bus_start_service_by_name_dylibloader_wrapper_dbus)( DBusConnection*,const char*, dbus_uint32_t, dbus_uint32_t*, DBusError*); +extern void (*dbus_bus_add_match_dylibloader_wrapper_dbus)( DBusConnection*,const char*, DBusError*); +extern void (*dbus_bus_remove_match_dylibloader_wrapper_dbus)( DBusConnection*,const char*, DBusError*); +extern char* (*dbus_get_local_machine_id_dylibloader_wrapper_dbus)( void); +extern void (*dbus_get_version_dylibloader_wrapper_dbus)( int*, int*, int*); +extern dbus_bool_t (*dbus_setenv_dylibloader_wrapper_dbus)(const char*,const char*); +extern char* (*dbus_try_get_local_machine_id_dylibloader_wrapper_dbus)( DBusError*); +extern DBusPendingCall* (*dbus_pending_call_ref_dylibloader_wrapper_dbus)( DBusPendingCall*); +extern void (*dbus_pending_call_unref_dylibloader_wrapper_dbus)( DBusPendingCall*); +extern dbus_bool_t (*dbus_pending_call_set_notify_dylibloader_wrapper_dbus)( DBusPendingCall*, DBusPendingCallNotifyFunction, void*, DBusFreeFunction); +extern void (*dbus_pending_call_cancel_dylibloader_wrapper_dbus)( DBusPendingCall*); +extern dbus_bool_t (*dbus_pending_call_get_completed_dylibloader_wrapper_dbus)( DBusPendingCall*); +extern DBusMessage* (*dbus_pending_call_steal_reply_dylibloader_wrapper_dbus)( DBusPendingCall*); +extern void (*dbus_pending_call_block_dylibloader_wrapper_dbus)( DBusPendingCall*); +extern dbus_bool_t (*dbus_pending_call_allocate_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +extern void (*dbus_pending_call_free_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +extern dbus_bool_t (*dbus_pending_call_set_data_dylibloader_wrapper_dbus)( DBusPendingCall*, dbus_int32_t, void*, DBusFreeFunction); +extern void* (*dbus_pending_call_get_data_dylibloader_wrapper_dbus)( DBusPendingCall*, dbus_int32_t); +extern DBusServer* (*dbus_server_listen_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern DBusServer* (*dbus_server_ref_dylibloader_wrapper_dbus)( DBusServer*); +extern void (*dbus_server_unref_dylibloader_wrapper_dbus)( DBusServer*); +extern void (*dbus_server_disconnect_dylibloader_wrapper_dbus)( DBusServer*); +extern dbus_bool_t (*dbus_server_get_is_connected_dylibloader_wrapper_dbus)( DBusServer*); +extern char* (*dbus_server_get_address_dylibloader_wrapper_dbus)( DBusServer*); +extern char* (*dbus_server_get_id_dylibloader_wrapper_dbus)( DBusServer*); +extern void (*dbus_server_set_new_connection_function_dylibloader_wrapper_dbus)( DBusServer*, DBusNewConnectionFunction, void*, DBusFreeFunction); +extern dbus_bool_t (*dbus_server_set_watch_functions_dylibloader_wrapper_dbus)( DBusServer*, DBusAddWatchFunction, DBusRemoveWatchFunction, DBusWatchToggledFunction, void*, DBusFreeFunction); +extern dbus_bool_t (*dbus_server_set_timeout_functions_dylibloader_wrapper_dbus)( DBusServer*, DBusAddTimeoutFunction, DBusRemoveTimeoutFunction, DBusTimeoutToggledFunction, void*, DBusFreeFunction); +extern dbus_bool_t (*dbus_server_set_auth_mechanisms_dylibloader_wrapper_dbus)( DBusServer*,const char**); +extern dbus_bool_t (*dbus_server_allocate_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +extern void (*dbus_server_free_data_slot_dylibloader_wrapper_dbus)( dbus_int32_t*); +extern dbus_bool_t (*dbus_server_set_data_dylibloader_wrapper_dbus)( DBusServer*, int, void*, DBusFreeFunction); +extern void* (*dbus_server_get_data_dylibloader_wrapper_dbus)( DBusServer*, int); +extern void (*dbus_signature_iter_init_dylibloader_wrapper_dbus)( DBusSignatureIter*,const char*); +extern int (*dbus_signature_iter_get_current_type_dylibloader_wrapper_dbus)(const DBusSignatureIter*); +extern char* (*dbus_signature_iter_get_signature_dylibloader_wrapper_dbus)(const DBusSignatureIter*); +extern int (*dbus_signature_iter_get_element_type_dylibloader_wrapper_dbus)(const DBusSignatureIter*); +extern dbus_bool_t (*dbus_signature_iter_next_dylibloader_wrapper_dbus)( DBusSignatureIter*); +extern void (*dbus_signature_iter_recurse_dylibloader_wrapper_dbus)(const DBusSignatureIter*, DBusSignatureIter*); +extern dbus_bool_t (*dbus_signature_validate_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern dbus_bool_t (*dbus_signature_validate_single_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern dbus_bool_t (*dbus_type_is_valid_dylibloader_wrapper_dbus)( int); +extern dbus_bool_t (*dbus_type_is_basic_dylibloader_wrapper_dbus)( int); +extern dbus_bool_t (*dbus_type_is_container_dylibloader_wrapper_dbus)( int); +extern dbus_bool_t (*dbus_type_is_fixed_dylibloader_wrapper_dbus)( int); +extern dbus_bool_t (*dbus_validate_path_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern dbus_bool_t (*dbus_validate_interface_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern dbus_bool_t (*dbus_validate_member_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern dbus_bool_t (*dbus_validate_error_name_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern dbus_bool_t (*dbus_validate_bus_name_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern dbus_bool_t (*dbus_validate_utf8_dylibloader_wrapper_dbus)(const char*, DBusError*); +extern dbus_bool_t (*dbus_threads_init_dylibloader_wrapper_dbus)(const DBusThreadFunctions*); +extern dbus_bool_t (*dbus_threads_init_default_dylibloader_wrapper_dbus)( void); +int initialize_dbus(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 065250c40e..00e2b9e6eb 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -41,6 +41,7 @@ def get_opts(): BoolVariable("pulseaudio", "Detect and use PulseAudio", True), BoolVariable("dbus", "Detect and use D-Bus to handle screensaver", True), BoolVariable("speechd", "Detect and use Speech Dispatcher for Text-to-Speech support", True), + BoolVariable("fontconfig", "Detect and use fontconfig for system fonts support", True), BoolVariable("udev", "Use udev for gamepad connection callbacks", True), BoolVariable("x11", "Enable X11 display", True), BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True), @@ -298,6 +299,14 @@ def configure(env): ## Flags + if env["fontconfig"]: + if os.system("pkg-config --exists fontconfig") == 0: # 0 means found + env.Append(CPPDEFINES=["FONTCONFIG_ENABLED"]) + env.ParseConfig("pkg-config fontconfig --cflags") # Only cflags, we dlopen the library. + else: + env["fontconfig"] = False + print("Warning: fontconfig libraries not found. Disabling the system fonts support.") + if os.system("pkg-config --exists alsa") == 0: # 0 means found env["alsa"] = True env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) @@ -316,8 +325,9 @@ def configure(env): if env["dbus"]: if os.system("pkg-config --exists dbus-1") == 0: # 0 means found env.Append(CPPDEFINES=["DBUS_ENABLED"]) - env.ParseConfig("pkg-config dbus-1 --cflags --libs") + env.ParseConfig("pkg-config dbus-1 --cflags") # Only cflags, we dlopen the library. else: + env["dbus"] = False print("Warning: D-Bus development libraries not found. Disabling screensaver prevention.") if env["speechd"]: diff --git a/platform/linuxbsd/detect_prime_x11.cpp b/platform/linuxbsd/detect_prime_x11.cpp index 42b7f68a5e..fb833ab5e6 100644 --- a/platform/linuxbsd/detect_prime_x11.cpp +++ b/platform/linuxbsd/detect_prime_x11.cpp @@ -177,6 +177,11 @@ int detect_prime() { } else { // In child, exit() here will not quit the engine. + // Prevent false leak reports as we will not be properly + // cleaning up these processes, and fork() makes a copy + // of all globals. + CoreGlobals::leak_reporting_enabled = false; + char string[201]; close(fdset[0]); diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index d4267d3c02..8efbd2e3c5 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -3147,7 +3147,7 @@ void DisplayServerX11::_window_changed(XEvent *event) { Variant *rectp = ▭ Variant ret; Callable::CallError ce; - wd.rect_changed_callback.call((const Variant **)&rectp, 1, ret, ce); + wd.rect_changed_callback.callp((const Variant **)&rectp, 1, ret, ce); } } @@ -3168,7 +3168,7 @@ void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) { if (windows.has(E->get())) { Callable callable = windows[E->get()].input_event_callback; if (callable.is_valid()) { - callable.call((const Variant **)&evp, 1, ret, ce); + callable.callp((const Variant **)&evp, 1, ret, ce); } } return; @@ -3181,7 +3181,7 @@ void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) { if (windows.has(event_from_window->get_window_id())) { Callable callable = windows[event_from_window->get_window_id()].input_event_callback; if (callable.is_valid()) { - callable.call((const Variant **)&evp, 1, ret, ce); + callable.callp((const Variant **)&evp, 1, ret, ce); } } } else { @@ -3189,7 +3189,7 @@ void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) { for (KeyValue<WindowID, WindowData> &E : windows) { Callable callable = E.value.input_event_callback; if (callable.is_valid()) { - callable.call((const Variant **)&evp, 1, ret, ce); + callable.callp((const Variant **)&evp, 1, ret, ce); } } } @@ -3201,7 +3201,7 @@ void DisplayServerX11::_send_window_event(const WindowData &wd, WindowEvent p_ev Variant *eventp = &event; Variant ret; Callable::CallError ce; - wd.event_callback.call((const Variant **)&eventp, 1, ret, ce); + wd.event_callback.callp((const Variant **)&eventp, 1, ret, ce); } } @@ -4068,7 +4068,7 @@ void DisplayServerX11::process_events() { Variant *vp = &v; Variant ret; Callable::CallError ce; - windows[window_id].drop_files_callback.call((const Variant **)&vp, 1, ret, ce); + windows[window_id].drop_files_callback.callp((const Variant **)&vp, 1, ret, ce); } //Reply that all is well. @@ -4991,7 +4991,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode #ifdef DBUS_ENABLED screensaver = memnew(FreeDesktopScreenSaver); - screen_set_keep_on(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true)); + screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); #endif r_error = OK; diff --git a/platform/linuxbsd/export/export.cpp b/platform/linuxbsd/export/export.cpp index 4240e9adc0..990351d13f 100644 --- a/platform/linuxbsd/export/export.cpp +++ b/platform/linuxbsd/export/export.cpp @@ -30,6 +30,7 @@ #include "export.h" +#include "editor/export/editor_export.h" #include "export_plugin.h" void register_linuxbsd_exporter() { @@ -37,8 +38,6 @@ void register_linuxbsd_exporter() { platform.instantiate(); platform->set_logo(ImageTexture::create_from_image(memnew(Image(_linuxbsd_logo)))); platform->set_name("Linux/X11"); - platform->set_extension("x86_32"); - platform->set_extension("x86_64", "binary_format/64_bits"); platform->set_os_name("Linux"); platform->set_chmod_flags(0755); diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp index d54e07d8a5..4d45d3ba12 100644 --- a/platform/linuxbsd/export/export_plugin.cpp +++ b/platform/linuxbsd/export/export_plugin.cpp @@ -79,31 +79,21 @@ Error EditorExportPlatformLinuxBSD::export_project(const Ref<EditorExportPreset> return err; } -void EditorExportPlatformLinuxBSD::set_extension(const String &p_extension, const String &p_feature_key) { - extensions[p_feature_key] = p_extension; -} - String EditorExportPlatformLinuxBSD::get_template_file_name(const String &p_target, const String &p_arch) const { return "linux_" + p_target + "." + p_arch; } List<String> EditorExportPlatformLinuxBSD::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { List<String> list; - for (const KeyValue<String, String> &E : extensions) { - if (p_preset->get(E.key)) { - list.push_back(extensions[E.key]); - return list; - } - } - - if (extensions.has("default")) { - list.push_back(extensions["default"]); - return list; - } - + list.push_back(p_preset->get("binary_format/architecture")); return list; } +void EditorExportPlatformLinuxBSD::get_export_options(List<ExportOption> *r_options) { + EditorExportPlatformPC::get_export_options(r_options); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "x86_64,x86_32,arm64,arm32,rv64,ppc64,ppc32"), "x86_64")); +} + Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { // Patch the header of the "pck" section in the ELF file so that it corresponds to the embedded data diff --git a/platform/linuxbsd/export/export_plugin.h b/platform/linuxbsd/export/export_plugin.h index ccdf2ecc9f..4d6737498b 100644 --- a/platform/linuxbsd/export/export_plugin.h +++ b/platform/linuxbsd/export/export_plugin.h @@ -32,18 +32,18 @@ #define LINUXBSD_EXPORT_PLUGIN_H #include "core/io/file_access.h" -#include "editor/editor_export.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export_platform_pc.h" #include "platform/linuxbsd/logo.gen.h" #include "scene/resources/texture.h" class EditorExportPlatformLinuxBSD : public EditorExportPlatformPC { - HashMap<String, String> extensions; Error _export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path); public: void set_extension(const String &p_extension, const String &p_feature_key = "default"); virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override; + virtual void get_export_options(List<ExportOption> *r_options) override; virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; virtual String get_template_file_name(const String &p_target, const String &p_arch) const override; virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) override; diff --git a/platform/linuxbsd/fontconfig-so_wrap.c b/platform/linuxbsd/fontconfig-so_wrap.c new file mode 100644 index 0000000000..1a915faf98 --- /dev/null +++ b/platform/linuxbsd/fontconfig-so_wrap.c @@ -0,0 +1,2091 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by ./generate-wrapper.py 0.3 on 2022-07-29 05:40:07 +// flags: ./generate-wrapper.py --include /usr/include/fontconfig/fontconfig.h --sys-include <fontconfig/fontconfig.h> --soname libfontconfig.so --init-name fontconfig --output-header fontconfig-so_wrap.h --output-implementation fontconfig-so_wrap.c --omit-prefix FcCharSet +// +#include <stdint.h> + +#define FcBlanksCreate FcBlanksCreate_dylibloader_orig_fontconfig +#define FcBlanksDestroy FcBlanksDestroy_dylibloader_orig_fontconfig +#define FcBlanksAdd FcBlanksAdd_dylibloader_orig_fontconfig +#define FcBlanksIsMember FcBlanksIsMember_dylibloader_orig_fontconfig +#define FcCacheDir FcCacheDir_dylibloader_orig_fontconfig +#define FcCacheCopySet FcCacheCopySet_dylibloader_orig_fontconfig +#define FcCacheSubdir FcCacheSubdir_dylibloader_orig_fontconfig +#define FcCacheNumSubdir FcCacheNumSubdir_dylibloader_orig_fontconfig +#define FcCacheNumFont FcCacheNumFont_dylibloader_orig_fontconfig +#define FcDirCacheUnlink FcDirCacheUnlink_dylibloader_orig_fontconfig +#define FcDirCacheValid FcDirCacheValid_dylibloader_orig_fontconfig +#define FcDirCacheClean FcDirCacheClean_dylibloader_orig_fontconfig +#define FcCacheCreateTagFile FcCacheCreateTagFile_dylibloader_orig_fontconfig +#define FcConfigHome FcConfigHome_dylibloader_orig_fontconfig +#define FcConfigEnableHome FcConfigEnableHome_dylibloader_orig_fontconfig +#define FcConfigFilename FcConfigFilename_dylibloader_orig_fontconfig +#define FcConfigCreate FcConfigCreate_dylibloader_orig_fontconfig +#define FcConfigReference FcConfigReference_dylibloader_orig_fontconfig +#define FcConfigDestroy FcConfigDestroy_dylibloader_orig_fontconfig +#define FcConfigSetCurrent FcConfigSetCurrent_dylibloader_orig_fontconfig +#define FcConfigGetCurrent FcConfigGetCurrent_dylibloader_orig_fontconfig +#define FcConfigUptoDate FcConfigUptoDate_dylibloader_orig_fontconfig +#define FcConfigBuildFonts FcConfigBuildFonts_dylibloader_orig_fontconfig +#define FcConfigGetFontDirs FcConfigGetFontDirs_dylibloader_orig_fontconfig +#define FcConfigGetConfigDirs FcConfigGetConfigDirs_dylibloader_orig_fontconfig +#define FcConfigGetConfigFiles FcConfigGetConfigFiles_dylibloader_orig_fontconfig +#define FcConfigGetCache FcConfigGetCache_dylibloader_orig_fontconfig +#define FcConfigGetBlanks FcConfigGetBlanks_dylibloader_orig_fontconfig +#define FcConfigGetCacheDirs FcConfigGetCacheDirs_dylibloader_orig_fontconfig +#define FcConfigGetRescanInterval FcConfigGetRescanInterval_dylibloader_orig_fontconfig +#define FcConfigSetRescanInterval FcConfigSetRescanInterval_dylibloader_orig_fontconfig +#define FcConfigGetFonts FcConfigGetFonts_dylibloader_orig_fontconfig +#define FcConfigAppFontAddFile FcConfigAppFontAddFile_dylibloader_orig_fontconfig +#define FcConfigAppFontAddDir FcConfigAppFontAddDir_dylibloader_orig_fontconfig +#define FcConfigAppFontClear FcConfigAppFontClear_dylibloader_orig_fontconfig +#define FcConfigSubstituteWithPat FcConfigSubstituteWithPat_dylibloader_orig_fontconfig +#define FcConfigSubstitute FcConfigSubstitute_dylibloader_orig_fontconfig +#define FcConfigGetSysRoot FcConfigGetSysRoot_dylibloader_orig_fontconfig +#define FcConfigSetSysRoot FcConfigSetSysRoot_dylibloader_orig_fontconfig +#define FcValuePrint FcValuePrint_dylibloader_orig_fontconfig +#define FcPatternPrint FcPatternPrint_dylibloader_orig_fontconfig +#define FcFontSetPrint FcFontSetPrint_dylibloader_orig_fontconfig +#define FcGetDefaultLangs FcGetDefaultLangs_dylibloader_orig_fontconfig +#define FcDefaultSubstitute FcDefaultSubstitute_dylibloader_orig_fontconfig +#define FcFileIsDir FcFileIsDir_dylibloader_orig_fontconfig +#define FcFileScan FcFileScan_dylibloader_orig_fontconfig +#define FcDirScan FcDirScan_dylibloader_orig_fontconfig +#define FcDirSave FcDirSave_dylibloader_orig_fontconfig +#define FcDirCacheLoad FcDirCacheLoad_dylibloader_orig_fontconfig +#define FcDirCacheRescan FcDirCacheRescan_dylibloader_orig_fontconfig +#define FcDirCacheRead FcDirCacheRead_dylibloader_orig_fontconfig +#define FcDirCacheLoadFile FcDirCacheLoadFile_dylibloader_orig_fontconfig +#define FcDirCacheUnload FcDirCacheUnload_dylibloader_orig_fontconfig +#define FcFreeTypeQuery FcFreeTypeQuery_dylibloader_orig_fontconfig +#define FcFontSetCreate FcFontSetCreate_dylibloader_orig_fontconfig +#define FcFontSetDestroy FcFontSetDestroy_dylibloader_orig_fontconfig +#define FcFontSetAdd FcFontSetAdd_dylibloader_orig_fontconfig +#define FcInitLoadConfig FcInitLoadConfig_dylibloader_orig_fontconfig +#define FcInitLoadConfigAndFonts FcInitLoadConfigAndFonts_dylibloader_orig_fontconfig +#define FcInit FcInit_dylibloader_orig_fontconfig +#define FcFini FcFini_dylibloader_orig_fontconfig +#define FcGetVersion FcGetVersion_dylibloader_orig_fontconfig +#define FcInitReinitialize FcInitReinitialize_dylibloader_orig_fontconfig +#define FcInitBringUptoDate FcInitBringUptoDate_dylibloader_orig_fontconfig +#define FcGetLangs FcGetLangs_dylibloader_orig_fontconfig +#define FcLangNormalize FcLangNormalize_dylibloader_orig_fontconfig +#define FcLangGetCharSet FcLangGetCharSet_dylibloader_orig_fontconfig +#define FcLangSetCreate FcLangSetCreate_dylibloader_orig_fontconfig +#define FcLangSetDestroy FcLangSetDestroy_dylibloader_orig_fontconfig +#define FcLangSetCopy FcLangSetCopy_dylibloader_orig_fontconfig +#define FcLangSetAdd FcLangSetAdd_dylibloader_orig_fontconfig +#define FcLangSetDel FcLangSetDel_dylibloader_orig_fontconfig +#define FcLangSetHasLang FcLangSetHasLang_dylibloader_orig_fontconfig +#define FcLangSetCompare FcLangSetCompare_dylibloader_orig_fontconfig +#define FcLangSetContains FcLangSetContains_dylibloader_orig_fontconfig +#define FcLangSetEqual FcLangSetEqual_dylibloader_orig_fontconfig +#define FcLangSetHash FcLangSetHash_dylibloader_orig_fontconfig +#define FcLangSetGetLangs FcLangSetGetLangs_dylibloader_orig_fontconfig +#define FcLangSetUnion FcLangSetUnion_dylibloader_orig_fontconfig +#define FcLangSetSubtract FcLangSetSubtract_dylibloader_orig_fontconfig +#define FcObjectSetCreate FcObjectSetCreate_dylibloader_orig_fontconfig +#define FcObjectSetAdd FcObjectSetAdd_dylibloader_orig_fontconfig +#define FcObjectSetDestroy FcObjectSetDestroy_dylibloader_orig_fontconfig +#define FcObjectSetVaBuild FcObjectSetVaBuild_dylibloader_orig_fontconfig +#define FcObjectSetBuild FcObjectSetBuild_dylibloader_orig_fontconfig +#define FcFontSetList FcFontSetList_dylibloader_orig_fontconfig +#define FcFontList FcFontList_dylibloader_orig_fontconfig +#define FcAtomicCreate FcAtomicCreate_dylibloader_orig_fontconfig +#define FcAtomicLock FcAtomicLock_dylibloader_orig_fontconfig +#define FcAtomicNewFile FcAtomicNewFile_dylibloader_orig_fontconfig +#define FcAtomicOrigFile FcAtomicOrigFile_dylibloader_orig_fontconfig +#define FcAtomicReplaceOrig FcAtomicReplaceOrig_dylibloader_orig_fontconfig +#define FcAtomicDeleteNew FcAtomicDeleteNew_dylibloader_orig_fontconfig +#define FcAtomicUnlock FcAtomicUnlock_dylibloader_orig_fontconfig +#define FcAtomicDestroy FcAtomicDestroy_dylibloader_orig_fontconfig +#define FcFontSetMatch FcFontSetMatch_dylibloader_orig_fontconfig +#define FcFontMatch FcFontMatch_dylibloader_orig_fontconfig +#define FcFontRenderPrepare FcFontRenderPrepare_dylibloader_orig_fontconfig +#define FcFontSetSort FcFontSetSort_dylibloader_orig_fontconfig +#define FcFontSort FcFontSort_dylibloader_orig_fontconfig +#define FcFontSetSortDestroy FcFontSetSortDestroy_dylibloader_orig_fontconfig +#define FcMatrixCopy FcMatrixCopy_dylibloader_orig_fontconfig +#define FcMatrixEqual FcMatrixEqual_dylibloader_orig_fontconfig +#define FcMatrixMultiply FcMatrixMultiply_dylibloader_orig_fontconfig +#define FcMatrixRotate FcMatrixRotate_dylibloader_orig_fontconfig +#define FcMatrixScale FcMatrixScale_dylibloader_orig_fontconfig +#define FcMatrixShear FcMatrixShear_dylibloader_orig_fontconfig +#define FcNameRegisterObjectTypes FcNameRegisterObjectTypes_dylibloader_orig_fontconfig +#define FcNameUnregisterObjectTypes FcNameUnregisterObjectTypes_dylibloader_orig_fontconfig +#define FcNameGetObjectType FcNameGetObjectType_dylibloader_orig_fontconfig +#define FcNameRegisterConstants FcNameRegisterConstants_dylibloader_orig_fontconfig +#define FcNameUnregisterConstants FcNameUnregisterConstants_dylibloader_orig_fontconfig +#define FcNameGetConstant FcNameGetConstant_dylibloader_orig_fontconfig +#define FcNameConstant FcNameConstant_dylibloader_orig_fontconfig +#define FcNameParse FcNameParse_dylibloader_orig_fontconfig +#define FcNameUnparse FcNameUnparse_dylibloader_orig_fontconfig +#define FcPatternCreate FcPatternCreate_dylibloader_orig_fontconfig +#define FcPatternDuplicate FcPatternDuplicate_dylibloader_orig_fontconfig +#define FcPatternReference FcPatternReference_dylibloader_orig_fontconfig +#define FcPatternFilter FcPatternFilter_dylibloader_orig_fontconfig +#define FcValueDestroy FcValueDestroy_dylibloader_orig_fontconfig +#define FcValueEqual FcValueEqual_dylibloader_orig_fontconfig +#define FcValueSave FcValueSave_dylibloader_orig_fontconfig +#define FcPatternDestroy FcPatternDestroy_dylibloader_orig_fontconfig +#define FcPatternEqual FcPatternEqual_dylibloader_orig_fontconfig +#define FcPatternEqualSubset FcPatternEqualSubset_dylibloader_orig_fontconfig +#define FcPatternHash FcPatternHash_dylibloader_orig_fontconfig +#define FcPatternAdd FcPatternAdd_dylibloader_orig_fontconfig +#define FcPatternAddWeak FcPatternAddWeak_dylibloader_orig_fontconfig +#define FcPatternGet FcPatternGet_dylibloader_orig_fontconfig +#define FcPatternGetWithBinding FcPatternGetWithBinding_dylibloader_orig_fontconfig +#define FcPatternDel FcPatternDel_dylibloader_orig_fontconfig +#define FcPatternRemove FcPatternRemove_dylibloader_orig_fontconfig +#define FcPatternAddInteger FcPatternAddInteger_dylibloader_orig_fontconfig +#define FcPatternAddDouble FcPatternAddDouble_dylibloader_orig_fontconfig +#define FcPatternAddString FcPatternAddString_dylibloader_orig_fontconfig +#define FcPatternAddMatrix FcPatternAddMatrix_dylibloader_orig_fontconfig +#define FcPatternAddCharSet FcPatternAddCharSet_dylibloader_orig_fontconfig +#define FcPatternAddBool FcPatternAddBool_dylibloader_orig_fontconfig +#define FcPatternAddLangSet FcPatternAddLangSet_dylibloader_orig_fontconfig +#define FcPatternAddRange FcPatternAddRange_dylibloader_orig_fontconfig +#define FcPatternGetInteger FcPatternGetInteger_dylibloader_orig_fontconfig +#define FcPatternGetDouble FcPatternGetDouble_dylibloader_orig_fontconfig +#define FcPatternGetString FcPatternGetString_dylibloader_orig_fontconfig +#define FcPatternGetMatrix FcPatternGetMatrix_dylibloader_orig_fontconfig +#define FcPatternGetCharSet FcPatternGetCharSet_dylibloader_orig_fontconfig +#define FcPatternGetBool FcPatternGetBool_dylibloader_orig_fontconfig +#define FcPatternGetLangSet FcPatternGetLangSet_dylibloader_orig_fontconfig +#define FcPatternGetRange FcPatternGetRange_dylibloader_orig_fontconfig +#define FcPatternVaBuild FcPatternVaBuild_dylibloader_orig_fontconfig +#define FcPatternBuild FcPatternBuild_dylibloader_orig_fontconfig +#define FcPatternFormat FcPatternFormat_dylibloader_orig_fontconfig +#define FcRangeCreateDouble FcRangeCreateDouble_dylibloader_orig_fontconfig +#define FcRangeCreateInteger FcRangeCreateInteger_dylibloader_orig_fontconfig +#define FcRangeDestroy FcRangeDestroy_dylibloader_orig_fontconfig +#define FcRangeCopy FcRangeCopy_dylibloader_orig_fontconfig +#define FcRangeGetDouble FcRangeGetDouble_dylibloader_orig_fontconfig +#define FcWeightFromOpenType FcWeightFromOpenType_dylibloader_orig_fontconfig +#define FcWeightToOpenType FcWeightToOpenType_dylibloader_orig_fontconfig +#define FcStrCopy FcStrCopy_dylibloader_orig_fontconfig +#define FcStrCopyFilename FcStrCopyFilename_dylibloader_orig_fontconfig +#define FcStrPlus FcStrPlus_dylibloader_orig_fontconfig +#define FcStrFree FcStrFree_dylibloader_orig_fontconfig +#define FcStrDowncase FcStrDowncase_dylibloader_orig_fontconfig +#define FcStrCmpIgnoreCase FcStrCmpIgnoreCase_dylibloader_orig_fontconfig +#define FcStrCmp FcStrCmp_dylibloader_orig_fontconfig +#define FcStrStrIgnoreCase FcStrStrIgnoreCase_dylibloader_orig_fontconfig +#define FcStrStr FcStrStr_dylibloader_orig_fontconfig +#define FcUtf8ToUcs4 FcUtf8ToUcs4_dylibloader_orig_fontconfig +#define FcUtf8Len FcUtf8Len_dylibloader_orig_fontconfig +#define FcUcs4ToUtf8 FcUcs4ToUtf8_dylibloader_orig_fontconfig +#define FcUtf16ToUcs4 FcUtf16ToUcs4_dylibloader_orig_fontconfig +#define FcUtf16Len FcUtf16Len_dylibloader_orig_fontconfig +#define FcStrDirname FcStrDirname_dylibloader_orig_fontconfig +#define FcStrBasename FcStrBasename_dylibloader_orig_fontconfig +#define FcStrSetCreate FcStrSetCreate_dylibloader_orig_fontconfig +#define FcStrSetMember FcStrSetMember_dylibloader_orig_fontconfig +#define FcStrSetEqual FcStrSetEqual_dylibloader_orig_fontconfig +#define FcStrSetAdd FcStrSetAdd_dylibloader_orig_fontconfig +#define FcStrSetAddFilename FcStrSetAddFilename_dylibloader_orig_fontconfig +#define FcStrSetDel FcStrSetDel_dylibloader_orig_fontconfig +#define FcStrSetDestroy FcStrSetDestroy_dylibloader_orig_fontconfig +#define FcStrListCreate FcStrListCreate_dylibloader_orig_fontconfig +#define FcStrListFirst FcStrListFirst_dylibloader_orig_fontconfig +#define FcStrListNext FcStrListNext_dylibloader_orig_fontconfig +#define FcStrListDone FcStrListDone_dylibloader_orig_fontconfig +#define FcConfigParseAndLoad FcConfigParseAndLoad_dylibloader_orig_fontconfig +#define FcConfigParseAndLoadFromMemory FcConfigParseAndLoadFromMemory_dylibloader_orig_fontconfig +#include <fontconfig/fontconfig.h> +#undef FcBlanksCreate +#undef FcBlanksDestroy +#undef FcBlanksAdd +#undef FcBlanksIsMember +#undef FcCacheDir +#undef FcCacheCopySet +#undef FcCacheSubdir +#undef FcCacheNumSubdir +#undef FcCacheNumFont +#undef FcDirCacheUnlink +#undef FcDirCacheValid +#undef FcDirCacheClean +#undef FcCacheCreateTagFile +#undef FcConfigHome +#undef FcConfigEnableHome +#undef FcConfigFilename +#undef FcConfigCreate +#undef FcConfigReference +#undef FcConfigDestroy +#undef FcConfigSetCurrent +#undef FcConfigGetCurrent +#undef FcConfigUptoDate +#undef FcConfigBuildFonts +#undef FcConfigGetFontDirs +#undef FcConfigGetConfigDirs +#undef FcConfigGetConfigFiles +#undef FcConfigGetCache +#undef FcConfigGetBlanks +#undef FcConfigGetCacheDirs +#undef FcConfigGetRescanInterval +#undef FcConfigSetRescanInterval +#undef FcConfigGetFonts +#undef FcConfigAppFontAddFile +#undef FcConfigAppFontAddDir +#undef FcConfigAppFontClear +#undef FcConfigSubstituteWithPat +#undef FcConfigSubstitute +#undef FcConfigGetSysRoot +#undef FcConfigSetSysRoot +#undef FcValuePrint +#undef FcPatternPrint +#undef FcFontSetPrint +#undef FcGetDefaultLangs +#undef FcDefaultSubstitute +#undef FcFileIsDir +#undef FcFileScan +#undef FcDirScan +#undef FcDirSave +#undef FcDirCacheLoad +#undef FcDirCacheRescan +#undef FcDirCacheRead +#undef FcDirCacheLoadFile +#undef FcDirCacheUnload +#undef FcFreeTypeQuery +#undef FcFontSetCreate +#undef FcFontSetDestroy +#undef FcFontSetAdd +#undef FcInitLoadConfig +#undef FcInitLoadConfigAndFonts +#undef FcInit +#undef FcFini +#undef FcGetVersion +#undef FcInitReinitialize +#undef FcInitBringUptoDate +#undef FcGetLangs +#undef FcLangNormalize +#undef FcLangGetCharSet +#undef FcLangSetCreate +#undef FcLangSetDestroy +#undef FcLangSetCopy +#undef FcLangSetAdd +#undef FcLangSetDel +#undef FcLangSetHasLang +#undef FcLangSetCompare +#undef FcLangSetContains +#undef FcLangSetEqual +#undef FcLangSetHash +#undef FcLangSetGetLangs +#undef FcLangSetUnion +#undef FcLangSetSubtract +#undef FcObjectSetCreate +#undef FcObjectSetAdd +#undef FcObjectSetDestroy +#undef FcObjectSetVaBuild +#undef FcObjectSetBuild +#undef FcFontSetList +#undef FcFontList +#undef FcAtomicCreate +#undef FcAtomicLock +#undef FcAtomicNewFile +#undef FcAtomicOrigFile +#undef FcAtomicReplaceOrig +#undef FcAtomicDeleteNew +#undef FcAtomicUnlock +#undef FcAtomicDestroy +#undef FcFontSetMatch +#undef FcFontMatch +#undef FcFontRenderPrepare +#undef FcFontSetSort +#undef FcFontSort +#undef FcFontSetSortDestroy +#undef FcMatrixCopy +#undef FcMatrixEqual +#undef FcMatrixMultiply +#undef FcMatrixRotate +#undef FcMatrixScale +#undef FcMatrixShear +#undef FcNameRegisterObjectTypes +#undef FcNameUnregisterObjectTypes +#undef FcNameGetObjectType +#undef FcNameRegisterConstants +#undef FcNameUnregisterConstants +#undef FcNameGetConstant +#undef FcNameConstant +#undef FcNameParse +#undef FcNameUnparse +#undef FcPatternCreate +#undef FcPatternDuplicate +#undef FcPatternReference +#undef FcPatternFilter +#undef FcValueDestroy +#undef FcValueEqual +#undef FcValueSave +#undef FcPatternDestroy +#undef FcPatternEqual +#undef FcPatternEqualSubset +#undef FcPatternHash +#undef FcPatternAdd +#undef FcPatternAddWeak +#undef FcPatternGet +#undef FcPatternGetWithBinding +#undef FcPatternDel +#undef FcPatternRemove +#undef FcPatternAddInteger +#undef FcPatternAddDouble +#undef FcPatternAddString +#undef FcPatternAddMatrix +#undef FcPatternAddCharSet +#undef FcPatternAddBool +#undef FcPatternAddLangSet +#undef FcPatternAddRange +#undef FcPatternGetInteger +#undef FcPatternGetDouble +#undef FcPatternGetString +#undef FcPatternGetMatrix +#undef FcPatternGetCharSet +#undef FcPatternGetBool +#undef FcPatternGetLangSet +#undef FcPatternGetRange +#undef FcPatternVaBuild +#undef FcPatternBuild +#undef FcPatternFormat +#undef FcRangeCreateDouble +#undef FcRangeCreateInteger +#undef FcRangeDestroy +#undef FcRangeCopy +#undef FcRangeGetDouble +#undef FcWeightFromOpenType +#undef FcWeightToOpenType +#undef FcStrCopy +#undef FcStrCopyFilename +#undef FcStrPlus +#undef FcStrFree +#undef FcStrDowncase +#undef FcStrCmpIgnoreCase +#undef FcStrCmp +#undef FcStrStrIgnoreCase +#undef FcStrStr +#undef FcUtf8ToUcs4 +#undef FcUtf8Len +#undef FcUcs4ToUtf8 +#undef FcUtf16ToUcs4 +#undef FcUtf16Len +#undef FcStrDirname +#undef FcStrBasename +#undef FcStrSetCreate +#undef FcStrSetMember +#undef FcStrSetEqual +#undef FcStrSetAdd +#undef FcStrSetAddFilename +#undef FcStrSetDel +#undef FcStrSetDestroy +#undef FcStrListCreate +#undef FcStrListFirst +#undef FcStrListNext +#undef FcStrListDone +#undef FcConfigParseAndLoad +#undef FcConfigParseAndLoadFromMemory +#include <dlfcn.h> +#include <stdio.h> +FcBlanks* (*FcBlanksCreate_dylibloader_wrapper_fontconfig)( void); +void (*FcBlanksDestroy_dylibloader_wrapper_fontconfig)( FcBlanks*); +FcBool (*FcBlanksAdd_dylibloader_wrapper_fontconfig)( FcBlanks*, FcChar32); +FcBool (*FcBlanksIsMember_dylibloader_wrapper_fontconfig)( FcBlanks*, FcChar32); +const FcChar8* (*FcCacheDir_dylibloader_wrapper_fontconfig)(const FcCache*); +FcFontSet* (*FcCacheCopySet_dylibloader_wrapper_fontconfig)(const FcCache*); +const FcChar8* (*FcCacheSubdir_dylibloader_wrapper_fontconfig)(const FcCache*, int); +int (*FcCacheNumSubdir_dylibloader_wrapper_fontconfig)(const FcCache*); +int (*FcCacheNumFont_dylibloader_wrapper_fontconfig)(const FcCache*); +FcBool (*FcDirCacheUnlink_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*); +FcBool (*FcDirCacheValid_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcBool (*FcDirCacheClean_dylibloader_wrapper_fontconfig)(const FcChar8*, FcBool); +void (*FcCacheCreateTagFile_dylibloader_wrapper_fontconfig)(const FcConfig*); +FcChar8* (*FcConfigHome_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcConfigEnableHome_dylibloader_wrapper_fontconfig)( FcBool); +FcChar8* (*FcConfigFilename_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcConfig* (*FcConfigCreate_dylibloader_wrapper_fontconfig)( void); +FcConfig* (*FcConfigReference_dylibloader_wrapper_fontconfig)( FcConfig*); +void (*FcConfigDestroy_dylibloader_wrapper_fontconfig)( FcConfig*); +FcBool (*FcConfigSetCurrent_dylibloader_wrapper_fontconfig)( FcConfig*); +FcConfig* (*FcConfigGetCurrent_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcConfigUptoDate_dylibloader_wrapper_fontconfig)( FcConfig*); +FcBool (*FcConfigBuildFonts_dylibloader_wrapper_fontconfig)( FcConfig*); +FcStrList* (*FcConfigGetFontDirs_dylibloader_wrapper_fontconfig)( FcConfig*); +FcStrList* (*FcConfigGetConfigDirs_dylibloader_wrapper_fontconfig)( FcConfig*); +FcStrList* (*FcConfigGetConfigFiles_dylibloader_wrapper_fontconfig)( FcConfig*); +FcChar8* (*FcConfigGetCache_dylibloader_wrapper_fontconfig)( FcConfig*); +FcBlanks* (*FcConfigGetBlanks_dylibloader_wrapper_fontconfig)( FcConfig*); +FcStrList* (*FcConfigGetCacheDirs_dylibloader_wrapper_fontconfig)(const FcConfig*); +int (*FcConfigGetRescanInterval_dylibloader_wrapper_fontconfig)( FcConfig*); +FcBool (*FcConfigSetRescanInterval_dylibloader_wrapper_fontconfig)( FcConfig*, int); +FcFontSet* (*FcConfigGetFonts_dylibloader_wrapper_fontconfig)( FcConfig*, FcSetName); +FcBool (*FcConfigAppFontAddFile_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +FcBool (*FcConfigAppFontAddDir_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +void (*FcConfigAppFontClear_dylibloader_wrapper_fontconfig)( FcConfig*); +FcBool (*FcConfigSubstituteWithPat_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcPattern*, FcMatchKind); +FcBool (*FcConfigSubstitute_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcMatchKind); +const FcChar8* (*FcConfigGetSysRoot_dylibloader_wrapper_fontconfig)(const FcConfig*); +void (*FcConfigSetSysRoot_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +void (*FcValuePrint_dylibloader_wrapper_fontconfig)(const FcValue); +void (*FcPatternPrint_dylibloader_wrapper_fontconfig)(const FcPattern*); +void (*FcFontSetPrint_dylibloader_wrapper_fontconfig)(const FcFontSet*); +FcStrSet* (*FcGetDefaultLangs_dylibloader_wrapper_fontconfig)( void); +void (*FcDefaultSubstitute_dylibloader_wrapper_fontconfig)( FcPattern*); +FcBool (*FcFileIsDir_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcBool (*FcFileScan_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*, FcFileCache*, FcBlanks*,const FcChar8*, FcBool); +FcBool (*FcDirScan_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*, FcFileCache*, FcBlanks*,const FcChar8*, FcBool); +FcBool (*FcDirSave_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*,const FcChar8*); +FcCache* (*FcDirCacheLoad_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*, FcChar8**); +FcCache* (*FcDirCacheRescan_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*); +FcCache* (*FcDirCacheRead_dylibloader_wrapper_fontconfig)(const FcChar8*, FcBool, FcConfig*); +FcCache* (*FcDirCacheLoadFile_dylibloader_wrapper_fontconfig)(const FcChar8*,struct stat*); +void (*FcDirCacheUnload_dylibloader_wrapper_fontconfig)( FcCache*); +FcPattern* (*FcFreeTypeQuery_dylibloader_wrapper_fontconfig)(const FcChar8*, int, FcBlanks*, int*); +FcFontSet* (*FcFontSetCreate_dylibloader_wrapper_fontconfig)( void); +void (*FcFontSetDestroy_dylibloader_wrapper_fontconfig)( FcFontSet*); +FcBool (*FcFontSetAdd_dylibloader_wrapper_fontconfig)( FcFontSet*, FcPattern*); +FcConfig* (*FcInitLoadConfig_dylibloader_wrapper_fontconfig)( void); +FcConfig* (*FcInitLoadConfigAndFonts_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcInit_dylibloader_wrapper_fontconfig)( void); +void (*FcFini_dylibloader_wrapper_fontconfig)( void); +int (*FcGetVersion_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcInitReinitialize_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcInitBringUptoDate_dylibloader_wrapper_fontconfig)( void); +FcStrSet* (*FcGetLangs_dylibloader_wrapper_fontconfig)( void); +FcChar8* (*FcLangNormalize_dylibloader_wrapper_fontconfig)(const FcChar8*); +const FcCharSet* (*FcLangGetCharSet_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcLangSet* (*FcLangSetCreate_dylibloader_wrapper_fontconfig)( void); +void (*FcLangSetDestroy_dylibloader_wrapper_fontconfig)( FcLangSet*); +FcLangSet* (*FcLangSetCopy_dylibloader_wrapper_fontconfig)(const FcLangSet*); +FcBool (*FcLangSetAdd_dylibloader_wrapper_fontconfig)( FcLangSet*,const FcChar8*); +FcBool (*FcLangSetDel_dylibloader_wrapper_fontconfig)( FcLangSet*,const FcChar8*); +FcLangResult (*FcLangSetHasLang_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcChar8*); +FcLangResult (*FcLangSetCompare_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +FcBool (*FcLangSetContains_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +FcBool (*FcLangSetEqual_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +FcChar32 (*FcLangSetHash_dylibloader_wrapper_fontconfig)(const FcLangSet*); +FcStrSet* (*FcLangSetGetLangs_dylibloader_wrapper_fontconfig)(const FcLangSet*); +FcLangSet* (*FcLangSetUnion_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +FcLangSet* (*FcLangSetSubtract_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +FcObjectSet* (*FcObjectSetCreate_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcObjectSetAdd_dylibloader_wrapper_fontconfig)( FcObjectSet*,const char*); +void (*FcObjectSetDestroy_dylibloader_wrapper_fontconfig)( FcObjectSet*); +FcObjectSet* (*FcObjectSetVaBuild_dylibloader_wrapper_fontconfig)(const char*, va_list); +FcObjectSet* (*FcObjectSetBuild_dylibloader_wrapper_fontconfig)(const char*,...); +FcFontSet* (*FcFontSetList_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcObjectSet*); +FcFontSet* (*FcFontList_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcObjectSet*); +FcAtomic* (*FcAtomicCreate_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcBool (*FcAtomicLock_dylibloader_wrapper_fontconfig)( FcAtomic*); +FcChar8* (*FcAtomicNewFile_dylibloader_wrapper_fontconfig)( FcAtomic*); +FcChar8* (*FcAtomicOrigFile_dylibloader_wrapper_fontconfig)( FcAtomic*); +FcBool (*FcAtomicReplaceOrig_dylibloader_wrapper_fontconfig)( FcAtomic*); +void (*FcAtomicDeleteNew_dylibloader_wrapper_fontconfig)( FcAtomic*); +void (*FcAtomicUnlock_dylibloader_wrapper_fontconfig)( FcAtomic*); +void (*FcAtomicDestroy_dylibloader_wrapper_fontconfig)( FcAtomic*); +FcPattern* (*FcFontSetMatch_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcResult*); +FcPattern* (*FcFontMatch_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcResult*); +FcPattern* (*FcFontRenderPrepare_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcPattern*); +FcFontSet* (*FcFontSetSort_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcBool, FcCharSet**, FcResult*); +FcFontSet* (*FcFontSort_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcBool, FcCharSet**, FcResult*); +void (*FcFontSetSortDestroy_dylibloader_wrapper_fontconfig)( FcFontSet*); +FcMatrix* (*FcMatrixCopy_dylibloader_wrapper_fontconfig)(const FcMatrix*); +FcBool (*FcMatrixEqual_dylibloader_wrapper_fontconfig)(const FcMatrix*,const FcMatrix*); +void (*FcMatrixMultiply_dylibloader_wrapper_fontconfig)( FcMatrix*,const FcMatrix*,const FcMatrix*); +void (*FcMatrixRotate_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +void (*FcMatrixScale_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +void (*FcMatrixShear_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +FcBool (*FcNameRegisterObjectTypes_dylibloader_wrapper_fontconfig)(const FcObjectType*, int); +FcBool (*FcNameUnregisterObjectTypes_dylibloader_wrapper_fontconfig)(const FcObjectType*, int); +const FcObjectType* (*FcNameGetObjectType_dylibloader_wrapper_fontconfig)(const char*); +FcBool (*FcNameRegisterConstants_dylibloader_wrapper_fontconfig)(const FcConstant*, int); +FcBool (*FcNameUnregisterConstants_dylibloader_wrapper_fontconfig)(const FcConstant*, int); +const FcConstant* (*FcNameGetConstant_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcBool (*FcNameConstant_dylibloader_wrapper_fontconfig)(const FcChar8*, int*); +FcPattern* (*FcNameParse_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcChar8* (*FcNameUnparse_dylibloader_wrapper_fontconfig)( FcPattern*); +FcPattern* (*FcPatternCreate_dylibloader_wrapper_fontconfig)( void); +FcPattern* (*FcPatternDuplicate_dylibloader_wrapper_fontconfig)(const FcPattern*); +void (*FcPatternReference_dylibloader_wrapper_fontconfig)( FcPattern*); +FcPattern* (*FcPatternFilter_dylibloader_wrapper_fontconfig)( FcPattern*,const FcObjectSet*); +void (*FcValueDestroy_dylibloader_wrapper_fontconfig)( FcValue); +FcBool (*FcValueEqual_dylibloader_wrapper_fontconfig)( FcValue, FcValue); +FcValue (*FcValueSave_dylibloader_wrapper_fontconfig)( FcValue); +void (*FcPatternDestroy_dylibloader_wrapper_fontconfig)( FcPattern*); +FcBool (*FcPatternEqual_dylibloader_wrapper_fontconfig)(const FcPattern*,const FcPattern*); +FcBool (*FcPatternEqualSubset_dylibloader_wrapper_fontconfig)(const FcPattern*,const FcPattern*,const FcObjectSet*); +FcChar32 (*FcPatternHash_dylibloader_wrapper_fontconfig)(const FcPattern*); +FcBool (*FcPatternAdd_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcValue, FcBool); +FcBool (*FcPatternAddWeak_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcValue, FcBool); +FcResult (*FcPatternGet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcValue*); +FcResult (*FcPatternGetWithBinding_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcValue*, FcValueBinding*); +FcBool (*FcPatternDel_dylibloader_wrapper_fontconfig)( FcPattern*,const char*); +FcBool (*FcPatternRemove_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, int); +FcBool (*FcPatternAddInteger_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, int); +FcBool (*FcPatternAddDouble_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, double); +FcBool (*FcPatternAddString_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcChar8*); +FcBool (*FcPatternAddMatrix_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcMatrix*); +FcBool (*FcPatternAddCharSet_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcCharSet*); +FcBool (*FcPatternAddBool_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcBool); +FcBool (*FcPatternAddLangSet_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcLangSet*); +FcBool (*FcPatternAddRange_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcRange*); +FcResult (*FcPatternGetInteger_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, int*); +FcResult (*FcPatternGetDouble_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, double*); +FcResult (*FcPatternGetString_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcChar8**); +FcResult (*FcPatternGetMatrix_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcMatrix**); +FcResult (*FcPatternGetCharSet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcCharSet**); +FcResult (*FcPatternGetBool_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcBool*); +FcResult (*FcPatternGetLangSet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcLangSet**); +FcResult (*FcPatternGetRange_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcRange**); +FcPattern* (*FcPatternVaBuild_dylibloader_wrapper_fontconfig)( FcPattern*, va_list); +FcPattern* (*FcPatternBuild_dylibloader_wrapper_fontconfig)( FcPattern*,...); +FcChar8* (*FcPatternFormat_dylibloader_wrapper_fontconfig)( FcPattern*,const FcChar8*); +FcRange* (*FcRangeCreateDouble_dylibloader_wrapper_fontconfig)( double, double); +FcRange* (*FcRangeCreateInteger_dylibloader_wrapper_fontconfig)( FcChar32, FcChar32); +void (*FcRangeDestroy_dylibloader_wrapper_fontconfig)( FcRange*); +FcRange* (*FcRangeCopy_dylibloader_wrapper_fontconfig)(const FcRange*); +FcBool (*FcRangeGetDouble_dylibloader_wrapper_fontconfig)(const FcRange*, double*, double*); +int (*FcWeightFromOpenType_dylibloader_wrapper_fontconfig)( int); +int (*FcWeightToOpenType_dylibloader_wrapper_fontconfig)( int); +FcChar8* (*FcStrCopy_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcChar8* (*FcStrCopyFilename_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcChar8* (*FcStrPlus_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +void (*FcStrFree_dylibloader_wrapper_fontconfig)( FcChar8*); +FcChar8* (*FcStrDowncase_dylibloader_wrapper_fontconfig)(const FcChar8*); +int (*FcStrCmpIgnoreCase_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +int (*FcStrCmp_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +const FcChar8* (*FcStrStrIgnoreCase_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +const FcChar8* (*FcStrStr_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +int (*FcUtf8ToUcs4_dylibloader_wrapper_fontconfig)(const FcChar8*, FcChar32*, int); +FcBool (*FcUtf8Len_dylibloader_wrapper_fontconfig)(const FcChar8*, int, int*, int*); +int (*FcUcs4ToUtf8_dylibloader_wrapper_fontconfig)( FcChar32, FcChar8 [6]); +int (*FcUtf16ToUcs4_dylibloader_wrapper_fontconfig)(const FcChar8*, FcEndian, FcChar32*, int); +FcBool (*FcUtf16Len_dylibloader_wrapper_fontconfig)(const FcChar8*, FcEndian, int, int*, int*); +FcChar8* (*FcStrDirname_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcChar8* (*FcStrBasename_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcStrSet* (*FcStrSetCreate_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcStrSetMember_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +FcBool (*FcStrSetEqual_dylibloader_wrapper_fontconfig)( FcStrSet*, FcStrSet*); +FcBool (*FcStrSetAdd_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +FcBool (*FcStrSetAddFilename_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +FcBool (*FcStrSetDel_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +void (*FcStrSetDestroy_dylibloader_wrapper_fontconfig)( FcStrSet*); +FcStrList* (*FcStrListCreate_dylibloader_wrapper_fontconfig)( FcStrSet*); +void (*FcStrListFirst_dylibloader_wrapper_fontconfig)( FcStrList*); +FcChar8* (*FcStrListNext_dylibloader_wrapper_fontconfig)( FcStrList*); +void (*FcStrListDone_dylibloader_wrapper_fontconfig)( FcStrList*); +FcBool (*FcConfigParseAndLoad_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*, FcBool); +FcBool (*FcConfigParseAndLoadFromMemory_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*, FcBool); +int initialize_fontconfig(int verbose) { + void *handle; + char *error; + handle = dlopen("libfontconfig.so", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// FcBlanksCreate + *(void **) (&FcBlanksCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcBlanksCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcBlanksDestroy + *(void **) (&FcBlanksDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcBlanksDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcBlanksAdd + *(void **) (&FcBlanksAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcBlanksAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcBlanksIsMember + *(void **) (&FcBlanksIsMember_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcBlanksIsMember"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheDir + *(void **) (&FcCacheDir_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheDir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheCopySet + *(void **) (&FcCacheCopySet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheCopySet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheSubdir + *(void **) (&FcCacheSubdir_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheSubdir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheNumSubdir + *(void **) (&FcCacheNumSubdir_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheNumSubdir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheNumFont + *(void **) (&FcCacheNumFont_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheNumFont"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheUnlink + *(void **) (&FcDirCacheUnlink_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheUnlink"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheValid + *(void **) (&FcDirCacheValid_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheValid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheClean + *(void **) (&FcDirCacheClean_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheClean"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheCreateTagFile + *(void **) (&FcCacheCreateTagFile_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheCreateTagFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigHome + *(void **) (&FcConfigHome_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigHome"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigEnableHome + *(void **) (&FcConfigEnableHome_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigEnableHome"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigFilename + *(void **) (&FcConfigFilename_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigFilename"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigCreate + *(void **) (&FcConfigCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigReference + *(void **) (&FcConfigReference_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigReference"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigDestroy + *(void **) (&FcConfigDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigSetCurrent + *(void **) (&FcConfigSetCurrent_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigSetCurrent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetCurrent + *(void **) (&FcConfigGetCurrent_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetCurrent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigUptoDate + *(void **) (&FcConfigUptoDate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigUptoDate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigBuildFonts + *(void **) (&FcConfigBuildFonts_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigBuildFonts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetFontDirs + *(void **) (&FcConfigGetFontDirs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetFontDirs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetConfigDirs + *(void **) (&FcConfigGetConfigDirs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetConfigDirs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetConfigFiles + *(void **) (&FcConfigGetConfigFiles_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetConfigFiles"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetCache + *(void **) (&FcConfigGetCache_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetCache"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetBlanks + *(void **) (&FcConfigGetBlanks_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetBlanks"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetCacheDirs + *(void **) (&FcConfigGetCacheDirs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetCacheDirs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetRescanInterval + *(void **) (&FcConfigGetRescanInterval_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetRescanInterval"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigSetRescanInterval + *(void **) (&FcConfigSetRescanInterval_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigSetRescanInterval"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetFonts + *(void **) (&FcConfigGetFonts_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetFonts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigAppFontAddFile + *(void **) (&FcConfigAppFontAddFile_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigAppFontAddFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigAppFontAddDir + *(void **) (&FcConfigAppFontAddDir_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigAppFontAddDir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigAppFontClear + *(void **) (&FcConfigAppFontClear_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigAppFontClear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigSubstituteWithPat + *(void **) (&FcConfigSubstituteWithPat_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigSubstituteWithPat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigSubstitute + *(void **) (&FcConfigSubstitute_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigSubstitute"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetSysRoot + *(void **) (&FcConfigGetSysRoot_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetSysRoot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigSetSysRoot + *(void **) (&FcConfigSetSysRoot_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigSetSysRoot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcValuePrint + *(void **) (&FcValuePrint_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcValuePrint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternPrint + *(void **) (&FcPatternPrint_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternPrint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetPrint + *(void **) (&FcFontSetPrint_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetPrint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcGetDefaultLangs + *(void **) (&FcGetDefaultLangs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcGetDefaultLangs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDefaultSubstitute + *(void **) (&FcDefaultSubstitute_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDefaultSubstitute"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFileIsDir + *(void **) (&FcFileIsDir_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFileIsDir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFileScan + *(void **) (&FcFileScan_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFileScan"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirScan + *(void **) (&FcDirScan_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirScan"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirSave + *(void **) (&FcDirSave_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirSave"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheLoad + *(void **) (&FcDirCacheLoad_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheLoad"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheRescan + *(void **) (&FcDirCacheRescan_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheRescan"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheRead + *(void **) (&FcDirCacheRead_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheRead"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheLoadFile + *(void **) (&FcDirCacheLoadFile_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheLoadFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheUnload + *(void **) (&FcDirCacheUnload_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheUnload"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFreeTypeQuery + *(void **) (&FcFreeTypeQuery_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFreeTypeQuery"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetCreate + *(void **) (&FcFontSetCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetDestroy + *(void **) (&FcFontSetDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetAdd + *(void **) (&FcFontSetAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcInitLoadConfig + *(void **) (&FcInitLoadConfig_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcInitLoadConfig"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcInitLoadConfigAndFonts + *(void **) (&FcInitLoadConfigAndFonts_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcInitLoadConfigAndFonts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcInit + *(void **) (&FcInit_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcInit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFini + *(void **) (&FcFini_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFini"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcGetVersion + *(void **) (&FcGetVersion_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcGetVersion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcInitReinitialize + *(void **) (&FcInitReinitialize_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcInitReinitialize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcInitBringUptoDate + *(void **) (&FcInitBringUptoDate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcInitBringUptoDate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcGetLangs + *(void **) (&FcGetLangs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcGetLangs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangNormalize + *(void **) (&FcLangNormalize_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangNormalize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangGetCharSet + *(void **) (&FcLangGetCharSet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangGetCharSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetCreate + *(void **) (&FcLangSetCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetDestroy + *(void **) (&FcLangSetDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetCopy + *(void **) (&FcLangSetCopy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetCopy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetAdd + *(void **) (&FcLangSetAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetDel + *(void **) (&FcLangSetDel_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetDel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetHasLang + *(void **) (&FcLangSetHasLang_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetHasLang"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetCompare + *(void **) (&FcLangSetCompare_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetCompare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetContains + *(void **) (&FcLangSetContains_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetContains"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetEqual + *(void **) (&FcLangSetEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetHash + *(void **) (&FcLangSetHash_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetHash"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetGetLangs + *(void **) (&FcLangSetGetLangs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetGetLangs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetUnion + *(void **) (&FcLangSetUnion_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetUnion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetSubtract + *(void **) (&FcLangSetSubtract_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetSubtract"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcObjectSetCreate + *(void **) (&FcObjectSetCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcObjectSetCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcObjectSetAdd + *(void **) (&FcObjectSetAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcObjectSetAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcObjectSetDestroy + *(void **) (&FcObjectSetDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcObjectSetDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcObjectSetVaBuild + *(void **) (&FcObjectSetVaBuild_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcObjectSetVaBuild"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcObjectSetBuild + *(void **) (&FcObjectSetBuild_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcObjectSetBuild"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetList + *(void **) (&FcFontSetList_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontList + *(void **) (&FcFontList_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicCreate + *(void **) (&FcAtomicCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicLock + *(void **) (&FcAtomicLock_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicLock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicNewFile + *(void **) (&FcAtomicNewFile_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicNewFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicOrigFile + *(void **) (&FcAtomicOrigFile_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicOrigFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicReplaceOrig + *(void **) (&FcAtomicReplaceOrig_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicReplaceOrig"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicDeleteNew + *(void **) (&FcAtomicDeleteNew_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicDeleteNew"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicUnlock + *(void **) (&FcAtomicUnlock_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicUnlock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicDestroy + *(void **) (&FcAtomicDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetMatch + *(void **) (&FcFontSetMatch_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetMatch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontMatch + *(void **) (&FcFontMatch_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontMatch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontRenderPrepare + *(void **) (&FcFontRenderPrepare_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontRenderPrepare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetSort + *(void **) (&FcFontSetSort_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetSort"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSort + *(void **) (&FcFontSort_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSort"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetSortDestroy + *(void **) (&FcFontSetSortDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetSortDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixCopy + *(void **) (&FcMatrixCopy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixCopy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixEqual + *(void **) (&FcMatrixEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixMultiply + *(void **) (&FcMatrixMultiply_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixMultiply"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixRotate + *(void **) (&FcMatrixRotate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixRotate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixScale + *(void **) (&FcMatrixScale_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixScale"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixShear + *(void **) (&FcMatrixShear_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixShear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameRegisterObjectTypes + *(void **) (&FcNameRegisterObjectTypes_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameRegisterObjectTypes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameUnregisterObjectTypes + *(void **) (&FcNameUnregisterObjectTypes_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameUnregisterObjectTypes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameGetObjectType + *(void **) (&FcNameGetObjectType_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameGetObjectType"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameRegisterConstants + *(void **) (&FcNameRegisterConstants_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameRegisterConstants"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameUnregisterConstants + *(void **) (&FcNameUnregisterConstants_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameUnregisterConstants"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameGetConstant + *(void **) (&FcNameGetConstant_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameGetConstant"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameConstant + *(void **) (&FcNameConstant_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameConstant"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameParse + *(void **) (&FcNameParse_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameParse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameUnparse + *(void **) (&FcNameUnparse_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameUnparse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternCreate + *(void **) (&FcPatternCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternDuplicate + *(void **) (&FcPatternDuplicate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternDuplicate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternReference + *(void **) (&FcPatternReference_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternReference"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternFilter + *(void **) (&FcPatternFilter_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternFilter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcValueDestroy + *(void **) (&FcValueDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcValueDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcValueEqual + *(void **) (&FcValueEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcValueEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcValueSave + *(void **) (&FcValueSave_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcValueSave"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternDestroy + *(void **) (&FcPatternDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternEqual + *(void **) (&FcPatternEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternEqualSubset + *(void **) (&FcPatternEqualSubset_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternEqualSubset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternHash + *(void **) (&FcPatternHash_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternHash"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAdd + *(void **) (&FcPatternAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddWeak + *(void **) (&FcPatternAddWeak_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddWeak"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGet + *(void **) (&FcPatternGet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetWithBinding + *(void **) (&FcPatternGetWithBinding_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetWithBinding"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternDel + *(void **) (&FcPatternDel_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternDel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternRemove + *(void **) (&FcPatternRemove_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternRemove"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddInteger + *(void **) (&FcPatternAddInteger_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddInteger"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddDouble + *(void **) (&FcPatternAddDouble_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddDouble"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddString + *(void **) (&FcPatternAddString_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddMatrix + *(void **) (&FcPatternAddMatrix_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddMatrix"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddCharSet + *(void **) (&FcPatternAddCharSet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddCharSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddBool + *(void **) (&FcPatternAddBool_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddBool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddLangSet + *(void **) (&FcPatternAddLangSet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddLangSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddRange + *(void **) (&FcPatternAddRange_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddRange"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetInteger + *(void **) (&FcPatternGetInteger_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetInteger"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetDouble + *(void **) (&FcPatternGetDouble_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetDouble"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetString + *(void **) (&FcPatternGetString_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetMatrix + *(void **) (&FcPatternGetMatrix_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetMatrix"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetCharSet + *(void **) (&FcPatternGetCharSet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetCharSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetBool + *(void **) (&FcPatternGetBool_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetBool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetLangSet + *(void **) (&FcPatternGetLangSet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetLangSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetRange + *(void **) (&FcPatternGetRange_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetRange"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternVaBuild + *(void **) (&FcPatternVaBuild_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternVaBuild"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternBuild + *(void **) (&FcPatternBuild_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternBuild"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternFormat + *(void **) (&FcPatternFormat_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternFormat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcRangeCreateDouble + *(void **) (&FcRangeCreateDouble_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcRangeCreateDouble"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcRangeCreateInteger + *(void **) (&FcRangeCreateInteger_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcRangeCreateInteger"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcRangeDestroy + *(void **) (&FcRangeDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcRangeDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcRangeCopy + *(void **) (&FcRangeCopy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcRangeCopy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcRangeGetDouble + *(void **) (&FcRangeGetDouble_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcRangeGetDouble"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcWeightFromOpenType + *(void **) (&FcWeightFromOpenType_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcWeightFromOpenType"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcWeightToOpenType + *(void **) (&FcWeightToOpenType_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcWeightToOpenType"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrCopy + *(void **) (&FcStrCopy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrCopy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrCopyFilename + *(void **) (&FcStrCopyFilename_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrCopyFilename"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrPlus + *(void **) (&FcStrPlus_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrPlus"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrFree + *(void **) (&FcStrFree_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrFree"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrDowncase + *(void **) (&FcStrDowncase_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrDowncase"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrCmpIgnoreCase + *(void **) (&FcStrCmpIgnoreCase_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrCmpIgnoreCase"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrCmp + *(void **) (&FcStrCmp_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrCmp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrStrIgnoreCase + *(void **) (&FcStrStrIgnoreCase_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrStrIgnoreCase"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrStr + *(void **) (&FcStrStr_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrStr"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcUtf8ToUcs4 + *(void **) (&FcUtf8ToUcs4_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcUtf8ToUcs4"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcUtf8Len + *(void **) (&FcUtf8Len_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcUtf8Len"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcUcs4ToUtf8 + *(void **) (&FcUcs4ToUtf8_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcUcs4ToUtf8"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcUtf16ToUcs4 + *(void **) (&FcUtf16ToUcs4_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcUtf16ToUcs4"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcUtf16Len + *(void **) (&FcUtf16Len_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcUtf16Len"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrDirname + *(void **) (&FcStrDirname_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrDirname"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrBasename + *(void **) (&FcStrBasename_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrBasename"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetCreate + *(void **) (&FcStrSetCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetMember + *(void **) (&FcStrSetMember_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetMember"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetEqual + *(void **) (&FcStrSetEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetAdd + *(void **) (&FcStrSetAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetAddFilename + *(void **) (&FcStrSetAddFilename_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetAddFilename"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetDel + *(void **) (&FcStrSetDel_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetDel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetDestroy + *(void **) (&FcStrSetDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrListCreate + *(void **) (&FcStrListCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrListCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrListFirst + *(void **) (&FcStrListFirst_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrListFirst"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrListNext + *(void **) (&FcStrListNext_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrListNext"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrListDone + *(void **) (&FcStrListDone_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrListDone"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigParseAndLoad + *(void **) (&FcConfigParseAndLoad_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigParseAndLoad"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigParseAndLoadFromMemory + *(void **) (&FcConfigParseAndLoadFromMemory_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigParseAndLoadFromMemory"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/fontconfig-so_wrap.h b/platform/linuxbsd/fontconfig-so_wrap.h new file mode 100644 index 0000000000..f0794cce8b --- /dev/null +++ b/platform/linuxbsd/fontconfig-so_wrap.h @@ -0,0 +1,770 @@ +#ifndef DYLIBLOAD_WRAPPER_FONTCONFIG +#define DYLIBLOAD_WRAPPER_FONTCONFIG +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by ./generate-wrapper.py 0.3 on 2022-07-29 05:40:07 +// flags: ./generate-wrapper.py --include /usr/include/fontconfig/fontconfig.h --sys-include <fontconfig/fontconfig.h> --soname libfontconfig.so --init-name fontconfig --output-header fontconfig-so_wrap.h --output-implementation fontconfig-so_wrap.c --omit-prefix FcCharSet +// +#include <stdint.h> + +#define FcBlanksCreate FcBlanksCreate_dylibloader_orig_fontconfig +#define FcBlanksDestroy FcBlanksDestroy_dylibloader_orig_fontconfig +#define FcBlanksAdd FcBlanksAdd_dylibloader_orig_fontconfig +#define FcBlanksIsMember FcBlanksIsMember_dylibloader_orig_fontconfig +#define FcCacheDir FcCacheDir_dylibloader_orig_fontconfig +#define FcCacheCopySet FcCacheCopySet_dylibloader_orig_fontconfig +#define FcCacheSubdir FcCacheSubdir_dylibloader_orig_fontconfig +#define FcCacheNumSubdir FcCacheNumSubdir_dylibloader_orig_fontconfig +#define FcCacheNumFont FcCacheNumFont_dylibloader_orig_fontconfig +#define FcDirCacheUnlink FcDirCacheUnlink_dylibloader_orig_fontconfig +#define FcDirCacheValid FcDirCacheValid_dylibloader_orig_fontconfig +#define FcDirCacheClean FcDirCacheClean_dylibloader_orig_fontconfig +#define FcCacheCreateTagFile FcCacheCreateTagFile_dylibloader_orig_fontconfig +#define FcConfigHome FcConfigHome_dylibloader_orig_fontconfig +#define FcConfigEnableHome FcConfigEnableHome_dylibloader_orig_fontconfig +#define FcConfigFilename FcConfigFilename_dylibloader_orig_fontconfig +#define FcConfigCreate FcConfigCreate_dylibloader_orig_fontconfig +#define FcConfigReference FcConfigReference_dylibloader_orig_fontconfig +#define FcConfigDestroy FcConfigDestroy_dylibloader_orig_fontconfig +#define FcConfigSetCurrent FcConfigSetCurrent_dylibloader_orig_fontconfig +#define FcConfigGetCurrent FcConfigGetCurrent_dylibloader_orig_fontconfig +#define FcConfigUptoDate FcConfigUptoDate_dylibloader_orig_fontconfig +#define FcConfigBuildFonts FcConfigBuildFonts_dylibloader_orig_fontconfig +#define FcConfigGetFontDirs FcConfigGetFontDirs_dylibloader_orig_fontconfig +#define FcConfigGetConfigDirs FcConfigGetConfigDirs_dylibloader_orig_fontconfig +#define FcConfigGetConfigFiles FcConfigGetConfigFiles_dylibloader_orig_fontconfig +#define FcConfigGetCache FcConfigGetCache_dylibloader_orig_fontconfig +#define FcConfigGetBlanks FcConfigGetBlanks_dylibloader_orig_fontconfig +#define FcConfigGetCacheDirs FcConfigGetCacheDirs_dylibloader_orig_fontconfig +#define FcConfigGetRescanInterval FcConfigGetRescanInterval_dylibloader_orig_fontconfig +#define FcConfigSetRescanInterval FcConfigSetRescanInterval_dylibloader_orig_fontconfig +#define FcConfigGetFonts FcConfigGetFonts_dylibloader_orig_fontconfig +#define FcConfigAppFontAddFile FcConfigAppFontAddFile_dylibloader_orig_fontconfig +#define FcConfigAppFontAddDir FcConfigAppFontAddDir_dylibloader_orig_fontconfig +#define FcConfigAppFontClear FcConfigAppFontClear_dylibloader_orig_fontconfig +#define FcConfigSubstituteWithPat FcConfigSubstituteWithPat_dylibloader_orig_fontconfig +#define FcConfigSubstitute FcConfigSubstitute_dylibloader_orig_fontconfig +#define FcConfigGetSysRoot FcConfigGetSysRoot_dylibloader_orig_fontconfig +#define FcConfigSetSysRoot FcConfigSetSysRoot_dylibloader_orig_fontconfig +#define FcValuePrint FcValuePrint_dylibloader_orig_fontconfig +#define FcPatternPrint FcPatternPrint_dylibloader_orig_fontconfig +#define FcFontSetPrint FcFontSetPrint_dylibloader_orig_fontconfig +#define FcGetDefaultLangs FcGetDefaultLangs_dylibloader_orig_fontconfig +#define FcDefaultSubstitute FcDefaultSubstitute_dylibloader_orig_fontconfig +#define FcFileIsDir FcFileIsDir_dylibloader_orig_fontconfig +#define FcFileScan FcFileScan_dylibloader_orig_fontconfig +#define FcDirScan FcDirScan_dylibloader_orig_fontconfig +#define FcDirSave FcDirSave_dylibloader_orig_fontconfig +#define FcDirCacheLoad FcDirCacheLoad_dylibloader_orig_fontconfig +#define FcDirCacheRescan FcDirCacheRescan_dylibloader_orig_fontconfig +#define FcDirCacheRead FcDirCacheRead_dylibloader_orig_fontconfig +#define FcDirCacheLoadFile FcDirCacheLoadFile_dylibloader_orig_fontconfig +#define FcDirCacheUnload FcDirCacheUnload_dylibloader_orig_fontconfig +#define FcFreeTypeQuery FcFreeTypeQuery_dylibloader_orig_fontconfig +#define FcFontSetCreate FcFontSetCreate_dylibloader_orig_fontconfig +#define FcFontSetDestroy FcFontSetDestroy_dylibloader_orig_fontconfig +#define FcFontSetAdd FcFontSetAdd_dylibloader_orig_fontconfig +#define FcInitLoadConfig FcInitLoadConfig_dylibloader_orig_fontconfig +#define FcInitLoadConfigAndFonts FcInitLoadConfigAndFonts_dylibloader_orig_fontconfig +#define FcInit FcInit_dylibloader_orig_fontconfig +#define FcFini FcFini_dylibloader_orig_fontconfig +#define FcGetVersion FcGetVersion_dylibloader_orig_fontconfig +#define FcInitReinitialize FcInitReinitialize_dylibloader_orig_fontconfig +#define FcInitBringUptoDate FcInitBringUptoDate_dylibloader_orig_fontconfig +#define FcGetLangs FcGetLangs_dylibloader_orig_fontconfig +#define FcLangNormalize FcLangNormalize_dylibloader_orig_fontconfig +#define FcLangGetCharSet FcLangGetCharSet_dylibloader_orig_fontconfig +#define FcLangSetCreate FcLangSetCreate_dylibloader_orig_fontconfig +#define FcLangSetDestroy FcLangSetDestroy_dylibloader_orig_fontconfig +#define FcLangSetCopy FcLangSetCopy_dylibloader_orig_fontconfig +#define FcLangSetAdd FcLangSetAdd_dylibloader_orig_fontconfig +#define FcLangSetDel FcLangSetDel_dylibloader_orig_fontconfig +#define FcLangSetHasLang FcLangSetHasLang_dylibloader_orig_fontconfig +#define FcLangSetCompare FcLangSetCompare_dylibloader_orig_fontconfig +#define FcLangSetContains FcLangSetContains_dylibloader_orig_fontconfig +#define FcLangSetEqual FcLangSetEqual_dylibloader_orig_fontconfig +#define FcLangSetHash FcLangSetHash_dylibloader_orig_fontconfig +#define FcLangSetGetLangs FcLangSetGetLangs_dylibloader_orig_fontconfig +#define FcLangSetUnion FcLangSetUnion_dylibloader_orig_fontconfig +#define FcLangSetSubtract FcLangSetSubtract_dylibloader_orig_fontconfig +#define FcObjectSetCreate FcObjectSetCreate_dylibloader_orig_fontconfig +#define FcObjectSetAdd FcObjectSetAdd_dylibloader_orig_fontconfig +#define FcObjectSetDestroy FcObjectSetDestroy_dylibloader_orig_fontconfig +#define FcObjectSetVaBuild FcObjectSetVaBuild_dylibloader_orig_fontconfig +#define FcObjectSetBuild FcObjectSetBuild_dylibloader_orig_fontconfig +#define FcFontSetList FcFontSetList_dylibloader_orig_fontconfig +#define FcFontList FcFontList_dylibloader_orig_fontconfig +#define FcAtomicCreate FcAtomicCreate_dylibloader_orig_fontconfig +#define FcAtomicLock FcAtomicLock_dylibloader_orig_fontconfig +#define FcAtomicNewFile FcAtomicNewFile_dylibloader_orig_fontconfig +#define FcAtomicOrigFile FcAtomicOrigFile_dylibloader_orig_fontconfig +#define FcAtomicReplaceOrig FcAtomicReplaceOrig_dylibloader_orig_fontconfig +#define FcAtomicDeleteNew FcAtomicDeleteNew_dylibloader_orig_fontconfig +#define FcAtomicUnlock FcAtomicUnlock_dylibloader_orig_fontconfig +#define FcAtomicDestroy FcAtomicDestroy_dylibloader_orig_fontconfig +#define FcFontSetMatch FcFontSetMatch_dylibloader_orig_fontconfig +#define FcFontMatch FcFontMatch_dylibloader_orig_fontconfig +#define FcFontRenderPrepare FcFontRenderPrepare_dylibloader_orig_fontconfig +#define FcFontSetSort FcFontSetSort_dylibloader_orig_fontconfig +#define FcFontSort FcFontSort_dylibloader_orig_fontconfig +#define FcFontSetSortDestroy FcFontSetSortDestroy_dylibloader_orig_fontconfig +#define FcMatrixCopy FcMatrixCopy_dylibloader_orig_fontconfig +#define FcMatrixEqual FcMatrixEqual_dylibloader_orig_fontconfig +#define FcMatrixMultiply FcMatrixMultiply_dylibloader_orig_fontconfig +#define FcMatrixRotate FcMatrixRotate_dylibloader_orig_fontconfig +#define FcMatrixScale FcMatrixScale_dylibloader_orig_fontconfig +#define FcMatrixShear FcMatrixShear_dylibloader_orig_fontconfig +#define FcNameRegisterObjectTypes FcNameRegisterObjectTypes_dylibloader_orig_fontconfig +#define FcNameUnregisterObjectTypes FcNameUnregisterObjectTypes_dylibloader_orig_fontconfig +#define FcNameGetObjectType FcNameGetObjectType_dylibloader_orig_fontconfig +#define FcNameRegisterConstants FcNameRegisterConstants_dylibloader_orig_fontconfig +#define FcNameUnregisterConstants FcNameUnregisterConstants_dylibloader_orig_fontconfig +#define FcNameGetConstant FcNameGetConstant_dylibloader_orig_fontconfig +#define FcNameConstant FcNameConstant_dylibloader_orig_fontconfig +#define FcNameParse FcNameParse_dylibloader_orig_fontconfig +#define FcNameUnparse FcNameUnparse_dylibloader_orig_fontconfig +#define FcPatternCreate FcPatternCreate_dylibloader_orig_fontconfig +#define FcPatternDuplicate FcPatternDuplicate_dylibloader_orig_fontconfig +#define FcPatternReference FcPatternReference_dylibloader_orig_fontconfig +#define FcPatternFilter FcPatternFilter_dylibloader_orig_fontconfig +#define FcValueDestroy FcValueDestroy_dylibloader_orig_fontconfig +#define FcValueEqual FcValueEqual_dylibloader_orig_fontconfig +#define FcValueSave FcValueSave_dylibloader_orig_fontconfig +#define FcPatternDestroy FcPatternDestroy_dylibloader_orig_fontconfig +#define FcPatternEqual FcPatternEqual_dylibloader_orig_fontconfig +#define FcPatternEqualSubset FcPatternEqualSubset_dylibloader_orig_fontconfig +#define FcPatternHash FcPatternHash_dylibloader_orig_fontconfig +#define FcPatternAdd FcPatternAdd_dylibloader_orig_fontconfig +#define FcPatternAddWeak FcPatternAddWeak_dylibloader_orig_fontconfig +#define FcPatternGet FcPatternGet_dylibloader_orig_fontconfig +#define FcPatternGetWithBinding FcPatternGetWithBinding_dylibloader_orig_fontconfig +#define FcPatternDel FcPatternDel_dylibloader_orig_fontconfig +#define FcPatternRemove FcPatternRemove_dylibloader_orig_fontconfig +#define FcPatternAddInteger FcPatternAddInteger_dylibloader_orig_fontconfig +#define FcPatternAddDouble FcPatternAddDouble_dylibloader_orig_fontconfig +#define FcPatternAddString FcPatternAddString_dylibloader_orig_fontconfig +#define FcPatternAddMatrix FcPatternAddMatrix_dylibloader_orig_fontconfig +#define FcPatternAddCharSet FcPatternAddCharSet_dylibloader_orig_fontconfig +#define FcPatternAddBool FcPatternAddBool_dylibloader_orig_fontconfig +#define FcPatternAddLangSet FcPatternAddLangSet_dylibloader_orig_fontconfig +#define FcPatternAddRange FcPatternAddRange_dylibloader_orig_fontconfig +#define FcPatternGetInteger FcPatternGetInteger_dylibloader_orig_fontconfig +#define FcPatternGetDouble FcPatternGetDouble_dylibloader_orig_fontconfig +#define FcPatternGetString FcPatternGetString_dylibloader_orig_fontconfig +#define FcPatternGetMatrix FcPatternGetMatrix_dylibloader_orig_fontconfig +#define FcPatternGetCharSet FcPatternGetCharSet_dylibloader_orig_fontconfig +#define FcPatternGetBool FcPatternGetBool_dylibloader_orig_fontconfig +#define FcPatternGetLangSet FcPatternGetLangSet_dylibloader_orig_fontconfig +#define FcPatternGetRange FcPatternGetRange_dylibloader_orig_fontconfig +#define FcPatternVaBuild FcPatternVaBuild_dylibloader_orig_fontconfig +#define FcPatternBuild FcPatternBuild_dylibloader_orig_fontconfig +#define FcPatternFormat FcPatternFormat_dylibloader_orig_fontconfig +#define FcRangeCreateDouble FcRangeCreateDouble_dylibloader_orig_fontconfig +#define FcRangeCreateInteger FcRangeCreateInteger_dylibloader_orig_fontconfig +#define FcRangeDestroy FcRangeDestroy_dylibloader_orig_fontconfig +#define FcRangeCopy FcRangeCopy_dylibloader_orig_fontconfig +#define FcRangeGetDouble FcRangeGetDouble_dylibloader_orig_fontconfig +#define FcWeightFromOpenType FcWeightFromOpenType_dylibloader_orig_fontconfig +#define FcWeightToOpenType FcWeightToOpenType_dylibloader_orig_fontconfig +#define FcStrCopy FcStrCopy_dylibloader_orig_fontconfig +#define FcStrCopyFilename FcStrCopyFilename_dylibloader_orig_fontconfig +#define FcStrPlus FcStrPlus_dylibloader_orig_fontconfig +#define FcStrFree FcStrFree_dylibloader_orig_fontconfig +#define FcStrDowncase FcStrDowncase_dylibloader_orig_fontconfig +#define FcStrCmpIgnoreCase FcStrCmpIgnoreCase_dylibloader_orig_fontconfig +#define FcStrCmp FcStrCmp_dylibloader_orig_fontconfig +#define FcStrStrIgnoreCase FcStrStrIgnoreCase_dylibloader_orig_fontconfig +#define FcStrStr FcStrStr_dylibloader_orig_fontconfig +#define FcUtf8ToUcs4 FcUtf8ToUcs4_dylibloader_orig_fontconfig +#define FcUtf8Len FcUtf8Len_dylibloader_orig_fontconfig +#define FcUcs4ToUtf8 FcUcs4ToUtf8_dylibloader_orig_fontconfig +#define FcUtf16ToUcs4 FcUtf16ToUcs4_dylibloader_orig_fontconfig +#define FcUtf16Len FcUtf16Len_dylibloader_orig_fontconfig +#define FcStrDirname FcStrDirname_dylibloader_orig_fontconfig +#define FcStrBasename FcStrBasename_dylibloader_orig_fontconfig +#define FcStrSetCreate FcStrSetCreate_dylibloader_orig_fontconfig +#define FcStrSetMember FcStrSetMember_dylibloader_orig_fontconfig +#define FcStrSetEqual FcStrSetEqual_dylibloader_orig_fontconfig +#define FcStrSetAdd FcStrSetAdd_dylibloader_orig_fontconfig +#define FcStrSetAddFilename FcStrSetAddFilename_dylibloader_orig_fontconfig +#define FcStrSetDel FcStrSetDel_dylibloader_orig_fontconfig +#define FcStrSetDestroy FcStrSetDestroy_dylibloader_orig_fontconfig +#define FcStrListCreate FcStrListCreate_dylibloader_orig_fontconfig +#define FcStrListFirst FcStrListFirst_dylibloader_orig_fontconfig +#define FcStrListNext FcStrListNext_dylibloader_orig_fontconfig +#define FcStrListDone FcStrListDone_dylibloader_orig_fontconfig +#define FcConfigParseAndLoad FcConfigParseAndLoad_dylibloader_orig_fontconfig +#define FcConfigParseAndLoadFromMemory FcConfigParseAndLoadFromMemory_dylibloader_orig_fontconfig +#include <fontconfig/fontconfig.h> +#undef FcBlanksCreate +#undef FcBlanksDestroy +#undef FcBlanksAdd +#undef FcBlanksIsMember +#undef FcCacheDir +#undef FcCacheCopySet +#undef FcCacheSubdir +#undef FcCacheNumSubdir +#undef FcCacheNumFont +#undef FcDirCacheUnlink +#undef FcDirCacheValid +#undef FcDirCacheClean +#undef FcCacheCreateTagFile +#undef FcConfigHome +#undef FcConfigEnableHome +#undef FcConfigFilename +#undef FcConfigCreate +#undef FcConfigReference +#undef FcConfigDestroy +#undef FcConfigSetCurrent +#undef FcConfigGetCurrent +#undef FcConfigUptoDate +#undef FcConfigBuildFonts +#undef FcConfigGetFontDirs +#undef FcConfigGetConfigDirs +#undef FcConfigGetConfigFiles +#undef FcConfigGetCache +#undef FcConfigGetBlanks +#undef FcConfigGetCacheDirs +#undef FcConfigGetRescanInterval +#undef FcConfigSetRescanInterval +#undef FcConfigGetFonts +#undef FcConfigAppFontAddFile +#undef FcConfigAppFontAddDir +#undef FcConfigAppFontClear +#undef FcConfigSubstituteWithPat +#undef FcConfigSubstitute +#undef FcConfigGetSysRoot +#undef FcConfigSetSysRoot +#undef FcValuePrint +#undef FcPatternPrint +#undef FcFontSetPrint +#undef FcGetDefaultLangs +#undef FcDefaultSubstitute +#undef FcFileIsDir +#undef FcFileScan +#undef FcDirScan +#undef FcDirSave +#undef FcDirCacheLoad +#undef FcDirCacheRescan +#undef FcDirCacheRead +#undef FcDirCacheLoadFile +#undef FcDirCacheUnload +#undef FcFreeTypeQuery +#undef FcFontSetCreate +#undef FcFontSetDestroy +#undef FcFontSetAdd +#undef FcInitLoadConfig +#undef FcInitLoadConfigAndFonts +#undef FcInit +#undef FcFini +#undef FcGetVersion +#undef FcInitReinitialize +#undef FcInitBringUptoDate +#undef FcGetLangs +#undef FcLangNormalize +#undef FcLangGetCharSet +#undef FcLangSetCreate +#undef FcLangSetDestroy +#undef FcLangSetCopy +#undef FcLangSetAdd +#undef FcLangSetDel +#undef FcLangSetHasLang +#undef FcLangSetCompare +#undef FcLangSetContains +#undef FcLangSetEqual +#undef FcLangSetHash +#undef FcLangSetGetLangs +#undef FcLangSetUnion +#undef FcLangSetSubtract +#undef FcObjectSetCreate +#undef FcObjectSetAdd +#undef FcObjectSetDestroy +#undef FcObjectSetVaBuild +#undef FcObjectSetBuild +#undef FcFontSetList +#undef FcFontList +#undef FcAtomicCreate +#undef FcAtomicLock +#undef FcAtomicNewFile +#undef FcAtomicOrigFile +#undef FcAtomicReplaceOrig +#undef FcAtomicDeleteNew +#undef FcAtomicUnlock +#undef FcAtomicDestroy +#undef FcFontSetMatch +#undef FcFontMatch +#undef FcFontRenderPrepare +#undef FcFontSetSort +#undef FcFontSort +#undef FcFontSetSortDestroy +#undef FcMatrixCopy +#undef FcMatrixEqual +#undef FcMatrixMultiply +#undef FcMatrixRotate +#undef FcMatrixScale +#undef FcMatrixShear +#undef FcNameRegisterObjectTypes +#undef FcNameUnregisterObjectTypes +#undef FcNameGetObjectType +#undef FcNameRegisterConstants +#undef FcNameUnregisterConstants +#undef FcNameGetConstant +#undef FcNameConstant +#undef FcNameParse +#undef FcNameUnparse +#undef FcPatternCreate +#undef FcPatternDuplicate +#undef FcPatternReference +#undef FcPatternFilter +#undef FcValueDestroy +#undef FcValueEqual +#undef FcValueSave +#undef FcPatternDestroy +#undef FcPatternEqual +#undef FcPatternEqualSubset +#undef FcPatternHash +#undef FcPatternAdd +#undef FcPatternAddWeak +#undef FcPatternGet +#undef FcPatternGetWithBinding +#undef FcPatternDel +#undef FcPatternRemove +#undef FcPatternAddInteger +#undef FcPatternAddDouble +#undef FcPatternAddString +#undef FcPatternAddMatrix +#undef FcPatternAddCharSet +#undef FcPatternAddBool +#undef FcPatternAddLangSet +#undef FcPatternAddRange +#undef FcPatternGetInteger +#undef FcPatternGetDouble +#undef FcPatternGetString +#undef FcPatternGetMatrix +#undef FcPatternGetCharSet +#undef FcPatternGetBool +#undef FcPatternGetLangSet +#undef FcPatternGetRange +#undef FcPatternVaBuild +#undef FcPatternBuild +#undef FcPatternFormat +#undef FcRangeCreateDouble +#undef FcRangeCreateInteger +#undef FcRangeDestroy +#undef FcRangeCopy +#undef FcRangeGetDouble +#undef FcWeightFromOpenType +#undef FcWeightToOpenType +#undef FcStrCopy +#undef FcStrCopyFilename +#undef FcStrPlus +#undef FcStrFree +#undef FcStrDowncase +#undef FcStrCmpIgnoreCase +#undef FcStrCmp +#undef FcStrStrIgnoreCase +#undef FcStrStr +#undef FcUtf8ToUcs4 +#undef FcUtf8Len +#undef FcUcs4ToUtf8 +#undef FcUtf16ToUcs4 +#undef FcUtf16Len +#undef FcStrDirname +#undef FcStrBasename +#undef FcStrSetCreate +#undef FcStrSetMember +#undef FcStrSetEqual +#undef FcStrSetAdd +#undef FcStrSetAddFilename +#undef FcStrSetDel +#undef FcStrSetDestroy +#undef FcStrListCreate +#undef FcStrListFirst +#undef FcStrListNext +#undef FcStrListDone +#undef FcConfigParseAndLoad +#undef FcConfigParseAndLoadFromMemory +#ifdef __cplusplus +extern "C" { +#endif +#define FcBlanksCreate FcBlanksCreate_dylibloader_wrapper_fontconfig +#define FcBlanksDestroy FcBlanksDestroy_dylibloader_wrapper_fontconfig +#define FcBlanksAdd FcBlanksAdd_dylibloader_wrapper_fontconfig +#define FcBlanksIsMember FcBlanksIsMember_dylibloader_wrapper_fontconfig +#define FcCacheDir FcCacheDir_dylibloader_wrapper_fontconfig +#define FcCacheCopySet FcCacheCopySet_dylibloader_wrapper_fontconfig +#define FcCacheSubdir FcCacheSubdir_dylibloader_wrapper_fontconfig +#define FcCacheNumSubdir FcCacheNumSubdir_dylibloader_wrapper_fontconfig +#define FcCacheNumFont FcCacheNumFont_dylibloader_wrapper_fontconfig +#define FcDirCacheUnlink FcDirCacheUnlink_dylibloader_wrapper_fontconfig +#define FcDirCacheValid FcDirCacheValid_dylibloader_wrapper_fontconfig +#define FcDirCacheClean FcDirCacheClean_dylibloader_wrapper_fontconfig +#define FcCacheCreateTagFile FcCacheCreateTagFile_dylibloader_wrapper_fontconfig +#define FcConfigHome FcConfigHome_dylibloader_wrapper_fontconfig +#define FcConfigEnableHome FcConfigEnableHome_dylibloader_wrapper_fontconfig +#define FcConfigFilename FcConfigFilename_dylibloader_wrapper_fontconfig +#define FcConfigCreate FcConfigCreate_dylibloader_wrapper_fontconfig +#define FcConfigReference FcConfigReference_dylibloader_wrapper_fontconfig +#define FcConfigDestroy FcConfigDestroy_dylibloader_wrapper_fontconfig +#define FcConfigSetCurrent FcConfigSetCurrent_dylibloader_wrapper_fontconfig +#define FcConfigGetCurrent FcConfigGetCurrent_dylibloader_wrapper_fontconfig +#define FcConfigUptoDate FcConfigUptoDate_dylibloader_wrapper_fontconfig +#define FcConfigBuildFonts FcConfigBuildFonts_dylibloader_wrapper_fontconfig +#define FcConfigGetFontDirs FcConfigGetFontDirs_dylibloader_wrapper_fontconfig +#define FcConfigGetConfigDirs FcConfigGetConfigDirs_dylibloader_wrapper_fontconfig +#define FcConfigGetConfigFiles FcConfigGetConfigFiles_dylibloader_wrapper_fontconfig +#define FcConfigGetCache FcConfigGetCache_dylibloader_wrapper_fontconfig +#define FcConfigGetBlanks FcConfigGetBlanks_dylibloader_wrapper_fontconfig +#define FcConfigGetCacheDirs FcConfigGetCacheDirs_dylibloader_wrapper_fontconfig +#define FcConfigGetRescanInterval FcConfigGetRescanInterval_dylibloader_wrapper_fontconfig +#define FcConfigSetRescanInterval FcConfigSetRescanInterval_dylibloader_wrapper_fontconfig +#define FcConfigGetFonts FcConfigGetFonts_dylibloader_wrapper_fontconfig +#define FcConfigAppFontAddFile FcConfigAppFontAddFile_dylibloader_wrapper_fontconfig +#define FcConfigAppFontAddDir FcConfigAppFontAddDir_dylibloader_wrapper_fontconfig +#define FcConfigAppFontClear FcConfigAppFontClear_dylibloader_wrapper_fontconfig +#define FcConfigSubstituteWithPat FcConfigSubstituteWithPat_dylibloader_wrapper_fontconfig +#define FcConfigSubstitute FcConfigSubstitute_dylibloader_wrapper_fontconfig +#define FcConfigGetSysRoot FcConfigGetSysRoot_dylibloader_wrapper_fontconfig +#define FcConfigSetSysRoot FcConfigSetSysRoot_dylibloader_wrapper_fontconfig +#define FcValuePrint FcValuePrint_dylibloader_wrapper_fontconfig +#define FcPatternPrint FcPatternPrint_dylibloader_wrapper_fontconfig +#define FcFontSetPrint FcFontSetPrint_dylibloader_wrapper_fontconfig +#define FcGetDefaultLangs FcGetDefaultLangs_dylibloader_wrapper_fontconfig +#define FcDefaultSubstitute FcDefaultSubstitute_dylibloader_wrapper_fontconfig +#define FcFileIsDir FcFileIsDir_dylibloader_wrapper_fontconfig +#define FcFileScan FcFileScan_dylibloader_wrapper_fontconfig +#define FcDirScan FcDirScan_dylibloader_wrapper_fontconfig +#define FcDirSave FcDirSave_dylibloader_wrapper_fontconfig +#define FcDirCacheLoad FcDirCacheLoad_dylibloader_wrapper_fontconfig +#define FcDirCacheRescan FcDirCacheRescan_dylibloader_wrapper_fontconfig +#define FcDirCacheRead FcDirCacheRead_dylibloader_wrapper_fontconfig +#define FcDirCacheLoadFile FcDirCacheLoadFile_dylibloader_wrapper_fontconfig +#define FcDirCacheUnload FcDirCacheUnload_dylibloader_wrapper_fontconfig +#define FcFreeTypeQuery FcFreeTypeQuery_dylibloader_wrapper_fontconfig +#define FcFontSetCreate FcFontSetCreate_dylibloader_wrapper_fontconfig +#define FcFontSetDestroy FcFontSetDestroy_dylibloader_wrapper_fontconfig +#define FcFontSetAdd FcFontSetAdd_dylibloader_wrapper_fontconfig +#define FcInitLoadConfig FcInitLoadConfig_dylibloader_wrapper_fontconfig +#define FcInitLoadConfigAndFonts FcInitLoadConfigAndFonts_dylibloader_wrapper_fontconfig +#define FcInit FcInit_dylibloader_wrapper_fontconfig +#define FcFini FcFini_dylibloader_wrapper_fontconfig +#define FcGetVersion FcGetVersion_dylibloader_wrapper_fontconfig +#define FcInitReinitialize FcInitReinitialize_dylibloader_wrapper_fontconfig +#define FcInitBringUptoDate FcInitBringUptoDate_dylibloader_wrapper_fontconfig +#define FcGetLangs FcGetLangs_dylibloader_wrapper_fontconfig +#define FcLangNormalize FcLangNormalize_dylibloader_wrapper_fontconfig +#define FcLangGetCharSet FcLangGetCharSet_dylibloader_wrapper_fontconfig +#define FcLangSetCreate FcLangSetCreate_dylibloader_wrapper_fontconfig +#define FcLangSetDestroy FcLangSetDestroy_dylibloader_wrapper_fontconfig +#define FcLangSetCopy FcLangSetCopy_dylibloader_wrapper_fontconfig +#define FcLangSetAdd FcLangSetAdd_dylibloader_wrapper_fontconfig +#define FcLangSetDel FcLangSetDel_dylibloader_wrapper_fontconfig +#define FcLangSetHasLang FcLangSetHasLang_dylibloader_wrapper_fontconfig +#define FcLangSetCompare FcLangSetCompare_dylibloader_wrapper_fontconfig +#define FcLangSetContains FcLangSetContains_dylibloader_wrapper_fontconfig +#define FcLangSetEqual FcLangSetEqual_dylibloader_wrapper_fontconfig +#define FcLangSetHash FcLangSetHash_dylibloader_wrapper_fontconfig +#define FcLangSetGetLangs FcLangSetGetLangs_dylibloader_wrapper_fontconfig +#define FcLangSetUnion FcLangSetUnion_dylibloader_wrapper_fontconfig +#define FcLangSetSubtract FcLangSetSubtract_dylibloader_wrapper_fontconfig +#define FcObjectSetCreate FcObjectSetCreate_dylibloader_wrapper_fontconfig +#define FcObjectSetAdd FcObjectSetAdd_dylibloader_wrapper_fontconfig +#define FcObjectSetDestroy FcObjectSetDestroy_dylibloader_wrapper_fontconfig +#define FcObjectSetVaBuild FcObjectSetVaBuild_dylibloader_wrapper_fontconfig +#define FcObjectSetBuild FcObjectSetBuild_dylibloader_wrapper_fontconfig +#define FcFontSetList FcFontSetList_dylibloader_wrapper_fontconfig +#define FcFontList FcFontList_dylibloader_wrapper_fontconfig +#define FcAtomicCreate FcAtomicCreate_dylibloader_wrapper_fontconfig +#define FcAtomicLock FcAtomicLock_dylibloader_wrapper_fontconfig +#define FcAtomicNewFile FcAtomicNewFile_dylibloader_wrapper_fontconfig +#define FcAtomicOrigFile FcAtomicOrigFile_dylibloader_wrapper_fontconfig +#define FcAtomicReplaceOrig FcAtomicReplaceOrig_dylibloader_wrapper_fontconfig +#define FcAtomicDeleteNew FcAtomicDeleteNew_dylibloader_wrapper_fontconfig +#define FcAtomicUnlock FcAtomicUnlock_dylibloader_wrapper_fontconfig +#define FcAtomicDestroy FcAtomicDestroy_dylibloader_wrapper_fontconfig +#define FcFontSetMatch FcFontSetMatch_dylibloader_wrapper_fontconfig +#define FcFontMatch FcFontMatch_dylibloader_wrapper_fontconfig +#define FcFontRenderPrepare FcFontRenderPrepare_dylibloader_wrapper_fontconfig +#define FcFontSetSort FcFontSetSort_dylibloader_wrapper_fontconfig +#define FcFontSort FcFontSort_dylibloader_wrapper_fontconfig +#define FcFontSetSortDestroy FcFontSetSortDestroy_dylibloader_wrapper_fontconfig +#define FcMatrixCopy FcMatrixCopy_dylibloader_wrapper_fontconfig +#define FcMatrixEqual FcMatrixEqual_dylibloader_wrapper_fontconfig +#define FcMatrixMultiply FcMatrixMultiply_dylibloader_wrapper_fontconfig +#define FcMatrixRotate FcMatrixRotate_dylibloader_wrapper_fontconfig +#define FcMatrixScale FcMatrixScale_dylibloader_wrapper_fontconfig +#define FcMatrixShear FcMatrixShear_dylibloader_wrapper_fontconfig +#define FcNameRegisterObjectTypes FcNameRegisterObjectTypes_dylibloader_wrapper_fontconfig +#define FcNameUnregisterObjectTypes FcNameUnregisterObjectTypes_dylibloader_wrapper_fontconfig +#define FcNameGetObjectType FcNameGetObjectType_dylibloader_wrapper_fontconfig +#define FcNameRegisterConstants FcNameRegisterConstants_dylibloader_wrapper_fontconfig +#define FcNameUnregisterConstants FcNameUnregisterConstants_dylibloader_wrapper_fontconfig +#define FcNameGetConstant FcNameGetConstant_dylibloader_wrapper_fontconfig +#define FcNameConstant FcNameConstant_dylibloader_wrapper_fontconfig +#define FcNameParse FcNameParse_dylibloader_wrapper_fontconfig +#define FcNameUnparse FcNameUnparse_dylibloader_wrapper_fontconfig +#define FcPatternCreate FcPatternCreate_dylibloader_wrapper_fontconfig +#define FcPatternDuplicate FcPatternDuplicate_dylibloader_wrapper_fontconfig +#define FcPatternReference FcPatternReference_dylibloader_wrapper_fontconfig +#define FcPatternFilter FcPatternFilter_dylibloader_wrapper_fontconfig +#define FcValueDestroy FcValueDestroy_dylibloader_wrapper_fontconfig +#define FcValueEqual FcValueEqual_dylibloader_wrapper_fontconfig +#define FcValueSave FcValueSave_dylibloader_wrapper_fontconfig +#define FcPatternDestroy FcPatternDestroy_dylibloader_wrapper_fontconfig +#define FcPatternEqual FcPatternEqual_dylibloader_wrapper_fontconfig +#define FcPatternEqualSubset FcPatternEqualSubset_dylibloader_wrapper_fontconfig +#define FcPatternHash FcPatternHash_dylibloader_wrapper_fontconfig +#define FcPatternAdd FcPatternAdd_dylibloader_wrapper_fontconfig +#define FcPatternAddWeak FcPatternAddWeak_dylibloader_wrapper_fontconfig +#define FcPatternGet FcPatternGet_dylibloader_wrapper_fontconfig +#define FcPatternGetWithBinding FcPatternGetWithBinding_dylibloader_wrapper_fontconfig +#define FcPatternDel FcPatternDel_dylibloader_wrapper_fontconfig +#define FcPatternRemove FcPatternRemove_dylibloader_wrapper_fontconfig +#define FcPatternAddInteger FcPatternAddInteger_dylibloader_wrapper_fontconfig +#define FcPatternAddDouble FcPatternAddDouble_dylibloader_wrapper_fontconfig +#define FcPatternAddString FcPatternAddString_dylibloader_wrapper_fontconfig +#define FcPatternAddMatrix FcPatternAddMatrix_dylibloader_wrapper_fontconfig +#define FcPatternAddCharSet FcPatternAddCharSet_dylibloader_wrapper_fontconfig +#define FcPatternAddBool FcPatternAddBool_dylibloader_wrapper_fontconfig +#define FcPatternAddLangSet FcPatternAddLangSet_dylibloader_wrapper_fontconfig +#define FcPatternAddRange FcPatternAddRange_dylibloader_wrapper_fontconfig +#define FcPatternGetInteger FcPatternGetInteger_dylibloader_wrapper_fontconfig +#define FcPatternGetDouble FcPatternGetDouble_dylibloader_wrapper_fontconfig +#define FcPatternGetString FcPatternGetString_dylibloader_wrapper_fontconfig +#define FcPatternGetMatrix FcPatternGetMatrix_dylibloader_wrapper_fontconfig +#define FcPatternGetCharSet FcPatternGetCharSet_dylibloader_wrapper_fontconfig +#define FcPatternGetBool FcPatternGetBool_dylibloader_wrapper_fontconfig +#define FcPatternGetLangSet FcPatternGetLangSet_dylibloader_wrapper_fontconfig +#define FcPatternGetRange FcPatternGetRange_dylibloader_wrapper_fontconfig +#define FcPatternVaBuild FcPatternVaBuild_dylibloader_wrapper_fontconfig +#define FcPatternBuild FcPatternBuild_dylibloader_wrapper_fontconfig +#define FcPatternFormat FcPatternFormat_dylibloader_wrapper_fontconfig +#define FcRangeCreateDouble FcRangeCreateDouble_dylibloader_wrapper_fontconfig +#define FcRangeCreateInteger FcRangeCreateInteger_dylibloader_wrapper_fontconfig +#define FcRangeDestroy FcRangeDestroy_dylibloader_wrapper_fontconfig +#define FcRangeCopy FcRangeCopy_dylibloader_wrapper_fontconfig +#define FcRangeGetDouble FcRangeGetDouble_dylibloader_wrapper_fontconfig +#define FcWeightFromOpenType FcWeightFromOpenType_dylibloader_wrapper_fontconfig +#define FcWeightToOpenType FcWeightToOpenType_dylibloader_wrapper_fontconfig +#define FcStrCopy FcStrCopy_dylibloader_wrapper_fontconfig +#define FcStrCopyFilename FcStrCopyFilename_dylibloader_wrapper_fontconfig +#define FcStrPlus FcStrPlus_dylibloader_wrapper_fontconfig +#define FcStrFree FcStrFree_dylibloader_wrapper_fontconfig +#define FcStrDowncase FcStrDowncase_dylibloader_wrapper_fontconfig +#define FcStrCmpIgnoreCase FcStrCmpIgnoreCase_dylibloader_wrapper_fontconfig +#define FcStrCmp FcStrCmp_dylibloader_wrapper_fontconfig +#define FcStrStrIgnoreCase FcStrStrIgnoreCase_dylibloader_wrapper_fontconfig +#define FcStrStr FcStrStr_dylibloader_wrapper_fontconfig +#define FcUtf8ToUcs4 FcUtf8ToUcs4_dylibloader_wrapper_fontconfig +#define FcUtf8Len FcUtf8Len_dylibloader_wrapper_fontconfig +#define FcUcs4ToUtf8 FcUcs4ToUtf8_dylibloader_wrapper_fontconfig +#define FcUtf16ToUcs4 FcUtf16ToUcs4_dylibloader_wrapper_fontconfig +#define FcUtf16Len FcUtf16Len_dylibloader_wrapper_fontconfig +#define FcStrDirname FcStrDirname_dylibloader_wrapper_fontconfig +#define FcStrBasename FcStrBasename_dylibloader_wrapper_fontconfig +#define FcStrSetCreate FcStrSetCreate_dylibloader_wrapper_fontconfig +#define FcStrSetMember FcStrSetMember_dylibloader_wrapper_fontconfig +#define FcStrSetEqual FcStrSetEqual_dylibloader_wrapper_fontconfig +#define FcStrSetAdd FcStrSetAdd_dylibloader_wrapper_fontconfig +#define FcStrSetAddFilename FcStrSetAddFilename_dylibloader_wrapper_fontconfig +#define FcStrSetDel FcStrSetDel_dylibloader_wrapper_fontconfig +#define FcStrSetDestroy FcStrSetDestroy_dylibloader_wrapper_fontconfig +#define FcStrListCreate FcStrListCreate_dylibloader_wrapper_fontconfig +#define FcStrListFirst FcStrListFirst_dylibloader_wrapper_fontconfig +#define FcStrListNext FcStrListNext_dylibloader_wrapper_fontconfig +#define FcStrListDone FcStrListDone_dylibloader_wrapper_fontconfig +#define FcConfigParseAndLoad FcConfigParseAndLoad_dylibloader_wrapper_fontconfig +#define FcConfigParseAndLoadFromMemory FcConfigParseAndLoadFromMemory_dylibloader_wrapper_fontconfig +extern FcBlanks* (*FcBlanksCreate_dylibloader_wrapper_fontconfig)( void); +extern void (*FcBlanksDestroy_dylibloader_wrapper_fontconfig)( FcBlanks*); +extern FcBool (*FcBlanksAdd_dylibloader_wrapper_fontconfig)( FcBlanks*, FcChar32); +extern FcBool (*FcBlanksIsMember_dylibloader_wrapper_fontconfig)( FcBlanks*, FcChar32); +extern const FcChar8* (*FcCacheDir_dylibloader_wrapper_fontconfig)(const FcCache*); +extern FcFontSet* (*FcCacheCopySet_dylibloader_wrapper_fontconfig)(const FcCache*); +extern const FcChar8* (*FcCacheSubdir_dylibloader_wrapper_fontconfig)(const FcCache*, int); +extern int (*FcCacheNumSubdir_dylibloader_wrapper_fontconfig)(const FcCache*); +extern int (*FcCacheNumFont_dylibloader_wrapper_fontconfig)(const FcCache*); +extern FcBool (*FcDirCacheUnlink_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*); +extern FcBool (*FcDirCacheValid_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcBool (*FcDirCacheClean_dylibloader_wrapper_fontconfig)(const FcChar8*, FcBool); +extern void (*FcCacheCreateTagFile_dylibloader_wrapper_fontconfig)(const FcConfig*); +extern FcChar8* (*FcConfigHome_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcConfigEnableHome_dylibloader_wrapper_fontconfig)( FcBool); +extern FcChar8* (*FcConfigFilename_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcConfig* (*FcConfigCreate_dylibloader_wrapper_fontconfig)( void); +extern FcConfig* (*FcConfigReference_dylibloader_wrapper_fontconfig)( FcConfig*); +extern void (*FcConfigDestroy_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcBool (*FcConfigSetCurrent_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcConfig* (*FcConfigGetCurrent_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcConfigUptoDate_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcBool (*FcConfigBuildFonts_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcStrList* (*FcConfigGetFontDirs_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcStrList* (*FcConfigGetConfigDirs_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcStrList* (*FcConfigGetConfigFiles_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcChar8* (*FcConfigGetCache_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcBlanks* (*FcConfigGetBlanks_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcStrList* (*FcConfigGetCacheDirs_dylibloader_wrapper_fontconfig)(const FcConfig*); +extern int (*FcConfigGetRescanInterval_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcBool (*FcConfigSetRescanInterval_dylibloader_wrapper_fontconfig)( FcConfig*, int); +extern FcFontSet* (*FcConfigGetFonts_dylibloader_wrapper_fontconfig)( FcConfig*, FcSetName); +extern FcBool (*FcConfigAppFontAddFile_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +extern FcBool (*FcConfigAppFontAddDir_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +extern void (*FcConfigAppFontClear_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcBool (*FcConfigSubstituteWithPat_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcPattern*, FcMatchKind); +extern FcBool (*FcConfigSubstitute_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcMatchKind); +extern const FcChar8* (*FcConfigGetSysRoot_dylibloader_wrapper_fontconfig)(const FcConfig*); +extern void (*FcConfigSetSysRoot_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +extern void (*FcValuePrint_dylibloader_wrapper_fontconfig)(const FcValue); +extern void (*FcPatternPrint_dylibloader_wrapper_fontconfig)(const FcPattern*); +extern void (*FcFontSetPrint_dylibloader_wrapper_fontconfig)(const FcFontSet*); +extern FcStrSet* (*FcGetDefaultLangs_dylibloader_wrapper_fontconfig)( void); +extern void (*FcDefaultSubstitute_dylibloader_wrapper_fontconfig)( FcPattern*); +extern FcBool (*FcFileIsDir_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcBool (*FcFileScan_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*, FcFileCache*, FcBlanks*,const FcChar8*, FcBool); +extern FcBool (*FcDirScan_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*, FcFileCache*, FcBlanks*,const FcChar8*, FcBool); +extern FcBool (*FcDirSave_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*,const FcChar8*); +extern FcCache* (*FcDirCacheLoad_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*, FcChar8**); +extern FcCache* (*FcDirCacheRescan_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*); +extern FcCache* (*FcDirCacheRead_dylibloader_wrapper_fontconfig)(const FcChar8*, FcBool, FcConfig*); +extern FcCache* (*FcDirCacheLoadFile_dylibloader_wrapper_fontconfig)(const FcChar8*,struct stat*); +extern void (*FcDirCacheUnload_dylibloader_wrapper_fontconfig)( FcCache*); +extern FcPattern* (*FcFreeTypeQuery_dylibloader_wrapper_fontconfig)(const FcChar8*, int, FcBlanks*, int*); +extern FcFontSet* (*FcFontSetCreate_dylibloader_wrapper_fontconfig)( void); +extern void (*FcFontSetDestroy_dylibloader_wrapper_fontconfig)( FcFontSet*); +extern FcBool (*FcFontSetAdd_dylibloader_wrapper_fontconfig)( FcFontSet*, FcPattern*); +extern FcConfig* (*FcInitLoadConfig_dylibloader_wrapper_fontconfig)( void); +extern FcConfig* (*FcInitLoadConfigAndFonts_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcInit_dylibloader_wrapper_fontconfig)( void); +extern void (*FcFini_dylibloader_wrapper_fontconfig)( void); +extern int (*FcGetVersion_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcInitReinitialize_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcInitBringUptoDate_dylibloader_wrapper_fontconfig)( void); +extern FcStrSet* (*FcGetLangs_dylibloader_wrapper_fontconfig)( void); +extern FcChar8* (*FcLangNormalize_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern const FcCharSet* (*FcLangGetCharSet_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcLangSet* (*FcLangSetCreate_dylibloader_wrapper_fontconfig)( void); +extern void (*FcLangSetDestroy_dylibloader_wrapper_fontconfig)( FcLangSet*); +extern FcLangSet* (*FcLangSetCopy_dylibloader_wrapper_fontconfig)(const FcLangSet*); +extern FcBool (*FcLangSetAdd_dylibloader_wrapper_fontconfig)( FcLangSet*,const FcChar8*); +extern FcBool (*FcLangSetDel_dylibloader_wrapper_fontconfig)( FcLangSet*,const FcChar8*); +extern FcLangResult (*FcLangSetHasLang_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcChar8*); +extern FcLangResult (*FcLangSetCompare_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +extern FcBool (*FcLangSetContains_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +extern FcBool (*FcLangSetEqual_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +extern FcChar32 (*FcLangSetHash_dylibloader_wrapper_fontconfig)(const FcLangSet*); +extern FcStrSet* (*FcLangSetGetLangs_dylibloader_wrapper_fontconfig)(const FcLangSet*); +extern FcLangSet* (*FcLangSetUnion_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +extern FcLangSet* (*FcLangSetSubtract_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +extern FcObjectSet* (*FcObjectSetCreate_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcObjectSetAdd_dylibloader_wrapper_fontconfig)( FcObjectSet*,const char*); +extern void (*FcObjectSetDestroy_dylibloader_wrapper_fontconfig)( FcObjectSet*); +extern FcObjectSet* (*FcObjectSetVaBuild_dylibloader_wrapper_fontconfig)(const char*, va_list); +extern FcObjectSet* (*FcObjectSetBuild_dylibloader_wrapper_fontconfig)(const char*,...); +extern FcFontSet* (*FcFontSetList_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcObjectSet*); +extern FcFontSet* (*FcFontList_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcObjectSet*); +extern FcAtomic* (*FcAtomicCreate_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcBool (*FcAtomicLock_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern FcChar8* (*FcAtomicNewFile_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern FcChar8* (*FcAtomicOrigFile_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern FcBool (*FcAtomicReplaceOrig_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern void (*FcAtomicDeleteNew_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern void (*FcAtomicUnlock_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern void (*FcAtomicDestroy_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern FcPattern* (*FcFontSetMatch_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcResult*); +extern FcPattern* (*FcFontMatch_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcResult*); +extern FcPattern* (*FcFontRenderPrepare_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcPattern*); +extern FcFontSet* (*FcFontSetSort_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcBool, FcCharSet**, FcResult*); +extern FcFontSet* (*FcFontSort_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcBool, FcCharSet**, FcResult*); +extern void (*FcFontSetSortDestroy_dylibloader_wrapper_fontconfig)( FcFontSet*); +extern FcMatrix* (*FcMatrixCopy_dylibloader_wrapper_fontconfig)(const FcMatrix*); +extern FcBool (*FcMatrixEqual_dylibloader_wrapper_fontconfig)(const FcMatrix*,const FcMatrix*); +extern void (*FcMatrixMultiply_dylibloader_wrapper_fontconfig)( FcMatrix*,const FcMatrix*,const FcMatrix*); +extern void (*FcMatrixRotate_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +extern void (*FcMatrixScale_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +extern void (*FcMatrixShear_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +extern FcBool (*FcNameRegisterObjectTypes_dylibloader_wrapper_fontconfig)(const FcObjectType*, int); +extern FcBool (*FcNameUnregisterObjectTypes_dylibloader_wrapper_fontconfig)(const FcObjectType*, int); +extern const FcObjectType* (*FcNameGetObjectType_dylibloader_wrapper_fontconfig)(const char*); +extern FcBool (*FcNameRegisterConstants_dylibloader_wrapper_fontconfig)(const FcConstant*, int); +extern FcBool (*FcNameUnregisterConstants_dylibloader_wrapper_fontconfig)(const FcConstant*, int); +extern const FcConstant* (*FcNameGetConstant_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcBool (*FcNameConstant_dylibloader_wrapper_fontconfig)(const FcChar8*, int*); +extern FcPattern* (*FcNameParse_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcChar8* (*FcNameUnparse_dylibloader_wrapper_fontconfig)( FcPattern*); +extern FcPattern* (*FcPatternCreate_dylibloader_wrapper_fontconfig)( void); +extern FcPattern* (*FcPatternDuplicate_dylibloader_wrapper_fontconfig)(const FcPattern*); +extern void (*FcPatternReference_dylibloader_wrapper_fontconfig)( FcPattern*); +extern FcPattern* (*FcPatternFilter_dylibloader_wrapper_fontconfig)( FcPattern*,const FcObjectSet*); +extern void (*FcValueDestroy_dylibloader_wrapper_fontconfig)( FcValue); +extern FcBool (*FcValueEqual_dylibloader_wrapper_fontconfig)( FcValue, FcValue); +extern FcValue (*FcValueSave_dylibloader_wrapper_fontconfig)( FcValue); +extern void (*FcPatternDestroy_dylibloader_wrapper_fontconfig)( FcPattern*); +extern FcBool (*FcPatternEqual_dylibloader_wrapper_fontconfig)(const FcPattern*,const FcPattern*); +extern FcBool (*FcPatternEqualSubset_dylibloader_wrapper_fontconfig)(const FcPattern*,const FcPattern*,const FcObjectSet*); +extern FcChar32 (*FcPatternHash_dylibloader_wrapper_fontconfig)(const FcPattern*); +extern FcBool (*FcPatternAdd_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcValue, FcBool); +extern FcBool (*FcPatternAddWeak_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcValue, FcBool); +extern FcResult (*FcPatternGet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcValue*); +extern FcResult (*FcPatternGetWithBinding_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcValue*, FcValueBinding*); +extern FcBool (*FcPatternDel_dylibloader_wrapper_fontconfig)( FcPattern*,const char*); +extern FcBool (*FcPatternRemove_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, int); +extern FcBool (*FcPatternAddInteger_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, int); +extern FcBool (*FcPatternAddDouble_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, double); +extern FcBool (*FcPatternAddString_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcChar8*); +extern FcBool (*FcPatternAddMatrix_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcMatrix*); +extern FcBool (*FcPatternAddCharSet_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcCharSet*); +extern FcBool (*FcPatternAddBool_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcBool); +extern FcBool (*FcPatternAddLangSet_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcLangSet*); +extern FcBool (*FcPatternAddRange_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcRange*); +extern FcResult (*FcPatternGetInteger_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, int*); +extern FcResult (*FcPatternGetDouble_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, double*); +extern FcResult (*FcPatternGetString_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcChar8**); +extern FcResult (*FcPatternGetMatrix_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcMatrix**); +extern FcResult (*FcPatternGetCharSet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcCharSet**); +extern FcResult (*FcPatternGetBool_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcBool*); +extern FcResult (*FcPatternGetLangSet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcLangSet**); +extern FcResult (*FcPatternGetRange_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcRange**); +extern FcPattern* (*FcPatternVaBuild_dylibloader_wrapper_fontconfig)( FcPattern*, va_list); +extern FcPattern* (*FcPatternBuild_dylibloader_wrapper_fontconfig)( FcPattern*,...); +extern FcChar8* (*FcPatternFormat_dylibloader_wrapper_fontconfig)( FcPattern*,const FcChar8*); +extern FcRange* (*FcRangeCreateDouble_dylibloader_wrapper_fontconfig)( double, double); +extern FcRange* (*FcRangeCreateInteger_dylibloader_wrapper_fontconfig)( FcChar32, FcChar32); +extern void (*FcRangeDestroy_dylibloader_wrapper_fontconfig)( FcRange*); +extern FcRange* (*FcRangeCopy_dylibloader_wrapper_fontconfig)(const FcRange*); +extern FcBool (*FcRangeGetDouble_dylibloader_wrapper_fontconfig)(const FcRange*, double*, double*); +extern int (*FcWeightFromOpenType_dylibloader_wrapper_fontconfig)( int); +extern int (*FcWeightToOpenType_dylibloader_wrapper_fontconfig)( int); +extern FcChar8* (*FcStrCopy_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcChar8* (*FcStrCopyFilename_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcChar8* (*FcStrPlus_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +extern void (*FcStrFree_dylibloader_wrapper_fontconfig)( FcChar8*); +extern FcChar8* (*FcStrDowncase_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern int (*FcStrCmpIgnoreCase_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +extern int (*FcStrCmp_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +extern const FcChar8* (*FcStrStrIgnoreCase_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +extern const FcChar8* (*FcStrStr_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +extern int (*FcUtf8ToUcs4_dylibloader_wrapper_fontconfig)(const FcChar8*, FcChar32*, int); +extern FcBool (*FcUtf8Len_dylibloader_wrapper_fontconfig)(const FcChar8*, int, int*, int*); +extern int (*FcUcs4ToUtf8_dylibloader_wrapper_fontconfig)( FcChar32, FcChar8 [6]); +extern int (*FcUtf16ToUcs4_dylibloader_wrapper_fontconfig)(const FcChar8*, FcEndian, FcChar32*, int); +extern FcBool (*FcUtf16Len_dylibloader_wrapper_fontconfig)(const FcChar8*, FcEndian, int, int*, int*); +extern FcChar8* (*FcStrDirname_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcChar8* (*FcStrBasename_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcStrSet* (*FcStrSetCreate_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcStrSetMember_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +extern FcBool (*FcStrSetEqual_dylibloader_wrapper_fontconfig)( FcStrSet*, FcStrSet*); +extern FcBool (*FcStrSetAdd_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +extern FcBool (*FcStrSetAddFilename_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +extern FcBool (*FcStrSetDel_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +extern void (*FcStrSetDestroy_dylibloader_wrapper_fontconfig)( FcStrSet*); +extern FcStrList* (*FcStrListCreate_dylibloader_wrapper_fontconfig)( FcStrSet*); +extern void (*FcStrListFirst_dylibloader_wrapper_fontconfig)( FcStrList*); +extern FcChar8* (*FcStrListNext_dylibloader_wrapper_fontconfig)( FcStrList*); +extern void (*FcStrListDone_dylibloader_wrapper_fontconfig)( FcStrList*); +extern FcBool (*FcConfigParseAndLoad_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*, FcBool); +extern FcBool (*FcConfigParseAndLoadFromMemory_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*, FcBool); +int initialize_fontconfig(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/freedesktop_screensaver.cpp b/platform/linuxbsd/freedesktop_screensaver.cpp index 1e93334e40..fa3f7fbfea 100644 --- a/platform/linuxbsd/freedesktop_screensaver.cpp +++ b/platform/linuxbsd/freedesktop_screensaver.cpp @@ -34,7 +34,7 @@ #include "core/config/project_settings.h" -#include <dbus/dbus.h> +#include "dbus-so_wrap.h" #define BUS_OBJECT_NAME "org.freedesktop.ScreenSaver" #define BUS_OBJECT_PATH "/org/freedesktop/ScreenSaver" @@ -126,4 +126,13 @@ void FreeDesktopScreenSaver::uninhibit() { dbus_connection_unref(bus); } +FreeDesktopScreenSaver::FreeDesktopScreenSaver() { +#ifdef DEBUG_ENABLED + int dylibloader_verbose = 1; +#else + int dylibloader_verbose = 0; +#endif + unsupported = (initialize_dbus(dylibloader_verbose) != 0); +} + #endif // DBUS_ENABLED diff --git a/platform/linuxbsd/freedesktop_screensaver.h b/platform/linuxbsd/freedesktop_screensaver.h index 1b632b9103..1a8b010cd5 100644 --- a/platform/linuxbsd/freedesktop_screensaver.h +++ b/platform/linuxbsd/freedesktop_screensaver.h @@ -33,7 +33,6 @@ #ifdef DBUS_ENABLED -#include <dbus/dbus.h> #include <stdint.h> class FreeDesktopScreenSaver { @@ -42,7 +41,7 @@ private: bool unsupported = false; public: - FreeDesktopScreenSaver() {} + FreeDesktopScreenSaver(); void inhibit(); void uninhibit(); }; diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index b73d4dc626..e306c1054b 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -52,6 +52,10 @@ #include <sys/types.h> #include <unistd.h> +#ifdef FONTCONFIG_ENABLED +#include "fontconfig-so_wrap.h" +#endif + void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) { const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" }; @@ -327,6 +331,98 @@ uint64_t OS_LinuxBSD::get_embedded_pck_offset() const { return off; } +Vector<String> OS_LinuxBSD::get_system_fonts() const { +#ifdef FONTCONFIG_ENABLED + if (!font_config_initialized) { + ERR_FAIL_V_MSG(Vector<String>(), "Unable to load fontconfig, system font support is disabled."); + } + HashSet<String> font_names; + Vector<String> ret; + + FcConfig *config = FcInitLoadConfigAndFonts(); + ERR_FAIL_COND_V(!config, ret); + + FcObjectSet *object_set = FcObjectSetBuild(FC_FAMILY, nullptr); + ERR_FAIL_COND_V(!object_set, ret); + + static const char *allowed_formats[] = { "TrueType", "CFF" }; + for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) { + FcPattern *pattern = FcPatternCreate(); + ERR_CONTINUE(!pattern); + + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast<const FcChar8 *>(allowed_formats[i])); + + FcFontSet *font_set = FcFontList(config, pattern, object_set); + if (font_set) { + for (int j = 0; j < font_set->nfont; j++) { + char *family_name = nullptr; + if (FcPatternGetString(font_set->fonts[j], FC_FAMILY, 0, reinterpret_cast<FcChar8 **>(&family_name)) == FcResultMatch) { + if (family_name) { + font_names.insert(String::utf8(family_name)); + } + } + } + FcFontSetDestroy(font_set); + } + FcPatternDestroy(pattern); + } + FcObjectSetDestroy(object_set); + + for (const String &E : font_names) { + ret.push_back(E); + } + return ret; +#else + ERR_FAIL_V_MSG(Vector<String>(), "Godot was compiled without fontconfig, system font support is disabled."); +#endif +} + +String OS_LinuxBSD::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { +#ifdef FONTCONFIG_ENABLED + if (!font_config_initialized) { + ERR_FAIL_V_MSG(String(), "Unable to load fontconfig, system font support is disabled."); + } + + String ret; + + FcConfig *config = FcInitLoadConfigAndFonts(); + ERR_FAIL_COND_V(!config, ret); + + FcObjectSet *object_set = FcObjectSetBuild(FC_FAMILY, FC_FILE, nullptr); + ERR_FAIL_COND_V(!object_set, ret); + + FcPattern *pattern = FcPatternCreate(); + if (pattern) { + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(p_font_name.utf8().get_data())); + FcPatternAddInteger(pattern, FC_WEIGHT, p_bold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); + FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcResult result; + FcPattern *match = FcFontMatch(0, pattern, &result); + if (match) { + char *file_name = nullptr; + if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast<FcChar8 **>(&file_name)) == FcResultMatch) { + if (file_name) { + ret = String::utf8(file_name); + } + } + + FcPatternDestroy(match); + } + FcPatternDestroy(pattern); + } + FcObjectSetDestroy(object_set); + return ret; +#else + ERR_FAIL_V_MSG(String(), "Godot was compiled without fontconfig, system font support is disabled."); +#endif +} + String OS_LinuxBSD::get_config_path() const { if (has_environment("XDG_CONFIG_HOME")) { if (get_environment("XDG_CONFIG_HOME").is_absolute_path()) { @@ -644,4 +740,13 @@ OS_LinuxBSD::OS_LinuxBSD() { #ifdef X11_ENABLED DisplayServerX11::register_x11_driver(); #endif + +#ifdef FONTCONFIG_ENABLED +#ifdef DEBUG_ENABLED + int dylibloader_verbose = 1; +#else + int dylibloader_verbose = 0; +#endif + font_config_initialized = (initialize_fontconfig(dylibloader_verbose) == 0); +#endif // FONTCONFIG_ENABLED } diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h index 13c07842fb..cc4e91e885 100644 --- a/platform/linuxbsd/os_linuxbsd.h +++ b/platform/linuxbsd/os_linuxbsd.h @@ -45,6 +45,10 @@ class OS_LinuxBSD : public OS_Unix { bool force_quit; +#ifdef FONTCONFIG_ENABLED + bool font_config_initialized = false; +#endif + #ifdef JOYDEV_ENABLED JoypadLinux *joypad = nullptr; #endif @@ -80,6 +84,9 @@ public: virtual uint64_t get_embedded_pck_offset() const override; + virtual Vector<String> get_system_fonts() const override; + virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; + virtual String get_config_path() const override; virtual String get_data_path() const override; virtual String get_cache_path() const override; diff --git a/platform/macos/dir_access_macos.h b/platform/macos/dir_access_macos.h index 1ac1b995de..920e69ef3e 100644 --- a/platform/macos/dir_access_macos.h +++ b/platform/macos/dir_access_macos.h @@ -43,12 +43,12 @@ class DirAccessMacOS : public DirAccessUnix { protected: - virtual String fix_unicode_name(const char *p_name) const; + virtual String fix_unicode_name(const char *p_name) const override; - virtual int get_drive_count(); - virtual String get_drive(int p_drive); + virtual int get_drive_count() override; + virtual String get_drive(int p_drive) override; - virtual bool is_hidden(const String &p_name); + virtual bool is_hidden(const String &p_name) override; }; #endif // UNIX ENABLED || LIBC_FILEIO_ENABLED diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index 41031ec81b..54c479fc81 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -50,6 +50,7 @@ #import <ApplicationServices/ApplicationServices.h> #import <CoreVideo/CoreVideo.h> #import <Foundation/Foundation.h> +#import <IOKit/pwr_mgt/IOPMLib.h> #undef BitMap #undef CursorShape @@ -171,6 +172,8 @@ private: HashMap<WindowID, WindowData> windows; + IOPMAssertionID screen_keep_on_assertion = kIOPMNullAssertionID; + const NSMenu *_get_menu_root(const String &p_menu_root) const; NSMenu *_get_menu_root(const String &p_menu_root); @@ -299,6 +302,8 @@ public: virtual float screen_get_max_scale() const override; virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual void screen_set_keep_on(bool p_enable) override; + virtual bool screen_is_kept_on() const override; virtual Vector<int> get_window_list() const override; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 07ba5d7497..a49485154b 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -39,6 +39,7 @@ #include "tts_macos.h" +#include "core/config/project_settings.h" #include "core/io/marshalls.h" #include "core/math/geometry_2d.h" #include "core/os/keyboard.h" @@ -334,7 +335,7 @@ void DisplayServerMacOS::_dispatch_input_event(const Ref<InputEvent> &p_event) { if (windows.has(E->get())) { Callable callable = windows[E->get()].input_event_callback; if (callable.is_valid()) { - callable.call((const Variant **)&evp, 1, ret, ce); + callable.callp((const Variant **)&evp, 1, ret, ce); } } in_dispatch_input_event = false; @@ -348,7 +349,7 @@ void DisplayServerMacOS::_dispatch_input_event(const Ref<InputEvent> &p_event) { if (windows.has(event_from_window->get_window_id())) { Callable callable = windows[event_from_window->get_window_id()].input_event_callback; if (callable.is_valid()) { - callable.call((const Variant **)&evp, 1, ret, ce); + callable.callp((const Variant **)&evp, 1, ret, ce); } } } else { @@ -356,7 +357,7 @@ void DisplayServerMacOS::_dispatch_input_event(const Ref<InputEvent> &p_event) { for (KeyValue<WindowID, WindowData> &E : windows) { Callable callable = E.value.input_event_callback; if (callable.is_valid()) { - callable.call((const Variant **)&evp, 1, ret, ce); + callable.callp((const Variant **)&evp, 1, ret, ce); } } } @@ -555,7 +556,7 @@ void DisplayServerMacOS::menu_callback(id p_sender) { Variant *tagp = &tag; Variant ret; Callable::CallError ce; - value->callback.call((const Variant **)&tagp, 1, ret, ce); + value->callback.callp((const Variant **)&tagp, 1, ret, ce); } } } @@ -596,7 +597,7 @@ void DisplayServerMacOS::send_window_event(const WindowData &wd, WindowEvent p_e Variant *eventp = &event; Variant ret; Callable::CallError ce; - wd.event_callback.call((const Variant **)&eventp, 1, ret, ce); + wd.event_callback.callp((const Variant **)&eventp, 1, ret, ce); } } @@ -1522,7 +1523,7 @@ Error DisplayServerMacOS::dialog_show(String p_title, String p_description, Vect Variant *buttonp = &button; Variant ret; Callable::CallError ce; - p_callback.call((const Variant **)&buttonp, 1, ret, ce); + p_callback.callp((const Variant **)&buttonp, 1, ret, ce); } return OK; @@ -1554,7 +1555,7 @@ Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description Variant *textp = &text; Variant ret; Callable::CallError ce; - p_callback.call((const Variant **)&textp, 1, ret, ce); + p_callback.callp((const Variant **)&textp, 1, ret, ce); } return OK; @@ -1891,6 +1892,24 @@ float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const { return SCREEN_REFRESH_RATE_FALLBACK; } +bool DisplayServerMacOS::screen_is_kept_on() const { + return (screen_keep_on_assertion); +} + +void DisplayServerMacOS::screen_set_keep_on(bool p_enable) { + if (screen_keep_on_assertion) { + IOPMAssertionRelease(screen_keep_on_assertion); + screen_keep_on_assertion = kIOPMNullAssertionID; + } + + if (p_enable) { + String app_name_string = ProjectSettings::get_singleton()->get("application/config/name"); + NSString *name = [NSString stringWithUTF8String:(app_name_string.is_empty() ? "Godot Engine" : app_name_string.utf8().get_data())]; + NSString *reason = @"Godot Engine running with display/window/energy_saving/keep_screen_on = true"; + IOPMAssertionCreateWithDescription(kIOPMAssertPreventUserIdleDisplaySleep, (__bridge CFStringRef)name, (__bridge CFStringRef)reason, (__bridge CFStringRef)reason, nullptr, 0, nullptr, &screen_keep_on_assertion); + } +} + Vector<DisplayServer::WindowID> DisplayServerMacOS::get_window_list() const { _THREAD_SAFE_METHOD_ @@ -3266,9 +3285,16 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM RendererCompositorRD::make_current(); } #endif + + screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); } DisplayServerMacOS::~DisplayServerMacOS() { + if (screen_keep_on_assertion) { + IOPMAssertionRelease(screen_keep_on_assertion); + screen_keep_on_assertion = kIOPMNullAssertionID; + } + // Destroy all windows. for (HashMap<WindowID, WindowData>::Iterator E = windows.begin(); E;) { HashMap<WindowID, WindowData>::Iterator F = E; diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp index fd0781ac50..bcc2636c07 100644 --- a/platform/macos/export/export_plugin.cpp +++ b/platform/macos/export/export_plugin.cpp @@ -32,12 +32,13 @@ #include "codesign.h" +#include "core/string/translation.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "modules/modules_enabled.gen.h" // For regex. -void EditorExportPlatformMacOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { +void EditorExportPlatformMacOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { if (p_preset->get("texture_format/s3tc")) { r_features->push_back("s3tc"); } @@ -47,8 +48,7 @@ void EditorExportPlatformMacOS::get_preset_features(const Ref<EditorExportPreset if (p_preset->get("texture_format/etc2")) { r_features->push_back("etc2"); } - - r_features->push_back("64"); + r_features->push_back(p_preset->get("binary_format/architecture")); } bool EditorExportPlatformMacOS::get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const { @@ -69,6 +69,7 @@ bool EditorExportPlatformMacOS::get_export_option_visibility(const String &p_opt } void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options) { + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "universal,x86_64,arm64", PROPERTY_USAGE_STORAGE), "universal")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); @@ -254,7 +255,7 @@ void EditorExportPlatformMacOS::_make_icon(const Ref<Image> &p_icon, Vector<uint // Encode PNG icon. it->set_image(copy); String path = EditorPaths::get_singleton()->get_cache_dir().plus_file("icon.png"); - ResourceSaver::save(path, it); + ResourceSaver::save(it, path); { Ref<FileAccess> f = FileAccess::open(path, FileAccess::READ); @@ -766,7 +767,8 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p int ret = unzGoToFirstFile(src_pkg_zip); - String binary_to_use = "godot_macos_" + String(p_debug ? "debug" : "release") + ".universal"; + String architecture = p_preset->get("binary_format/architecture"); + String binary_to_use = "godot_macos_" + String(p_debug ? "debug" : "release") + "." + architecture; String pkg_name; if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") { @@ -1064,19 +1066,19 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p } if (data.size() > 0) { - if (file.find("/data.mono.macos.release_debug.universal/") != -1) { + if (file.find("/data.mono.macos.release_debug." + architecture + "/") != -1) { if (!p_debug) { ret = unzGoToNextFile(src_pkg_zip); continue; // skip } - file = file.replace("/data.mono.macos.release_debug.universal/", "/GodotSharp/"); + file = file.replace("/data.mono.macos.release_debug." + architecture + "/", "/GodotSharp/"); } - if (file.find("/data.mono.macos.release.universal/") != -1) { + if (file.find("/data.mono.macos.release." + architecture + "/") != -1) { if (p_debug) { ret = unzGoToNextFile(src_pkg_zip); continue; // skip } - file = file.replace("/data.mono.macos.release.universal/", "/GodotSharp/"); + file = file.replace("/data.mono.macos.release." + architecture + "/", "/GodotSharp/"); } if (file.ends_with(".dylib")) { diff --git a/platform/macos/export/export_plugin.h b/platform/macos/export/export_plugin.h index e2e9cc3d22..21bc380d55 100644 --- a/platform/macos/export/export_plugin.h +++ b/platform/macos/export/export_plugin.h @@ -39,8 +39,8 @@ #include "core/io/zip_io.h" #include "core/os/os.h" #include "core/version.h" -#include "editor/editor_export.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" #include "platform/macos/logo.gen.h" #include <sys/stat.h> @@ -99,7 +99,7 @@ class EditorExportPlatformMacOS : public EditorExportPlatform { } protected: - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override; + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; virtual void get_export_options(List<ExportOption> *r_options) override; virtual bool get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const override; @@ -121,7 +121,7 @@ public: virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; - virtual void get_platform_features(List<String> *r_features) override { + virtual void get_platform_features(List<String> *r_features) const override { r_features->push_back("pc"); r_features->push_back("s3tc"); r_features->push_back("macos"); diff --git a/platform/macos/godot_content_view.mm b/platform/macos/godot_content_view.mm index 9ca7498a15..dbed969901 100644 --- a/platform/macos/godot_content_view.mm +++ b/platform/macos/godot_content_view.mm @@ -267,7 +267,7 @@ Variant *vp = &v; Variant ret; Callable::CallError ce; - wd.drop_files_callback.call((const Variant **)&vp, 1, ret, ce); + wd.drop_files_callback.callp((const Variant **)&vp, 1, ret, ce); } return NO; diff --git a/platform/macos/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm index e1e88274f0..2d9329ab3c 100644 --- a/platform/macos/godot_window_delegate.mm +++ b/platform/macos/godot_window_delegate.mm @@ -187,7 +187,7 @@ Variant *sizep = &size; Variant ret; Callable::CallError ce; - wd.rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce); + wd.rect_changed_callback.callp((const Variant **)&sizep, 1, ret, ce); } } @@ -205,7 +205,7 @@ Variant *sizep = &size; Variant ret; Callable::CallError ce; - wd.rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce); + wd.rect_changed_callback.callp((const Variant **)&sizep, 1, ret, ce); } } diff --git a/platform/macos/os_macos.h b/platform/macos/os_macos.h index a6c23ab71e..a1eb0f7f69 100644 --- a/platform/macos/os_macos.h +++ b/platform/macos/os_macos.h @@ -97,6 +97,8 @@ public: virtual String get_locale() const override; + virtual Vector<String> get_system_fonts() const override; + virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; virtual String get_executable_path() const override; virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override; virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override; diff --git a/platform/macos/os_macos.mm b/platform/macos/os_macos.mm index 2c6cd7de0b..cc550043de 100644 --- a/platform/macos/os_macos.mm +++ b/platform/macos/os_macos.mm @@ -303,6 +303,80 @@ String OS_MacOS::get_locale() const { return String([locale_code UTF8String]).replace("-", "_"); } +Vector<String> OS_MacOS::get_system_fonts() const { + HashSet<String> font_names; + CFArrayRef fonts = CTFontManagerCopyAvailableFontFamilyNames(); + if (fonts) { + for (CFIndex i = 0; i < CFArrayGetCount(fonts); i++) { + CFStringRef cf_name = (CFStringRef)CFArrayGetValueAtIndex(fonts, i); + if (cf_name && (CFStringGetLength(cf_name) > 0) && (CFStringCompare(cf_name, CFSTR("LastResort"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && (CFStringGetCharacterAtIndex(cf_name, 0) != '.')) { + NSString *ns_name = (__bridge NSString *)cf_name; + font_names.insert(String::utf8([ns_name UTF8String])); + } + } + CFRelease(fonts); + } + + Vector<String> ret; + for (const String &E : font_names) { + ret.push_back(E); + } + return ret; +} + +String OS_MacOS::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { + String ret; + + String font_name = p_font_name; + if (font_name.to_lower() == "sans-serif") { + font_name = "Helvetica"; + } else if (font_name.to_lower() == "serif") { + font_name = "Times"; + } else if (font_name.to_lower() == "monospace") { + font_name = "Courier"; + } else if (font_name.to_lower() == "fantasy") { + font_name = "Papyrus"; + } else if (font_name.to_lower() == "cursive") { + font_name = "Apple Chancery"; + }; + + CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8); + + CTFontSymbolicTraits traits = 0; + if (p_bold) { + traits |= kCTFontBoldTrait; + } + if (p_italic) { + traits |= kCTFontItalicTrait; + } + + CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits); + CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits); + + CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name); + CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict); + + CTFontDescriptorRef font = CTFontDescriptorCreateWithAttributes(attributes); + if (font) { + CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(font, kCTFontURLAttribute); + if (url) { + NSString *font_path = [NSString stringWithString:[(__bridge NSURL *)url path]]; + ret = String::utf8([font_path UTF8String]); + CFRelease(url); + } + CFRelease(font); + } + + CFRelease(attributes); + CFRelease(traits_dict); + CFRelease(sym_traits); + CFRelease(name); + + return ret; +} + String OS_MacOS::get_executable_path() const { char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; int pid = getpid(); diff --git a/platform/uwp/export/app_packager.h b/platform/uwp/export/app_packager.h index effe96ae67..18db3eb806 100644 --- a/platform/uwp/export/app_packager.h +++ b/platform/uwp/export/app_packager.h @@ -40,7 +40,7 @@ #include "core/io/zip_io.h" #include "core/object/class_db.h" #include "core/version.h" -#include "editor/editor_export.h" +#include "editor/export/editor_export_platform.h" #include "thirdparty/minizip/unzip.h" #include "thirdparty/minizip/zip.h" diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index efba006985..31105824a5 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -30,6 +30,7 @@ #include "export.h" +#include "editor/editor_settings.h" #include "export_plugin.h" void register_uwp_exporter() { diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp index 19b43d50be..070c46242f 100644 --- a/platform/uwp/export/export_plugin.cpp +++ b/platform/uwp/export/export_plugin.cpp @@ -30,6 +30,7 @@ #include "export_plugin.h" +#include "editor/editor_settings.h" #include "platform/uwp/logo.gen.h" String EditorExportPlatformUWP::get_name() const { @@ -49,27 +50,17 @@ Ref<Texture2D> EditorExportPlatformUWP::get_logo() const { return logo; } -void EditorExportPlatformUWP::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { +void EditorExportPlatformUWP::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { r_features->push_back("s3tc"); r_features->push_back("etc"); - switch ((int)p_preset->get("architecture/target")) { - case EditorExportPlatformUWP::ARM: { - r_features->push_back("arm"); - } break; - case EditorExportPlatformUWP::X86: { - r_features->push_back("32"); - } break; - case EditorExportPlatformUWP::X64: { - r_features->push_back("64"); - } break; - } + r_features->push_back(p_preset->get("binary_format/architecture")); } void EditorExportPlatformUWP::get_export_options(List<ExportOption> *r_options) { r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "architecture/target", PROPERTY_HINT_ENUM, "arm,x86,x64"), 1)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "x86_64,x86_32,arm32"), "x86_64")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), "")); @@ -143,23 +134,18 @@ bool EditorExportPlatformUWP::can_export(const Ref<EditorExportPreset> &p_preset bool valid = false; // Look for export templates (first official, and if defined custom templates). - - Platform arch = (Platform)(int)(p_preset->get("architecture/target")); - String platform_infix; - switch (arch) { - case EditorExportPlatformUWP::ARM: { - platform_infix = "arm"; - } break; - case EditorExportPlatformUWP::X86: { - platform_infix = "x86"; - } break; - case EditorExportPlatformUWP::X64: { - platform_infix = "x64"; - } break; + String arch = p_preset->get("binary_format/architecture"); + String arch_infix; + if (arch == "arm32") { + arch_infix = "arm"; + } else if (arch == "x86_32") { + arch_infix = "x86"; + } else if (arch == "x86_64") { + arch_infix = "x64"; } - bool dvalid = exists_export_template("uwp_" + platform_infix + "_debug.zip", &err); - bool rvalid = exists_export_template("uwp_" + platform_infix + "_release.zip", &err); + bool dvalid = exists_export_template("uwp_" + arch_infix + "_debug.zip", &err); + bool rvalid = exists_export_template("uwp_" + arch_infix + "_release.zip", &err); if (p_preset->get("custom_template/debug") != "") { dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); @@ -263,25 +249,21 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p src_appx = src_appx.strip_edges(); - Platform arch = (Platform)(int)p_preset->get("architecture/target"); + String arch = p_preset->get("binary_format/architecture"); if (src_appx.is_empty()) { - String err, infix; - switch (arch) { - case ARM: { - infix = "_arm_"; - } break; - case X86: { - infix = "_x86_"; - } break; - case X64: { - infix = "_x64_"; - } break; + String err, arch_infix; + if (arch == "arm32") { + arch_infix = "arm"; + } else if (arch == "x86_32") { + arch_infix = "x86"; + } else if (arch == "x86_64") { + arch_infix = "x64"; } if (p_debug) { - src_appx = find_export_template("uwp" + infix + "debug.zip", &err); + src_appx = find_export_template("uwp_" + arch_infix + "_debug.zip", &err); } else { - src_appx = find_export_template("uwp" + infix + "release.zip", &err); + src_appx = find_export_template("uwp_" + arch_infix + "_release.zip", &err); } if (src_appx.is_empty()) { EditorNode::add_io_error(err); @@ -494,7 +476,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p return OK; } -void EditorExportPlatformUWP::get_platform_features(List<String> *r_features) { +void EditorExportPlatformUWP::get_platform_features(List<String> *r_features) const { r_features->push_back("pc"); r_features->push_back("uwp"); } diff --git a/platform/uwp/export/export_plugin.h b/platform/uwp/export/export_plugin.h index 02dbcb726b..4a3c5db377 100644 --- a/platform/uwp/export/export_plugin.h +++ b/platform/uwp/export/export_plugin.h @@ -39,9 +39,9 @@ #include "core/io/zip_io.h" #include "core/object/class_db.h" #include "core/version.h" -#include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" +#include "editor/export/editor_export_platform.h" #include "thirdparty/minizip/unzip.h" #include "thirdparty/minizip/zip.h" @@ -90,12 +90,6 @@ class EditorExportPlatformUWP : public EditorExportPlatform { Ref<ImageTexture> logo; - enum Platform { - ARM, - X86, - X64 - }; - bool _valid_resource_name(const String &p_name) const { if (p_name.is_empty()) { return false; @@ -215,8 +209,8 @@ class EditorExportPlatformUWP : public EditorExportPlatform { String version = itos(p_preset->get("version/major")) + "." + itos(p_preset->get("version/minor")) + "." + itos(p_preset->get("version/build")) + "." + itos(p_preset->get("version/revision")); result = result.replace("$version_string$", version); - Platform arch = (Platform)(int)p_preset->get("architecture/target"); - String architecture = arch == ARM ? "arm" : (arch == X86 ? "x86" : "x64"); + String arch = p_preset->get("binary_format/architecture"); + String architecture = arch == "arm32" ? "arm" : (arch == "x86_32" ? "x86" : "x64"); result = result.replace("$architecture$", architecture); result = result.replace("$display_name$", String(p_preset->get("package/display_name")).is_empty() ? (String)ProjectSettings::get_singleton()->get("application/config/name") : String(p_preset->get("package/display_name"))); @@ -431,7 +425,7 @@ public: virtual Ref<Texture2D> get_logo() const override; - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override; + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; virtual void get_export_options(List<ExportOption> *r_options) override; @@ -439,7 +433,7 @@ public: virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; - virtual void get_platform_features(List<String> *r_features) override; + virtual void get_platform_features(List<String> *r_features) const override; virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override; diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index f37759c66f..40f93bb18b 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -275,7 +275,7 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a display_request->RequestActive(); } - set_keep_screen_on(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true)); + set_keep_screen_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); return OK; } @@ -716,7 +716,7 @@ bool OS_UWP::has_virtual_keyboard() const { return UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch; } -void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { +void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) { InputPane ^ pane = InputPane::GetForCurrentView(); pane->TryShow(); } diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index b9d035ff41..fe61f60548 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -231,7 +231,7 @@ public: virtual bool has_touchscreen_ui_hint() const; virtual bool has_virtual_keyboard() const; - virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1); + virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), VirtualKeyboardType p_type = KEYBOARD_TYPE_DEFAULT, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1); virtual void hide_virtual_keyboard(); virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr); diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 6a7caf4656..dd2df1f004 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -270,6 +270,7 @@ def configure_msvc(env, manual_msvc_config): "bcrypt", "Avrt", "dwmapi", + "dwrite", ] if env["vulkan"]: @@ -441,6 +442,7 @@ def configure_mingw(env): "avrt", "uuid", "dwmapi", + "dwrite", ] ) diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index f9988b23bc..8c8dbef8a4 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -531,10 +531,43 @@ DisplayServer::ScreenOrientation DisplayServerWindows::screen_get_orientation(in } void DisplayServerWindows::screen_set_keep_on(bool p_enable) { + if (keep_screen_on == p_enable) { + return; + } + + if (p_enable) { + const String reason = "Godot Engine running with display/window/energy_saving/keep_screen_on = true"; + Char16String reason_utf16 = reason.utf16(); + + REASON_CONTEXT context; + context.Version = POWER_REQUEST_CONTEXT_VERSION; + context.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING; + context.Reason.SimpleReasonString = (LPWSTR)(reason_utf16.ptrw()); + power_request = PowerCreateRequest(&context); + if (power_request == INVALID_HANDLE_VALUE) { + print_error("Failed to enable screen_keep_on."); + return; + } + if (PowerSetRequest(power_request, POWER_REQUEST_TYPE::PowerRequestSystemRequired) == 0) { + print_error("Failed to request system sleep override."); + return; + } + if (PowerSetRequest(power_request, POWER_REQUEST_TYPE::PowerRequestDisplayRequired) == 0) { + print_error("Failed to request display timeout override."); + return; + } + } else { + PowerClearRequest(power_request, POWER_REQUEST_TYPE::PowerRequestSystemRequired); + PowerClearRequest(power_request, POWER_REQUEST_TYPE::PowerRequestDisplayRequired); + CloseHandle(power_request); + power_request = nullptr; + } + + keep_screen_on = p_enable; } bool DisplayServerWindows::screen_is_kept_on() const { - return false; + return keep_screen_on; } Vector<DisplayServer::WindowID> DisplayServerWindows::get_window_list() const { @@ -2035,7 +2068,7 @@ void DisplayServerWindows::_send_window_event(const WindowData &wd, WindowEvent Variant *eventp = &event; Variant ret; Callable::CallError ce; - wd.event_callback.call((const Variant **)&eventp, 1, ret, ce); + wd.event_callback.callp((const Variant **)&eventp, 1, ret, ce); } } @@ -2062,7 +2095,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) if (windows.has(E->get())) { Callable callable = windows[E->get()].input_event_callback; if (callable.is_valid()) { - callable.call((const Variant **)&evp, 1, ret, ce); + callable.callp((const Variant **)&evp, 1, ret, ce); } } in_dispatch_input_event = false; @@ -2076,7 +2109,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) if (windows.has(event_from_window->get_window_id())) { Callable callable = windows[event_from_window->get_window_id()].input_event_callback; if (callable.is_valid()) { - callable.call((const Variant **)&evp, 1, ret, ce); + callable.callp((const Variant **)&evp, 1, ret, ce); } } } else { @@ -2084,7 +2117,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) for (const KeyValue<WindowID, WindowData> &E : windows) { const Callable callable = E.value.input_event_callback; if (callable.is_valid()) { - callable.call((const Variant **)&evp, 1, ret, ce); + callable.callp((const Variant **)&evp, 1, ret, ce); } } } @@ -3039,7 +3072,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA const Variant *args[] = { &size }; Variant ret; Callable::CallError ce; - window.rect_changed_callback.call(args, 1, ret, ce); + window.rect_changed_callback.callp(args, 1, ret, ce); } } @@ -3199,7 +3232,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA Variant *vp = &v; Variant ret; Callable::CallError ce; - windows[window_id].drop_files_callback.call((const Variant **)&vp, 1, ret, ce); + windows[window_id].drop_files_callback.callp((const Variant **)&vp, 1, ret, ce); } } break; default: { @@ -3619,6 +3652,9 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win // Init TTS tts = memnew(TTS_Windows); + // Enforce default keep screen on value. + screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); + // Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink. HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll"); if (wintab_lib) { @@ -3822,6 +3858,9 @@ DisplayServerWindows::~DisplayServerWindows() { SetWindowLongPtr(windows[MAIN_WINDOW_ID].hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc); } + // Close power request handle. + screen_set_keep_on(false); + #ifdef GLES3_ENABLED // destroy windows .. NYI? // FIXME wglDeleteContext is never called diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index ddbf674c64..db9b589304 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -331,6 +331,8 @@ class DisplayServerWindows : public DisplayServer { HINSTANCE hInstance; // Holds The Instance Of The Application String rendering_driver; bool app_focused = false; + bool keep_screen_on = false; + HANDLE power_request; TTS_Windows *tts = nullptr; diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index af19f24f09..20320470b8 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -30,6 +30,7 @@ #include "export.h" +#include "editor/export/editor_export.h" #include "export_plugin.h" void register_windows_exporter() { diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp index 45bfc761fe..febef5ad12 100644 --- a/platform/windows/export/export_plugin.cpp +++ b/platform/windows/export/export_plugin.cpp @@ -123,6 +123,7 @@ bool EditorExportPlatformWindows::get_export_option_visibility(const String &p_o void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) { EditorExportPlatformPC::get_export_options(r_options); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "x86_64,x86_32"), "x86_64")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA1 hash)"), 0)); @@ -230,13 +231,13 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset String str; Error err = OS::get_singleton()->execute(rcedit_path, args, &str, nullptr, true); if (err != OK || (str.find("not found") != -1) || (str.find("not recognized") != -1)) { - add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), TTR("Could not start rcedit executable, configure rcedit path in the Editor Settings (Export > Windows > Rcedit).")); + add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), TTR("Could not start rcedit executable. Configure rcedit path in the Editor Settings (Export > Windows > Rcedit), or disable \"Application > Modify Resources\" in the export preset.")); return err; } print_line("rcedit (" + p_path + "): " + str); if (str.find("Fatal error") != -1) { - add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("rcedit failed to modify executable:\n%s"), str)); + add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("rcedit failed to modify executable: %s."), str)); return FAILED; } @@ -378,7 +379,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p String str; Error err = OS::get_singleton()->execute(signtool_path, args, &str, nullptr, true); if (err != OK || (str.find("not found") != -1) || (str.find("not recognized") != -1)) { - add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start signtool executable, configure signtool path in the Editor Settings (Export > Windows > Signtool).")); + add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start signtool executable. Configure signtool path in the Editor Settings (Export > Windows > Signtool), or disable \"Codesign\" in the export preset.")); return err; } @@ -388,7 +389,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p #else if (str.find("Failed") != -1) { #endif - add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Signtool failed to sign executable:\n%s"), str)); + add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Signtool failed to sign executable: %s."), str)); return FAILED; } diff --git a/platform/windows/export/export_plugin.h b/platform/windows/export/export_plugin.h index bb8d6a15f2..b9e59829a0 100644 --- a/platform/windows/export/export_plugin.h +++ b/platform/windows/export/export_plugin.h @@ -33,8 +33,8 @@ #include "core/io/file_access.h" #include "core/os/os.h" -#include "editor/editor_export.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export_platform_pc.h" #include "platform/windows/logo.gen.h" class EditorExportPlatformWindows : public EditorExportPlatformPC { diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis index 899956d65a..cdd1c14978 100644 --- a/platform/windows/godot.natvis +++ b/platform/windows/godot.natvis @@ -40,7 +40,7 @@ <DisplayString Condition="type == Variant::TRANSFORM2D">{_data._transform2d}</DisplayString> <DisplayString Condition="type == Variant::AABB">{_data._aabb}</DisplayString> <DisplayString Condition="type == Variant::BASIS">{_data._basis}</DisplayString> - <DisplayString Condition="type == Variant::TRANSFORM3D">{_data._transform}</DisplayString> + <DisplayString Condition="type == Variant::TRANSFORM3D">{_data._transform3d}</DisplayString> <DisplayString Condition="type == Variant::PROJECTION">{_data._projection}</DisplayString> <DisplayString Condition="type == Variant::STRING">{*(String *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::VECTOR2">{*(Vector2 *)_data._mem}</DisplayString> @@ -74,7 +74,7 @@ <Item Name="[value]" Condition="type == Variant::TRANSFORM2D">_data._transform2d</Item> <Item Name="[value]" Condition="type == Variant::AABB">_data._aabb</Item> <Item Name="[value]" Condition="type == Variant::BASIS">_data._basis</Item> - <Item Name="[value]" Condition="type == Variant::TRANSFORM3D">_data._transform</Item> + <Item Name="[value]" Condition="type == Variant::TRANSFORM3D">_data._transform3d</Item> <Item Name="[value]" Condition="type == Variant::STRING">*(String *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::VECTOR2">*(Vector2 *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::RECT2">*(Rect2 *)_data._mem</Item> diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index b5423e62bf..ad4be950cc 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -48,6 +48,7 @@ #include <avrt.h> #include <bcrypt.h> #include <direct.h> +#include <dwrite.h> #include <knownfolders.h> #include <process.h> #include <regstr.h> @@ -621,6 +622,135 @@ Error OS_Windows::set_cwd(const String &p_cwd) { return OK; } +Vector<String> OS_Windows::get_system_fonts() const { + Vector<String> ret; + HashSet<String> font_names; + + ComAutoreleaseRef<IDWriteFactory> dwrite_factory; + HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory.reference)); + ERR_FAIL_COND_V(FAILED(hr) || dwrite_factory.is_null(), ret); + + ComAutoreleaseRef<IDWriteFontCollection> font_collection; + hr = dwrite_factory->GetSystemFontCollection(&font_collection.reference, false); + ERR_FAIL_COND_V(FAILED(hr) || font_collection.is_null(), ret); + + UINT32 family_count = font_collection->GetFontFamilyCount(); + for (UINT32 i = 0; i < family_count; i++) { + ComAutoreleaseRef<IDWriteFontFamily> family; + hr = font_collection->GetFontFamily(i, &family.reference); + ERR_CONTINUE(FAILED(hr) || family.is_null()); + + ComAutoreleaseRef<IDWriteLocalizedStrings> family_names; + hr = family->GetFamilyNames(&family_names.reference); + ERR_CONTINUE(FAILED(hr) || family_names.is_null()); + + UINT32 index = 0; + BOOL exists = false; + UINT32 length = 0; + Char16String name; + + hr = family_names->FindLocaleName(L"en-us", &index, &exists); + ERR_CONTINUE(FAILED(hr)); + + hr = family_names->GetStringLength(index, &length); + ERR_CONTINUE(FAILED(hr)); + + name.resize(length + 1); + hr = family_names->GetString(index, (WCHAR *)name.ptrw(), length + 1); + ERR_CONTINUE(FAILED(hr)); + + font_names.insert(String::utf16(name.ptr(), length)); + } + + for (const String &E : font_names) { + ret.push_back(E); + } + return ret; +} + +String OS_Windows::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { + String font_name = p_font_name; + if (font_name.to_lower() == "sans-serif") { + font_name = "Arial"; + } else if (font_name.to_lower() == "serif") { + font_name = "Times New Roman"; + } else if (font_name.to_lower() == "monospace") { + font_name = "Courier New"; + } else if (font_name.to_lower() == "cursive") { + font_name = "Comic Sans MS"; + } else if (font_name.to_lower() == "fantasy") { + font_name = "Gabriola"; + } + + ComAutoreleaseRef<IDWriteFactory> dwrite_factory; + HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory.reference)); + ERR_FAIL_COND_V(FAILED(hr) || dwrite_factory.is_null(), String()); + + ComAutoreleaseRef<IDWriteFontCollection> font_collection; + hr = dwrite_factory->GetSystemFontCollection(&font_collection.reference, false); + ERR_FAIL_COND_V(FAILED(hr) || font_collection.is_null(), String()); + + UINT32 index = 0; + BOOL exists = false; + font_collection->FindFamilyName((const WCHAR *)font_name.utf16().get_data(), &index, &exists); + if (FAILED(hr)) { + return String(); + } + + ComAutoreleaseRef<IDWriteFontFamily> family; + hr = font_collection->GetFontFamily(index, &family.reference); + if (FAILED(hr) || family.is_null()) { + return String(); + } + + ComAutoreleaseRef<IDWriteFont> dwrite_font; + hr = family->GetFirstMatchingFont(p_bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, p_italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, &dwrite_font.reference); + if (FAILED(hr) || dwrite_font.is_null()) { + return String(); + } + + ComAutoreleaseRef<IDWriteFontFace> dwrite_face; + hr = dwrite_font->CreateFontFace(&dwrite_face.reference); + if (FAILED(hr) || dwrite_face.is_null()) { + return String(); + } + + UINT32 number_of_files = 0; + hr = dwrite_face->GetFiles(&number_of_files, nullptr); + if (FAILED(hr)) { + return String(); + } + Vector<ComAutoreleaseRef<IDWriteFontFile>> files; + files.resize(number_of_files); + hr = dwrite_face->GetFiles(&number_of_files, (IDWriteFontFile **)files.ptrw()); + if (FAILED(hr)) { + return String(); + } + + for (UINT32 i = 0; i < number_of_files; i++) { + void const *reference_key = nullptr; + UINT32 reference_key_size = 0; + ComAutoreleaseRef<IDWriteLocalFontFileLoader> loader; + + hr = files.write[i]->GetLoader((IDWriteFontFileLoader **)&loader.reference); + if (FAILED(hr) || loader.is_null()) { + continue; + } + hr = files.write[i]->GetReferenceKey(&reference_key, &reference_key_size); + if (FAILED(hr)) { + continue; + } + + WCHAR file_path[MAX_PATH]; + hr = loader->GetFilePathFromKey(reference_key, reference_key_size, &file_path[0], MAX_PATH); + if (FAILED(hr)) { + continue; + } + return String::utf16((const char16_t *)&file_path[0]); + } + return String(); +} + String OS_Windows::get_executable_path() const { WCHAR bufname[4096]; GetModuleFileNameW(nullptr, bufname, 4096); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 7d2d4ae705..80fc860738 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -62,6 +62,26 @@ #define WINDOWS_DEBUG_OUTPUT_ENABLED #endif +template <class T> +class ComAutoreleaseRef { +public: + T *reference = nullptr; + + _FORCE_INLINE_ T *operator->() { return reference; } + _FORCE_INLINE_ const T *operator->() const { return reference; } + _FORCE_INLINE_ T *operator*() { return reference; } + _FORCE_INLINE_ const T *operator*() const { return reference; } + _FORCE_INLINE_ bool is_valid() const { return reference != nullptr; } + _FORCE_INLINE_ bool is_null() const { return reference == nullptr; } + ComAutoreleaseRef() {} + ~ComAutoreleaseRef() { + if (reference != nullptr) { + reference->Release(); + reference = nullptr; + } + } +}; + class JoypadWindows; class OS_Windows : public OS { #ifdef STDOUT_FILE @@ -147,6 +167,9 @@ public: virtual String get_environment(const String &p_var) const override; virtual bool set_environment(const String &p_var, const String &p_value) const override; + virtual Vector<String> get_system_fonts() const override; + virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; + virtual String get_executable_path() const override; virtual String get_locale() const override; diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index dfc1016c84..7890348314 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -184,8 +184,8 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree), make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree).bind(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree).bind(objid)); if (E->value.in_tree) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } @@ -277,8 +277,8 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree), make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree).bind(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree).bind(objid)); if (E->value.in_tree) { emit_signal(SceneStringNames::get_singleton()->area_entered, node); } diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 76b354805c..c43a796170 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -247,8 +247,8 @@ void Camera2D::_notification(int p_what) { add_to_group(canvas_group_name); _update_process_callback(); - _update_scroll(); first = true; + _update_scroll(); } break; case NOTIFICATION_EXIT_TREE: { @@ -439,7 +439,9 @@ void Camera2D::clear_current() { void Camera2D::set_limit(Side p_side, int p_limit) { ERR_FAIL_INDEX((int)p_side, 4); limit[p_side] = p_limit; + Point2 old_smoothed_camera_pos = smoothed_camera_pos; _update_scroll(); + smoothed_camera_pos = old_smoothed_camera_pos; } int Camera2D::get_limit(Side p_side) const { diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 4155d0797f..26204a3b1a 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -1470,7 +1470,7 @@ CPUParticles2D::CPUParticles2D() { set_emitting(true); set_amount(8); - set_use_local_coordinates(true); + set_use_local_coordinates(false); set_param_min(PARAM_INITIAL_LINEAR_VELOCITY, 0); set_param_min(PARAM_ANGULAR_VELOCITY, 0); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index a869cf2525..075421a26d 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -660,7 +660,7 @@ GPUParticles2D::GPUParticles2D() { set_explosiveness_ratio(0); set_randomness_ratio(0); set_visibility_rect(Rect2(Vector2(-100, -100), Vector2(200, 200))); - set_use_local_coordinates(true); + set_use_local_coordinates(false); set_draw_order(DRAW_ORDER_LIFETIME); set_speed_scale(1); set_fixed_fps(30); diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index 6e8fd891cb..cdf7c5afa9 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -35,6 +35,7 @@ #include "core/os/mutex.h" #include "scene/resources/world_2d.h" #include "servers/navigation_server_2d.h" +#include "servers/navigation_server_3d.h" #include "thirdparty/misc/polypartition.h" @@ -371,9 +372,11 @@ void NavigationRegion2D::set_enabled(bool p_enabled) { NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); } - if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) { +#ifdef DEBUG_ENABLED + if (Engine::get_singleton()->is_editor_hint() || NavigationServer3D::get_singleton()->get_debug_enabled()) { update(); } +#endif // DEBUG_ENABLED } bool NavigationRegion2D::is_enabled() const { @@ -419,7 +422,7 @@ real_t NavigationRegion2D::get_enter_cost() const { void NavigationRegion2D::set_travel_cost(real_t p_travel_cost) { ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive."); travel_cost = MAX(p_travel_cost, 0.0); - NavigationServer2D::get_singleton()->region_set_enter_cost(region, travel_cost); + NavigationServer2D::get_singleton()->region_set_travel_cost(region, travel_cost); } real_t NavigationRegion2D::get_travel_cost() const { @@ -462,7 +465,8 @@ void NavigationRegion2D::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) { +#ifdef DEBUG_ENABLED + if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || NavigationServer3D::get_singleton()->get_debug_enabled()) && navpoly.is_valid()) { Vector<Vector2> verts = navpoly->get_vertices(); if (verts.size() < 3) { return; @@ -470,11 +474,11 @@ void NavigationRegion2D::_notification(int p_what) { Color color; if (enabled) { - color = get_tree()->get_debug_navigation_color(); + color = NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_color(); } else { - color = get_tree()->get_debug_navigation_disabled_color(); + color = NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_disabled_color(); } - Color doors_color = color.lightened(0.2); + Color doors_color = NavigationServer3D::get_singleton()->get_debug_navigation_edge_connection_color(); RandomPCG rand; @@ -516,6 +520,7 @@ void NavigationRegion2D::_notification(int p_what) { draw_arc(b, radius, angle - Math_PI / 2.0, angle + Math_PI / 2.0, 10, doors_color); } } +#endif // DEBUG_ENABLED } break; } } @@ -552,10 +557,13 @@ void NavigationRegion2D::_navpoly_changed() { NavigationServer2D::get_singleton()->region_set_navpoly(region, navpoly); } } + void NavigationRegion2D::_map_changed(RID p_map) { - if (enabled && get_world_2d()->get_navigation_map() == p_map) { +#ifdef DEBUG_ENABLED + if (is_inside_tree() && get_world_2d()->get_navigation_map() == p_map) { update(); } +#endif // DEBUG_ENABLED } TypedArray<String> NavigationRegion2D::get_configuration_warnings() const { @@ -605,8 +613,18 @@ NavigationRegion2D::NavigationRegion2D() { region = NavigationServer2D::get_singleton()->region_create(); NavigationServer2D::get_singleton()->region_set_enter_cost(region, get_enter_cost()); NavigationServer2D::get_singleton()->region_set_travel_cost(region, get_travel_cost()); + +#ifdef DEBUG_ENABLED + NavigationServer3D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); + NavigationServer3D::get_singleton_mut()->connect("navigation_debug_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); +#endif // DEBUG_ENABLED } NavigationRegion2D::~NavigationRegion2D() { NavigationServer2D::get_singleton()->free(region); + +#ifdef DEBUG_ENABLED + NavigationServer3D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); + NavigationServer3D::get_singleton_mut()->disconnect("navigation_debug_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); +#endif // DEBUG_ENABLED } diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index e60a5ed034..ce22f32b01 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -387,8 +387,8 @@ void RigidDynamicBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p //E->value.rc=0; E->value.in_scene = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidDynamicBody2D::_body_enter_tree), make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidDynamicBody2D::_body_exit_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidDynamicBody2D::_body_enter_tree).bind(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidDynamicBody2D::_body_exit_tree).bind(objid)); if (E->value.in_scene) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 8953813452..68e5ffdcf9 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -240,7 +240,7 @@ void RayCast2D::_draw_debug_shape() { Transform2D xf; xf.rotate(target_position.angle()); - xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); + xf.translate_local(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); Vector<Vector2> pts = { xf.xform(Vector2(arrow_size, 0)), diff --git a/scene/2d/shape_cast_2d.cpp b/scene/2d/shape_cast_2d.cpp index ae810156a2..316988d298 100644 --- a/scene/2d/shape_cast_2d.cpp +++ b/scene/2d/shape_cast_2d.cpp @@ -217,7 +217,7 @@ void ShapeCast2D::_notification(int p_what) { if (shape.is_null()) { break; } - Color draw_col = get_tree()->get_debug_collisions_color(); + Color draw_col = collided ? Color(1.0, 0.01, 0) : get_tree()->get_debug_collisions_color(); if (!enabled) { float g = draw_col.get_v(); draw_col.r = g; @@ -235,18 +235,25 @@ void ShapeCast2D::_notification(int p_what) { // Draw an arrow indicating where the ShapeCast is pointing to. if (target_position != Vector2()) { - Transform2D xf; - xf.rotate(target_position.angle()); - xf.translate(Vector2(target_position.length(), 0)); + const real_t max_arrow_size = 6; + const real_t line_width = 1.4; + bool no_line = target_position.length() < line_width; + real_t arrow_size = CLAMP(target_position.length() * 2 / 3, line_width, max_arrow_size); - draw_line(Vector2(), target_position, draw_col, 2); + if (no_line) { + arrow_size = target_position.length(); + } else { + draw_line(Vector2(), target_position - target_position.normalized() * arrow_size, draw_col, line_width); + } - float tsize = 8; + Transform2D xf; + xf.rotate(target_position.angle()); + xf.translate_local(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); Vector<Vector2> pts = { - xf.xform(Vector2(tsize, 0)), - xf.xform(Vector2(0, Math_SQRT12 * tsize)), - xf.xform(Vector2(0, -Math_SQRT12 * tsize)) + xf.xform(Vector2(arrow_size, 0)), + xf.xform(Vector2(0, 0.5 * arrow_size)), + xf.xform(Vector2(0, -0.5 * arrow_size)) }; Vector<Color> cols = { draw_col, draw_col, draw_col }; @@ -291,6 +298,8 @@ void ShapeCast2D::_update_shapecast_state() { collision_safe_fraction = 0.0; collision_unsafe_fraction = 0.0; + bool prev_collision_state = collided; + if (target_position != Vector2()) { dss->cast_motion(params, collision_safe_fraction, collision_unsafe_fraction); if (collision_unsafe_fraction < 1.0) { @@ -314,6 +323,10 @@ void ShapeCast2D::_update_shapecast_state() { } } collided = !result.is_empty(); + + if (prev_collision_state != collided) { + update(); + } } void ShapeCast2D::force_shapecast_update() { diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 4a4a2a1da0..9dea69cd64 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -131,7 +131,7 @@ void TouchScreenButton::_notification(int p_what) { pos = texture_normal->get_size() * 0.5; } - draw_set_transform_matrix(get_canvas_transform().translated(pos)); + draw_set_transform_matrix(get_canvas_transform().translated_local(pos)); shape->draw(get_canvas_item(), draw_col); } } break; @@ -258,7 +258,7 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { pos = texture_normal->get_size() * 0.5; } - touched = shape->collide(Transform2D().translated(pos), unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); + touched = shape->collide(Transform2D().translated_local(pos), unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); } if (bitmask.is_valid()) { diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index fb0c59daa1..e9e19488e9 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -239,8 +239,8 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree), make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree).bind(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree).bind(objid)); if (E->value.in_tree) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } @@ -426,8 +426,8 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree), make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree).bind(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree).bind(objid)); if (E->value.in_tree) { emit_signal(SceneStringNames::get_singleton()->area_entered, node); } diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index da4a14394d..f654373ee5 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -507,7 +507,7 @@ void Camera3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal,Frustum"), "set_projection", "get_projection"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1,degrees"), "set_fov", "get_fov"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.001,16384,0.01,suffix:m"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.001,16384,0.001,suffix:m"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_frustum_offset", "get_frustum_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater,exp,suffix:m"), "set_near", "get_near"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_RANGE, "0.01,4000,0.01,or_greater,exp,suffix:m"), "set_far", "get_far"); diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index a36357555a..9a5d4f5480 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -319,7 +319,7 @@ bool CollisionObject3D::_are_collision_shapes_visible() { void CollisionObject3D::_update_shape_data(uint32_t p_owner) { if (_are_collision_shapes_visible()) { if (debug_shapes_to_update.is_empty()) { - callable_mp(this, &CollisionObject3D::_update_debug_shapes).call_deferred({}, 0); + callable_mp(this, &CollisionObject3D::_update_debug_shapes).call_deferredp({}, 0); } debug_shapes_to_update.insert(p_owner); } @@ -365,8 +365,7 @@ void CollisionObject3D::_update_debug_shapes() { RS::get_singleton()->instance_set_scenario(s.debug_shape, get_world_3d()->get_scenario()); if (!s.shape->is_connected("changed", callable_mp(this, &CollisionObject3D::_shape_changed))) { - s.shape->connect("changed", callable_mp(this, &CollisionObject3D::_shape_changed), - varray(s.shape), CONNECT_DEFERRED); + s.shape->connect("changed", callable_mp(this, &CollisionObject3D::_shape_changed).bind(s.shape), CONNECT_DEFERRED); } ++debug_shapes_count; @@ -404,6 +403,9 @@ void CollisionObject3D::_on_transform_changed() { debug_shape_old_transform = get_global_transform(); for (KeyValue<uint32_t, ShapeData> &E : shapes) { ShapeData &shapedata = E.value; + if (shapedata.disabled) { + continue; // If disabled then there are no debug shapes to update. + } const ShapeData::ShapeBase *shapes = shapedata.shapes.ptr(); for (int i = 0; i < shapedata.shapes.size(); i++) { RS::get_singleton()->instance_set_transform(shapes[i].debug_shape, debug_shape_old_transform * shapedata.xform); diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index 4cb693f494..e26c301038 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -138,7 +138,7 @@ private: real_t randomness_ratio = 0.0; double lifetime_randomness = 0.0; double speed_scale = 1.0; - bool local_coords = true; + bool local_coords = false; int fixed_fps = 0; bool fractional_delta = true; diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index 01cab493ec..0112f24e0c 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -215,11 +215,13 @@ void Decal::_bind_methods() { ClassDB::bind_method(D_METHOD("get_cull_mask"), &Decal::get_cull_mask); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,suffix:m"), "set_extents", "get_extents"); + ADD_GROUP("Textures", "texture_"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_orm", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ORM); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_emission", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION); + ADD_GROUP("Parameters", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_emission_energy", "get_emission_energy"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); @@ -227,13 +229,16 @@ void Decal::_bind_methods() { // A Normal Fade of 1.0 causes the decal to be invisible even if fully perpendicular to a surface. // Due to this, limit Normal Fade to 0.999. ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_fade", PROPERTY_HINT_RANGE, "0,0.999,0.001"), "set_normal_fade", "get_normal_fade"); + ADD_GROUP("Vertical Fade", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "upper_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_upper_fade", "get_upper_fade"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lower_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_lower_fade", "get_lower_fade"); + ADD_GROUP("Distance Fade", "distance_fade_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin", PROPERTY_HINT_NONE, "suffix:m"), "set_distance_fade_begin", "get_distance_fade_begin"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length", PROPERTY_HINT_NONE, "suffix:m"), "set_distance_fade_length", "get_distance_fade_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_distance_fade_begin", "get_distance_fade_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_distance_fade_length", "get_distance_fade_length"); + ADD_GROUP("Cull Mask", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); diff --git a/scene/3d/decal.h b/scene/3d/decal.h index d5990272c6..38da4c14e3 100644 --- a/scene/3d/decal.h +++ b/scene/3d/decal.h @@ -57,8 +57,8 @@ private: real_t upper_fade = 0.3; real_t lower_fade = 0.3; bool distance_fade_enabled = false; - real_t distance_fade_begin = 10.0; - real_t distance_fade_length = 1.0; + real_t distance_fade_begin = 40.0; + real_t distance_fade_length = 10.0; protected: static void _bind_methods(); diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index b352114c7f..2ee126e161 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -222,7 +222,7 @@ void GPUParticles3D::set_draw_pass_mesh(int p_pass, const Ref<Mesh> &p_mesh) { draw_passes.write[p_pass] = p_mesh; if (Engine::get_singleton()->is_editor_hint() && draw_passes.write[p_pass].is_valid()) { - draw_passes.write[p_pass]->connect("changed", callable_mp((Node *)this, &Node::update_configuration_warnings), varray(), CONNECT_DEFERRED); + draw_passes.write[p_pass]->connect("changed", callable_mp((Node *)this, &Node::update_configuration_warnings), CONNECT_DEFERRED); } RID mesh_rid; @@ -631,7 +631,7 @@ GPUParticles3D::GPUParticles3D() { set_randomness_ratio(0); set_trail_length(0.3); set_visibility_aabb(AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8))); - set_use_local_coordinates(true); + set_use_local_coordinates(false); set_draw_passes(1); set_draw_order(DRAW_ORDER_INDEX); set_speed_scale(1); diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 1fcd5160f6..1cfd889272 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -127,6 +127,10 @@ GPUParticlesCollisionBox3D::~GPUParticlesCollisionBox3D() { void GPUParticlesCollisionSDF3D::_find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes) { MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_at_node); if (mi && mi->is_visible_in_tree()) { + if ((mi->get_layer_mask() & bake_mask) == 0) { + return; + } + Ref<Mesh> mesh = mi->get_mesh(); if (mesh.is_valid()) { AABB aabb = mesh->get_aabb(); @@ -445,7 +449,7 @@ Ref<Image> GPUParticlesCollisionSDF3D::bake() { //compute bvh - ERR_FAIL_COND_V(faces.size() <= 1, Ref<Image>()); + ERR_FAIL_COND_V_MSG(faces.size() <= 1, Ref<Image>(), "No faces detected during GPUParticlesCollisionSDF3D bake. Check whether there are visible meshes matching the bake mask within its extents."); LocalVector<FacePos> face_pos; @@ -499,6 +503,16 @@ Ref<Image> GPUParticlesCollisionSDF3D::bake() { return ret; } +TypedArray<String> GPUParticlesCollisionSDF3D::get_configuration_warnings() const { + TypedArray<String> warnings = Node::get_configuration_warnings(); + + if (bake_mask == 0) { + warnings.push_back(RTR("The Bake Mask has no bits enabled, which means baking will not produce any collision for this GPUParticlesCollisionSDF3D.\nTo resolve this, enable at least one bit in the Bake Mask property.")); + } + + return warnings; +} + void GPUParticlesCollisionSDF3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionSDF3D::set_extents); ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionSDF3D::get_extents); @@ -512,9 +526,15 @@ void GPUParticlesCollisionSDF3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &GPUParticlesCollisionSDF3D::set_thickness); ClassDB::bind_method(D_METHOD("get_thickness"), &GPUParticlesCollisionSDF3D::get_thickness); + ClassDB::bind_method(D_METHOD("set_bake_mask", "mask"), &GPUParticlesCollisionSDF3D::set_bake_mask); + ClassDB::bind_method(D_METHOD("get_bake_mask"), &GPUParticlesCollisionSDF3D::get_bake_mask); + ClassDB::bind_method(D_METHOD("set_bake_mask_value", "layer_number", "value"), &GPUParticlesCollisionSDF3D::set_bake_mask_value); + ClassDB::bind_method(D_METHOD("get_bake_mask_value", "layer_number"), &GPUParticlesCollisionSDF3D::get_bake_mask_value); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents"); ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "16,32,64,128,256,512,suffix:px"), "set_resolution", "get_resolution"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "thickness", PROPERTY_HINT_RANGE, "0.0,2.0,0.01,suffix:m"), "set_thickness", "get_thickness"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_bake_mask", "get_bake_mask"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture"); BIND_ENUM_CONSTANT(RESOLUTION_16); @@ -553,6 +573,31 @@ GPUParticlesCollisionSDF3D::Resolution GPUParticlesCollisionSDF3D::get_resolutio return resolution; } +void GPUParticlesCollisionSDF3D::set_bake_mask(uint32_t p_mask) { + bake_mask = p_mask; + update_configuration_warnings(); +} + +uint32_t GPUParticlesCollisionSDF3D::get_bake_mask() const { + return bake_mask; +} + +void GPUParticlesCollisionSDF3D::set_bake_mask_value(int p_layer_number, bool p_value) { + ERR_FAIL_COND_MSG(p_layer_number < 1 || p_layer_number > 20, vformat("The render layer number (%d) must be between 1 and 20 (inclusive).", p_layer_number)); + uint32_t mask = get_bake_mask(); + if (p_value) { + mask |= 1 << (p_layer_number - 1); + } else { + mask &= ~(1 << (p_layer_number - 1)); + } + set_bake_mask(mask); +} + +bool GPUParticlesCollisionSDF3D::get_bake_mask_value(int p_layer_number) const { + ERR_FAIL_COND_V_MSG(p_layer_number < 1 || p_layer_number > 20, false, vformat("The render layer number (%d) must be between 1 and 20 (inclusive).", p_layer_number)); + return bake_mask & (1 << (p_layer_number - 1)); +} + void GPUParticlesCollisionSDF3D::set_texture(const Ref<Texture3D> &p_texture) { texture = p_texture; RID tex = texture.is_valid() ? texture->get_rid() : RID(); diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index 4b2cb930fa..712bd015ff 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -110,6 +110,7 @@ public: private: Vector3 extents = Vector3(1, 1, 1); Resolution resolution = RESOLUTION_64; + uint32_t bake_mask = 0xFFFFFFFF; Ref<Texture3D> texture; float thickness = 1.0; @@ -161,6 +162,8 @@ protected: static void _bind_methods(); public: + virtual TypedArray<String> get_configuration_warnings() const override; + void set_thickness(float p_thickness); float get_thickness() const; @@ -170,6 +173,12 @@ public: void set_resolution(Resolution p_resolution); Resolution get_resolution() const; + void set_bake_mask(uint32_t p_mask); + uint32_t get_bake_mask() const; + + void set_bake_mask_value(int p_layer_number, bool p_enable); + bool get_bake_mask_value(int p_layer_number) const; + void set_texture(const Ref<Texture3D> &p_texture); Ref<Texture3D> get_texture() const; diff --git a/scene/3d/joint_3d.cpp b/scene/3d/joint_3d.cpp index 0b824ef28b..b0509475a7 100644 --- a/scene/3d/joint_3d.cpp +++ b/scene/3d/joint_3d.cpp @@ -737,7 +737,8 @@ void Generic6DOFJoint3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flag_z", "flag", "value"), &Generic6DOFJoint3D::set_flag_z); ClassDB::bind_method(D_METHOD("get_flag_z", "flag"), &Generic6DOFJoint3D::get_flag_z); - // X + ADD_GROUP("Linear Limit", "linear_limit_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_x", "get_param_x", PARAM_LINEAR_UPPER_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_x", "get_param_x", PARAM_LINEAR_LOWER_LIMIT); @@ -745,15 +746,53 @@ void Generic6DOFJoint3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_RESTITUTION); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_y", "get_param_y", PARAM_LINEAR_UPPER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_y", "get_param_y", PARAM_LINEAR_LOWER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_DAMPING); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_z", "get_param_z", PARAM_LINEAR_UPPER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_z", "get_param_z", PARAM_LINEAR_LOWER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_DAMPING); + + ADD_GROUP("Linear Motor", "linear_motor_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_MOTOR); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_x/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_MOTOR); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_MOTOR); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + + ADD_GROUP("Linear Spring", "linear_spring_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_SPRING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_STIFFNESS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/damping"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/damping"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/damping"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); + + ADD_GROUP("Angular Limit", "angular_limit_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_LIMIT); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_x/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_x", "_get_angular_hi_limit_x"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_x/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_x", "_get_angular_lo_limit_x"); @@ -763,68 +802,15 @@ void Generic6DOFJoint3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/erp"), "set_param_x", "get_param_x", PARAM_ANGULAR_ERP); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/damping"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); - - // Y - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_y", "get_param_y", PARAM_LINEAR_UPPER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_y", "get_param_y", PARAM_LINEAR_LOWER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_DAMPING); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_FORCE_LIMIT); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/damping"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_LIMIT); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_y/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_y", "_get_angular_hi_limit_y"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_y/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_y", "_get_angular_lo_limit_y"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_LIMIT_SOFTNESS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_RESTITUTION); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/erp"), "set_param_y", "get_param_y", PARAM_ANGULAR_ERP); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/damping"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); - - // Z - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_z", "get_param_z", PARAM_LINEAR_UPPER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_z", "get_param_z", PARAM_LINEAR_LOWER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_DAMPING); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_FORCE_LIMIT); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/damping"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_ANGULAR_LIMIT); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_z/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_z", "_get_angular_hi_limit_z"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_z/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_z", "_get_angular_lo_limit_z"); @@ -834,10 +820,32 @@ void Generic6DOFJoint3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/erp"), "set_param_z", "get_param_z", PARAM_ANGULAR_ERP); + ADD_GROUP("Angular Motor", "angular_motor_"); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_MOTOR); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_MOTOR); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_MOTOR); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_z/target_velocity"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + ADD_GROUP("Angular Spring", "angular_spring_"); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/damping"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/damping"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_ANGULAR_SPRING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_STIFFNESS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/damping"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_DAMPING); diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index bc435c5451..712a37e745 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -126,7 +126,7 @@ void Label3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_draw_flag", "get_draw_flag", FLAG_DISABLE_DEPTH_TEST); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size"), "set_draw_flag", "get_draw_flag", FLAG_FIXED_SIZE); ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass"), "set_alpha_cut_mode", "get_alpha_cut_mode"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_outline_render_priority", "get_outline_render_priority"); diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 678c217676..53c072c318 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -224,7 +224,7 @@ bool Light3D::is_editor_only() const { } void Light3D::_validate_property(PropertyInfo &property) const { - if (!shadow && (property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_fog_fade" || property.name == "shadow_blur" || property.name == "distance_fade_shadow")) { + if (!shadow && (property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_fog_fade" || property.name == "shadow_opacity" || property.name == "shadow_blur" || property.name == "distance_fade_shadow")) { property.usage = PROPERTY_USAGE_NO_EDITOR; } @@ -299,6 +299,7 @@ void Light3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_fog_fade", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_param", "get_param", PARAM_SHADOW_VOLUMETRIC_FOG_FADE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_OPACITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BLUR); ADD_GROUP("Distance Fade", "distance_fade_"); @@ -328,6 +329,7 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_SHADOW_NORMAL_BIAS); BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS); BIND_ENUM_CONSTANT(PARAM_SHADOW_PANCAKE_SIZE); + BIND_ENUM_CONSTANT(PARAM_SHADOW_OPACITY); BIND_ENUM_CONSTANT(PARAM_SHADOW_BLUR); BIND_ENUM_CONSTANT(PARAM_SHADOW_VOLUMETRIC_FOG_FADE); BIND_ENUM_CONSTANT(PARAM_TRANSMITTANCE_BIAS); @@ -375,6 +377,7 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5); set_param(PARAM_SHADOW_FADE_START, 0.8); set_param(PARAM_SHADOW_PANCAKE_SIZE, 20.0); + set_param(PARAM_SHADOW_OPACITY, 1.0); set_param(PARAM_SHADOW_BLUR, 1.0); set_param(PARAM_SHADOW_BIAS, 0.03); set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 6ff332df5a..ef003e133d 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -54,6 +54,7 @@ public: PARAM_SHADOW_NORMAL_BIAS = RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS, PARAM_SHADOW_BIAS = RS::LIGHT_PARAM_SHADOW_BIAS, PARAM_SHADOW_PANCAKE_SIZE = RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE, + PARAM_SHADOW_OPACITY = RS::LIGHT_PARAM_SHADOW_OPACITY, PARAM_SHADOW_BLUR = RS::LIGHT_PARAM_SHADOW_BLUR, PARAM_SHADOW_VOLUMETRIC_FOG_FADE = RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE, PARAM_TRANSMITTANCE_BIAS = RS::LIGHT_PARAM_TRANSMITTANCE_BIAS, diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index e805d28ed3..6b6a2eff9e 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -1219,7 +1219,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa } data->set_path(p_image_data_path); - Error err = ResourceSaver::save(p_image_data_path, data); + Error err = ResourceSaver::save(data); if (err != OK) { return BAKE_ERROR_CANT_CREATE_IMAGE; diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 2a8149c6f6..4150b01651 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -49,14 +49,29 @@ void NavigationRegion3D::set_enabled(bool p_enabled) { NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); } - if (debug_view) { - MeshInstance3D *dm = Object::cast_to<MeshInstance3D>(debug_view); - if (is_enabled()) { - dm->set_material_override(get_tree()->get_debug_navigation_material()); +#ifdef DEBUG_ENABLED + if (debug_instance.is_valid()) { + if (!is_enabled()) { + if (debug_mesh.is_valid()) { + if (debug_mesh->get_surface_count() > 0) { + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 0, NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_face_disabled_material()->get_rid()); + } + if (debug_mesh->get_surface_count() > 1) { + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 1, NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_edge_disabled_material()->get_rid()); + } + } } else { - dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); + if (debug_mesh.is_valid()) { + if (debug_mesh->get_surface_count() > 0) { + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 0, RID()); + } + if (debug_mesh->get_surface_count() > 1) { + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 1, RID()); + } + } } } +#endif // DEBUG_ENABLED update_gizmos(); } @@ -104,7 +119,7 @@ real_t NavigationRegion3D::get_enter_cost() const { void NavigationRegion3D::set_travel_cost(real_t p_travel_cost) { ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive."); travel_cost = MAX(p_travel_cost, 0.0); - NavigationServer3D::get_singleton()->region_set_enter_cost(region, travel_cost); + NavigationServer3D::get_singleton()->region_set_travel_cost(region, travel_cost); } real_t NavigationRegion3D::get_travel_cost() const { @@ -124,30 +139,36 @@ void NavigationRegion3D::_notification(int p_what) { NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); } - if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) { - MeshInstance3D *dm = memnew(MeshInstance3D); - dm->set_mesh(navmesh->get_debug_mesh()); - if (is_enabled()) { - dm->set_material_override(get_tree()->get_debug_navigation_material()); - } else { - dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); - } - add_child(dm); - debug_view = dm; +#ifdef DEBUG_ENABLED + if (NavigationServer3D::get_singleton()->get_debug_enabled()) { + _update_debug_mesh(); } +#endif // DEBUG_ENABLED + } break; case NOTIFICATION_TRANSFORM_CHANGED: { NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform()); + +#ifdef DEBUG_ENABLED + if (is_inside_tree() && debug_instance.is_valid()) { + RS::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); + } +#endif // DEBUG_ENABLED + } break; case NOTIFICATION_EXIT_TREE: { NavigationServer3D::get_singleton()->region_set_map(region, RID()); - if (debug_view) { - debug_view->queue_delete(); - debug_view = nullptr; +#ifdef DEBUG_ENABLED + if (debug_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_instance, false); + } + if (debug_edge_connections_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, false); } +#endif // DEBUG_ENABLED } break; } } @@ -169,20 +190,21 @@ void NavigationRegion3D::set_navigation_mesh(const Ref<NavigationMesh> &p_navmes NavigationServer3D::get_singleton()->region_set_navmesh(region, p_navmesh); - if (debug_view == nullptr && is_inside_tree() && navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) { - MeshInstance3D *dm = memnew(MeshInstance3D); - dm->set_mesh(navmesh->get_debug_mesh()); - if (is_enabled()) { - dm->set_material_override(get_tree()->get_debug_navigation_material()); +#ifdef DEBUG_ENABLED + if (is_inside_tree() && NavigationServer3D::get_singleton()->get_debug_enabled()) { + if (navmesh.is_valid()) { + _update_debug_mesh(); + _update_debug_edge_connections_mesh(); } else { - dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); + if (debug_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_instance, false); + } + if (debug_edge_connections_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, false); + } } - add_child(dm); - debug_view = dm; - } - if (debug_view && navmesh.is_valid()) { - Object::cast_to<MeshInstance3D>(debug_view)->set_mesh(navmesh->get_debug_mesh()); } +#endif // DEBUG_ENABLED emit_signal(SNAME("navigation_mesh_changed")); @@ -287,13 +309,31 @@ void NavigationRegion3D::_bind_methods() { void NavigationRegion3D::_navigation_changed() { update_gizmos(); update_configuration_warnings(); + +#ifdef DEBUG_ENABLED + _update_debug_edge_connections_mesh(); +#endif // DEBUG_ENABLED +} + +#ifdef DEBUG_ENABLED +void NavigationRegion3D::_navigation_map_changed(RID p_map) { + if (is_inside_tree() && p_map == get_world_3d()->get_navigation_map()) { + _update_debug_edge_connections_mesh(); + } } +#endif // DEBUG_ENABLED NavigationRegion3D::NavigationRegion3D() { set_notify_transform(true); region = NavigationServer3D::get_singleton()->region_create(); NavigationServer3D::get_singleton()->region_set_enter_cost(region, get_enter_cost()); NavigationServer3D::get_singleton()->region_set_travel_cost(region, get_travel_cost()); + +#ifdef DEBUG_ENABLED + NavigationServer3D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion3D::_navigation_map_changed)); + NavigationServer3D::get_singleton_mut()->connect("navigation_debug_changed", callable_mp(this, &NavigationRegion3D::_update_debug_mesh)); + NavigationServer3D::get_singleton_mut()->connect("navigation_debug_changed", callable_mp(this, &NavigationRegion3D::_update_debug_edge_connections_mesh)); +#endif // DEBUG_ENABLED } NavigationRegion3D::~NavigationRegion3D() { @@ -301,4 +341,245 @@ NavigationRegion3D::~NavigationRegion3D() { navmesh->disconnect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed)); } NavigationServer3D::get_singleton()->free(region); + +#ifdef DEBUG_ENABLED + NavigationServer3D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion3D::_navigation_map_changed)); + NavigationServer3D::get_singleton_mut()->disconnect("navigation_debug_changed", callable_mp(this, &NavigationRegion3D::_update_debug_mesh)); + NavigationServer3D::get_singleton_mut()->disconnect("navigation_debug_changed", callable_mp(this, &NavigationRegion3D::_update_debug_edge_connections_mesh)); + if (debug_instance.is_valid()) { + RenderingServer::get_singleton()->free(debug_instance); + } + if (debug_mesh.is_valid()) { + RenderingServer::get_singleton()->free(debug_mesh->get_rid()); + } + if (debug_edge_connections_instance.is_valid()) { + RenderingServer::get_singleton()->free(debug_edge_connections_instance); + } + if (debug_edge_connections_mesh.is_valid()) { + RenderingServer::get_singleton()->free(debug_edge_connections_mesh->get_rid()); + } +#endif // DEBUG_ENABLED +} + +#ifdef DEBUG_ENABLED +void NavigationRegion3D::_update_debug_mesh() { + if (!NavigationServer3D::get_singleton()->get_debug_enabled()) { + if (debug_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_instance, false); + } + return; + } + + if (!navmesh.is_valid()) { + if (debug_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_instance, false); + } + return; + } + + if (!debug_instance.is_valid()) { + debug_instance = RenderingServer::get_singleton()->instance_create(); + } + + if (!debug_mesh.is_valid()) { + debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + } + + debug_mesh->clear_surfaces(); + + bool enabled_geometry_face_random_color = NavigationServer3D::get_singleton()->get_debug_navigation_enable_geometry_face_random_color(); + bool enabled_edge_lines = NavigationServer3D::get_singleton()->get_debug_navigation_enable_edge_lines(); + + Vector<Vector3> vertices = navmesh->get_vertices(); + if (vertices.size() == 0) { + return; + } + + int polygon_count = navmesh->get_polygon_count(); + if (polygon_count == 0) { + return; + } + + Vector<Vector3> face_vertex_array; + face_vertex_array.resize(polygon_count * 3); + + Vector<Color> face_color_array; + if (enabled_geometry_face_random_color) { + face_color_array.resize(polygon_count * 3); + } + + Vector<Vector3> line_vertex_array; + if (enabled_edge_lines) { + line_vertex_array.resize(polygon_count * 6); + } + + Color debug_navigation_geometry_face_color = NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_color(); + + Ref<StandardMaterial3D> face_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_face_material(); + Ref<StandardMaterial3D> line_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_edge_material(); + + Color polygon_color = debug_navigation_geometry_face_color; + + for (int i = 0; i < polygon_count; i++) { + if (enabled_geometry_face_random_color) { + polygon_color = debug_navigation_geometry_face_color * (Color(Math::randf(), Math::randf(), Math::randf())); + } + + Vector<int> polygon = navmesh->get_polygon(i); + + face_vertex_array.push_back(vertices[polygon[0]]); + face_vertex_array.push_back(vertices[polygon[1]]); + face_vertex_array.push_back(vertices[polygon[2]]); + if (enabled_geometry_face_random_color) { + face_color_array.push_back(polygon_color); + face_color_array.push_back(polygon_color); + face_color_array.push_back(polygon_color); + } + + if (enabled_edge_lines) { + line_vertex_array.push_back(vertices[polygon[0]]); + line_vertex_array.push_back(vertices[polygon[1]]); + line_vertex_array.push_back(vertices[polygon[1]]); + line_vertex_array.push_back(vertices[polygon[2]]); + line_vertex_array.push_back(vertices[polygon[2]]); + line_vertex_array.push_back(vertices[polygon[0]]); + } + } + + Array face_mesh_array; + face_mesh_array.resize(Mesh::ARRAY_MAX); + face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array; + if (enabled_geometry_face_random_color) { + face_mesh_array[Mesh::ARRAY_COLOR] = face_color_array; + } + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, face_mesh_array); + debug_mesh->surface_set_material(0, face_material); + + if (enabled_edge_lines) { + Array line_mesh_array; + line_mesh_array.resize(Mesh::ARRAY_MAX); + line_mesh_array[Mesh::ARRAY_VERTEX] = line_vertex_array; + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, line_mesh_array); + debug_mesh->surface_set_material(1, line_material); + } + + RS::get_singleton()->instance_set_base(debug_instance, debug_mesh->get_rid()); + if (is_inside_tree()) { + RS::get_singleton()->instance_set_scenario(debug_instance, get_world_3d()->get_scenario()); + RS::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree()); + } + if (!is_enabled()) { + if (debug_mesh.is_valid()) { + if (debug_mesh->get_surface_count() > 0) { + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 0, NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_face_disabled_material()->get_rid()); + } + if (debug_mesh->get_surface_count() > 1) { + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 1, NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_edge_disabled_material()->get_rid()); + } + } + } else { + if (debug_mesh.is_valid()) { + if (debug_mesh->get_surface_count() > 0) { + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 0, RID()); + } + if (debug_mesh->get_surface_count() > 1) { + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 1, RID()); + } + } + } +} +#endif // DEBUG_ENABLED + +#ifdef DEBUG_ENABLED +void NavigationRegion3D::_update_debug_edge_connections_mesh() { + if (!NavigationServer3D::get_singleton()->get_debug_enabled()) { + if (debug_edge_connections_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, false); + } + return; + } + + if (!is_inside_tree()) { + return; + } + + if (!navmesh.is_valid()) { + if (debug_edge_connections_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, false); + } + return; + } + + if (!debug_edge_connections_instance.is_valid()) { + debug_edge_connections_instance = RenderingServer::get_singleton()->instance_create(); + } + + if (!debug_edge_connections_mesh.is_valid()) { + debug_edge_connections_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + } + + debug_edge_connections_mesh->clear_surfaces(); + + float edge_connection_margin = NavigationServer3D::get_singleton()->map_get_edge_connection_margin(get_world_3d()->get_navigation_map()); + float half_edge_connection_margin = edge_connection_margin * 0.5; + int connections_count = NavigationServer3D::get_singleton()->region_get_connections_count(region); + + if (connections_count == 0) { + RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, false); + return; + } + + Vector<Vector3> vertex_array; + + for (int i = 0; i < connections_count; i++) { + Vector3 connection_pathway_start = NavigationServer3D::get_singleton()->region_get_connection_pathway_start(region, i); + Vector3 connection_pathway_end = NavigationServer3D::get_singleton()->region_get_connection_pathway_end(region, i); + + Vector3 direction_start_end = connection_pathway_start.direction_to(connection_pathway_end); + Vector3 direction_end_start = connection_pathway_end.direction_to(connection_pathway_start); + + Vector3 start_right_dir = direction_start_end.cross(Vector3(0, 1, 0)); + Vector3 start_left_dir = -start_right_dir; + + Vector3 end_right_dir = direction_end_start.cross(Vector3(0, 1, 0)); + Vector3 end_left_dir = -end_right_dir; + + Vector3 left_start_pos = connection_pathway_start + (start_left_dir * half_edge_connection_margin); + Vector3 right_start_pos = connection_pathway_start + (start_right_dir * half_edge_connection_margin); + Vector3 left_end_pos = connection_pathway_end + (end_right_dir * half_edge_connection_margin); + Vector3 right_end_pos = connection_pathway_end + (end_left_dir * half_edge_connection_margin); + + vertex_array.push_back(right_end_pos); + vertex_array.push_back(left_start_pos); + vertex_array.push_back(right_start_pos); + + vertex_array.push_back(left_end_pos); + vertex_array.push_back(right_end_pos); + vertex_array.push_back(right_start_pos); + } + + if (vertex_array.size() == 0) { + return; + } + + Ref<StandardMaterial3D> edge_connections_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_edge_connections_material(); + + Array mesh_array; + mesh_array.resize(Mesh::ARRAY_MAX); + mesh_array[Mesh::ARRAY_VERTEX] = vertex_array; + + debug_edge_connections_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, mesh_array); + debug_edge_connections_mesh->surface_set_material(0, edge_connections_material); + + RS::get_singleton()->instance_set_base(debug_edge_connections_instance, debug_edge_connections_mesh->get_rid()); + RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, is_visible_in_tree()); + if (is_inside_tree()) { + RS::get_singleton()->instance_set_scenario(debug_edge_connections_instance, get_world_3d()->get_scenario()); + } + + bool enable_edge_connections = NavigationServer3D::get_singleton()->get_debug_navigation_enable_edge_connections(); + if (!enable_edge_connections) { + RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, false); + } } +#endif // DEBUG_ENABLED diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index b15e97de6a..ba326abb46 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -44,11 +44,22 @@ class NavigationRegion3D : public Node3D { real_t enter_cost = 0.0; real_t travel_cost = 1.0; - Node *debug_view = nullptr; Thread bake_thread; void _navigation_changed(); +#ifdef DEBUG_ENABLED + RID debug_instance; + RID debug_edge_connections_instance; + Ref<ArrayMesh> debug_mesh; + Ref<ArrayMesh> debug_edge_connections_mesh; + +private: + void _update_debug_mesh(); + void _update_debug_edge_connections_mesh(); + void _navigation_map_changed(RID p_map); +#endif // DEBUG_ENABLED + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 04b1081516..1de85d57a3 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -733,7 +733,7 @@ void Node3D::rotate_z(real_t p_angle) { void Node3D::translate(const Vector3 &p_offset) { Transform3D t = get_transform(); - t.translate(p_offset); + t.translate_local(p_offset); set_transform(t); } @@ -741,7 +741,7 @@ void Node3D::translate_object_local(const Vector3 &p_offset) { Transform3D t = get_transform(); Transform3D s; - s.translate(p_offset); + s.translate_local(p_offset); set_transform(t * s); } diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp index 66d0a8c4e2..c1c309fdbe 100644 --- a/scene/3d/occluder_instance_3d.cpp +++ b/scene/3d/occluder_instance_3d.cpp @@ -670,7 +670,7 @@ OccluderInstance3D::BakeError OccluderInstance3D::bake_scene(Node *p_from_node, occ->set_arrays(vertices, indices); - Error err = ResourceSaver::save(p_occluder_path, occ); + Error err = ResourceSaver::save(occ, p_occluder_path); if (err != OK) { return BAKE_ERROR_CANT_SAVE; diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 1f10337b4c..25226ad384 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -296,7 +296,7 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) { } } - t.translate(Vector3(h_offset, v_offset, 0)); + t.translate_local(Vector3(h_offset, v_offset, 0)); } else { t.origin = pos + Vector3(h_offset, v_offset, 0); } diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 30f7a025fa..993608c306 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -439,8 +439,8 @@ void RigidDynamicBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p //E->value.rc=0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidDynamicBody3D::_body_enter_tree), make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidDynamicBody3D::_body_exit_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidDynamicBody3D::_body_enter_tree).bind(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidDynamicBody3D::_body_exit_tree).bind(objid)); if (E->value.in_tree) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } diff --git a/scene/3d/shape_cast_3d.cpp b/scene/3d/shape_cast_3d.cpp new file mode 100644 index 0000000000..d324e09df5 --- /dev/null +++ b/scene/3d/shape_cast_3d.cpp @@ -0,0 +1,634 @@ +/*************************************************************************/ +/* shape_cast_3d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "shape_cast_3d.h" + +#include "collision_object_3d.h" +#include "mesh_instance_3d.h" +#include "scene/resources/concave_polygon_shape_3d.h" + +void ShapeCast3D::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + if (Engine::get_singleton()->is_editor_hint()) { + _update_debug_shape_vertices(); + } + if (enabled && !Engine::get_singleton()->is_editor_hint()) { + set_physics_process_internal(true); + } else { + set_physics_process_internal(false); + } + + if (get_tree()->is_debugging_collisions_hint()) { + _update_debug_shape(); + } + + if (Object::cast_to<CollisionObject3D>(get_parent())) { + if (exclude_parent_body) { + exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid()); + } else { + exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid()); + } + } + } break; + + case NOTIFICATION_EXIT_TREE: { + if (enabled) { + set_physics_process_internal(false); + } + + if (debug_shape) { + _clear_debug_shape(); + } + } break; + + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + if (!enabled) { + break; + } + + bool prev_collision_state = collided; + _update_shapecast_state(); + if (get_tree()->is_debugging_collisions_hint()) { + if (prev_collision_state != collided) { + _update_debug_shape_material(true); + } + if (collided) { + _update_debug_shape(); + } + if (prev_collision_state == collided && !collided) { + _update_debug_shape(); + } + } + } break; + } +} + +void ShapeCast3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("resource_changed", "resource"), &ShapeCast3D::resource_changed); + + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &ShapeCast3D::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &ShapeCast3D::is_enabled); + + ClassDB::bind_method(D_METHOD("set_shape", "shape"), &ShapeCast3D::set_shape); + ClassDB::bind_method(D_METHOD("get_shape"), &ShapeCast3D::get_shape); + + ClassDB::bind_method(D_METHOD("set_target_position", "local_point"), &ShapeCast3D::set_target_position); + ClassDB::bind_method(D_METHOD("get_target_position"), &ShapeCast3D::get_target_position); + + ClassDB::bind_method(D_METHOD("set_margin", "margin"), &ShapeCast3D::set_margin); + ClassDB::bind_method(D_METHOD("get_margin"), &ShapeCast3D::get_margin); + + ClassDB::bind_method(D_METHOD("set_max_results", "max_results"), &ShapeCast3D::set_max_results); + ClassDB::bind_method(D_METHOD("get_max_results"), &ShapeCast3D::get_max_results); + + ClassDB::bind_method(D_METHOD("is_colliding"), &ShapeCast3D::is_colliding); + ClassDB::bind_method(D_METHOD("get_collision_count"), &ShapeCast3D::get_collision_count); + + ClassDB::bind_method(D_METHOD("force_shapecast_update"), &ShapeCast3D::force_shapecast_update); + + ClassDB::bind_method(D_METHOD("get_collider", "index"), &ShapeCast3D::get_collider); + ClassDB::bind_method(D_METHOD("get_collider_shape", "index"), &ShapeCast3D::get_collider_shape); + ClassDB::bind_method(D_METHOD("get_collision_point", "index"), &ShapeCast3D::get_collision_point); + ClassDB::bind_method(D_METHOD("get_collision_normal", "index"), &ShapeCast3D::get_collision_normal); + + ClassDB::bind_method(D_METHOD("get_closest_collision_safe_fraction"), &ShapeCast3D::get_closest_collision_safe_fraction); + ClassDB::bind_method(D_METHOD("get_closest_collision_unsafe_fraction"), &ShapeCast3D::get_closest_collision_unsafe_fraction); + + ClassDB::bind_method(D_METHOD("add_exception_rid", "rid"), &ShapeCast3D::add_exception_rid); + ClassDB::bind_method(D_METHOD("add_exception", "node"), &ShapeCast3D::add_exception); + + ClassDB::bind_method(D_METHOD("remove_exception_rid", "rid"), &ShapeCast3D::remove_exception_rid); + ClassDB::bind_method(D_METHOD("remove_exception", "node"), &ShapeCast3D::remove_exception); + + ClassDB::bind_method(D_METHOD("clear_exceptions"), &ShapeCast3D::clear_exceptions); + + ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &ShapeCast3D::set_collision_mask); + ClassDB::bind_method(D_METHOD("get_collision_mask"), &ShapeCast3D::get_collision_mask); + + ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &ShapeCast3D::set_collision_mask_value); + ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &ShapeCast3D::get_collision_mask_value); + + ClassDB::bind_method(D_METHOD("set_exclude_parent_body", "mask"), &ShapeCast3D::set_exclude_parent_body); + ClassDB::bind_method(D_METHOD("get_exclude_parent_body"), &ShapeCast3D::get_exclude_parent_body); + + ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &ShapeCast3D::set_collide_with_areas); + ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &ShapeCast3D::is_collide_with_areas_enabled); + + ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &ShapeCast3D::set_collide_with_bodies); + ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &ShapeCast3D::is_collide_with_bodies_enabled); + + ClassDB::bind_method(D_METHOD("_get_collision_result"), &ShapeCast3D::_get_collision_result); + + ClassDB::bind_method(D_METHOD("set_debug_shape_custom_color", "debug_shape_custom_color"), &ShapeCast3D::set_debug_shape_custom_color); + ClassDB::bind_method(D_METHOD("get_debug_shape_custom_color"), &ShapeCast3D::get_debug_shape_custom_color); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position", PROPERTY_HINT_NONE, "suffix:m"), "set_target_position", "get_target_position"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01,suffix:m"), "set_margin", "get_margin"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_results"), "set_max_results", "get_max_results"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "collision_result", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "", "_get_collision_result"); + + ADD_GROUP("Collide With", "collide_with"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); + + ADD_GROUP("Debug Shape", "debug_shape"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_shape_custom_color"), "set_debug_shape_custom_color", "get_debug_shape_custom_color"); +} + +TypedArray<String> ShapeCast3D::get_configuration_warnings() const { + TypedArray<String> warnings = Node3D::get_configuration_warnings(); + + if (shape.is_null()) { + warnings.push_back(RTR("This node cannot interact with other objects unless a Shape3D is assigned.")); + } + if (shape.is_valid() && Object::cast_to<ConcavePolygonShape3D>(*shape)) { + warnings.push_back(RTR("ShapeCast3D does not support ConcavePolygonShape3Ds. Collisions will not be reported.")); + } + return warnings; +} + +void ShapeCast3D::set_enabled(bool p_enabled) { + enabled = p_enabled; + update_gizmos(); + + if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) { + set_physics_process_internal(p_enabled); + } + if (!p_enabled) { + collided = false; + } + + if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) { + if (p_enabled) { + _update_debug_shape(); + } else { + _clear_debug_shape(); + } + } +} + +bool ShapeCast3D::is_enabled() const { + return enabled; +} + +void ShapeCast3D::set_target_position(const Vector3 &p_point) { + target_position = p_point; + if (is_inside_tree()) { + _update_debug_shape(); + } + update_gizmos(); + + if (Engine::get_singleton()->is_editor_hint()) { + if (is_inside_tree()) { + _update_debug_shape_vertices(); + } + } else if (debug_shape) { + _update_debug_shape(); + } +} + +Vector3 ShapeCast3D::get_target_position() const { + return target_position; +} + +void ShapeCast3D::set_margin(real_t p_margin) { + margin = p_margin; +} + +real_t ShapeCast3D::get_margin() const { + return margin; +} + +void ShapeCast3D::set_max_results(int p_max_results) { + max_results = p_max_results; +} + +int ShapeCast3D::get_max_results() const { + return max_results; +} + +void ShapeCast3D::set_collision_mask(uint32_t p_mask) { + collision_mask = p_mask; +} + +uint32_t ShapeCast3D::get_collision_mask() const { + return collision_mask; +} + +void ShapeCast3D::set_collision_mask_value(int p_layer_number, bool p_value) { + ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive."); + uint32_t mask = get_collision_mask(); + if (p_value) { + mask |= 1 << (p_layer_number - 1); + } else { + mask &= ~(1 << (p_layer_number - 1)); + } + set_collision_mask(mask); +} + +bool ShapeCast3D::get_collision_mask_value(int p_layer_number) const { + ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive."); + return get_collision_mask() & (1 << (p_layer_number - 1)); +} + +int ShapeCast3D::get_collision_count() const { + return result.size(); +} + +bool ShapeCast3D::is_colliding() const { + return collided; +} + +Object *ShapeCast3D::get_collider(int p_idx) const { + ERR_FAIL_INDEX_V_MSG(p_idx, result.size(), nullptr, "No collider found."); + + if (result[p_idx].collider_id.is_null()) { + return nullptr; + } + return ObjectDB::get_instance(result[p_idx].collider_id); +} + +int ShapeCast3D::get_collider_shape(int p_idx) const { + ERR_FAIL_INDEX_V_MSG(p_idx, result.size(), -1, "No collider shape found."); + return result[p_idx].shape; +} + +Vector3 ShapeCast3D::get_collision_point(int p_idx) const { + ERR_FAIL_INDEX_V_MSG(p_idx, result.size(), Vector3(), "No collision point found."); + return result[p_idx].point; +} + +Vector3 ShapeCast3D::get_collision_normal(int p_idx) const { + ERR_FAIL_INDEX_V_MSG(p_idx, result.size(), Vector3(), "No collision normal found."); + return result[p_idx].normal; +} + +real_t ShapeCast3D::get_closest_collision_safe_fraction() const { + return collision_safe_fraction; +} + +real_t ShapeCast3D::get_closest_collision_unsafe_fraction() const { + return collision_unsafe_fraction; +} + +void ShapeCast3D::resource_changed(Ref<Resource> p_res) { + if (is_inside_tree()) { + _update_debug_shape(); + } + update_gizmos(); +} + +void ShapeCast3D::set_shape(const Ref<Shape3D> &p_shape) { + if (p_shape == shape) { + return; + } + if (!shape.is_null()) { + shape->unregister_owner(this); + } + shape = p_shape; + if (!shape.is_null()) { + shape->register_owner(this); + } + if (p_shape.is_valid()) { + shape_rid = shape->get_rid(); + } + + if (is_inside_tree()) { + _update_debug_shape(); + } + + update_gizmos(); + update_configuration_warnings(); +} + +Ref<Shape3D> ShapeCast3D::get_shape() const { + return shape; +} + +void ShapeCast3D::set_exclude_parent_body(bool p_exclude_parent_body) { + if (exclude_parent_body == p_exclude_parent_body) { + return; + } + exclude_parent_body = p_exclude_parent_body; + + if (!is_inside_tree()) { + return; + } + if (Object::cast_to<CollisionObject3D>(get_parent())) { + if (exclude_parent_body) { + exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid()); + } else { + exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid()); + } + } +} + +bool ShapeCast3D::get_exclude_parent_body() const { + return exclude_parent_body; +} + +void ShapeCast3D::_update_shapecast_state() { + result.clear(); + + ERR_FAIL_COND_MSG(shape.is_null(), "Null reference to shape. ShapeCast3D requires a Shape3D to sweep for collisions."); + + Ref<World3D> w3d = get_world_3d(); + ERR_FAIL_COND(w3d.is_null()); + + PhysicsDirectSpaceState3D *dss = PhysicsServer3D::get_singleton()->space_get_direct_state(w3d->get_space()); + ERR_FAIL_COND(!dss); + + Transform3D gt = get_global_transform(); + + PhysicsDirectSpaceState3D::ShapeParameters params; + params.shape_rid = shape_rid; + params.transform = gt; + params.motion = gt.basis.xform(target_position); + params.margin = margin; + params.exclude = exclude; + params.collision_mask = collision_mask; + params.collide_with_bodies = collide_with_bodies; + params.collide_with_areas = collide_with_areas; + + collision_safe_fraction = 0.0; + collision_unsafe_fraction = 0.0; + + if (target_position != Vector3()) { + dss->cast_motion(params, collision_safe_fraction, collision_unsafe_fraction); + if (collision_unsafe_fraction < 1.0) { + // Move shape transform to the point of impact, + // so we can collect contact info at that point. + gt.set_origin(gt.get_origin() + params.motion * (collision_unsafe_fraction + CMP_EPSILON)); + params.transform = gt; + } + } + // Regardless of whether the shape is stuck or it's moved along + // the motion vector, we'll only consider static collisions from now on. + params.motion = Vector3(); + + bool intersected = true; + while (intersected && result.size() < max_results) { + PhysicsDirectSpaceState3D::ShapeRestInfo info; + intersected = dss->rest_info(params, &info); + if (intersected) { + result.push_back(info); + params.exclude.insert(info.rid); + } + } + collided = !result.is_empty(); +} + +void ShapeCast3D::force_shapecast_update() { + _update_shapecast_state(); +} + +void ShapeCast3D::add_exception_rid(const RID &p_rid) { + exclude.insert(p_rid); +} + +void ShapeCast3D::add_exception(const Object *p_object) { + ERR_FAIL_NULL(p_object); + const CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_object); + if (!co) { + return; + } + add_exception_rid(co->get_rid()); +} + +void ShapeCast3D::remove_exception_rid(const RID &p_rid) { + exclude.erase(p_rid); +} + +void ShapeCast3D::remove_exception(const Object *p_object) { + ERR_FAIL_NULL(p_object); + const CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_object); + if (!co) { + return; + } + remove_exception_rid(co->get_rid()); +} + +void ShapeCast3D::clear_exceptions() { + exclude.clear(); +} + +void ShapeCast3D::set_collide_with_areas(bool p_clip) { + collide_with_areas = p_clip; +} + +bool ShapeCast3D::is_collide_with_areas_enabled() const { + return collide_with_areas; +} + +void ShapeCast3D::set_collide_with_bodies(bool p_clip) { + collide_with_bodies = p_clip; +} + +bool ShapeCast3D::is_collide_with_bodies_enabled() const { + return collide_with_bodies; +} + +Array ShapeCast3D::_get_collision_result() const { + Array ret; + + for (int i = 0; i < result.size(); ++i) { + const PhysicsDirectSpaceState3D::ShapeRestInfo &sri = result[i]; + + Dictionary col; + col["point"] = sri.point; + col["normal"] = sri.normal; + col["rid"] = sri.rid; + col["collider"] = ObjectDB::get_instance(sri.collider_id); + col["collider_id"] = sri.collider_id; + col["shape"] = sri.shape; + col["linear_velocity"] = sri.linear_velocity; + + ret.push_back(col); + } + return ret; +} + +void ShapeCast3D::_update_debug_shape_vertices() { + debug_shape_vertices.clear(); + debug_line_vertices.clear(); + + if (!shape.is_null()) { + debug_shape_vertices.append_array(shape->get_debug_mesh_lines()); + for (int i = 0; i < debug_shape_vertices.size(); i++) { + debug_shape_vertices.set(i, debug_shape_vertices[i] + Vector3(target_position * get_closest_collision_safe_fraction())); + } + } + + if (target_position == Vector3()) { + return; + } + + debug_line_vertices.push_back(Vector3()); + debug_line_vertices.push_back(target_position); +} + +const Vector<Vector3> &ShapeCast3D::get_debug_shape_vertices() const { + return debug_shape_vertices; +} + +const Vector<Vector3> &ShapeCast3D::get_debug_line_vertices() const { + return debug_line_vertices; +} + +void ShapeCast3D::set_debug_shape_custom_color(const Color &p_color) { + debug_shape_custom_color = p_color; + if (debug_material.is_valid()) { + _update_debug_shape_material(); + } +} + +Ref<StandardMaterial3D> ShapeCast3D::get_debug_material() { + _update_debug_shape_material(); + return debug_material; +} + +const Color &ShapeCast3D::get_debug_shape_custom_color() const { + return debug_shape_custom_color; +} + +void ShapeCast3D::_create_debug_shape() { + _update_debug_shape_material(); + + Ref<ArrayMesh> mesh = memnew(ArrayMesh); + + MeshInstance3D *mi = memnew(MeshInstance3D); + mi->set_mesh(mesh); + + add_child(mi); + debug_shape = mi; +} + +void ShapeCast3D::_update_debug_shape_material(bool p_check_collision) { + if (!debug_material.is_valid()) { + Ref<StandardMaterial3D> material = memnew(StandardMaterial3D); + debug_material = material; + + material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + // Use double-sided rendering so that the RayCast can be seen if the camera is inside. + material->set_cull_mode(BaseMaterial3D::CULL_DISABLED); + material->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA); + } + + Color color = debug_shape_custom_color; + if (color == Color(0.0, 0.0, 0.0)) { + // Use the default debug shape color defined in the Project Settings. + color = get_tree()->get_debug_collisions_color(); + } + + if (p_check_collision && collided) { + if ((color.get_h() < 0.055 || color.get_h() > 0.945) && color.get_s() > 0.5 && color.get_v() > 0.5) { + // If base color is already quite reddish, highlight collision with green color + color = Color(0.0, 1.0, 0.0, color.a); + } else { + // Else, highlight collision with red color + color = Color(1.0, 0, 0, color.a); + } + } + + Ref<StandardMaterial3D> material = static_cast<Ref<StandardMaterial3D>>(debug_material); + material->set_albedo(color); +} + +void ShapeCast3D::_update_debug_shape() { + if (!enabled) { + return; + } + + if (!debug_shape) { + _create_debug_shape(); + } + + _update_debug_shape_vertices(); + + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + + MeshInstance3D *mi = static_cast<MeshInstance3D *>(debug_shape); + Ref<ArrayMesh> mesh = mi->get_mesh(); + if (!mesh.is_valid()) { + return; + } + + mesh->clear_surfaces(); + + Array a; + a.resize(Mesh::ARRAY_MAX); + + uint32_t flags = 0; + int surface_count = 0; + + if (!debug_shape_vertices.is_empty()) { + a[Mesh::ARRAY_VERTEX] = debug_shape_vertices; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); + mesh->surface_set_material(surface_count, debug_material); + ++surface_count; + } + + if (!debug_line_vertices.is_empty()) { + a[Mesh::ARRAY_VERTEX] = debug_line_vertices; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); + mesh->surface_set_material(surface_count, debug_material); + ++surface_count; + } +} + +void ShapeCast3D::_clear_debug_shape() { + if (!debug_shape) { + return; + } + + MeshInstance3D *mi = static_cast<MeshInstance3D *>(debug_shape); + if (mi->is_inside_tree()) { + mi->queue_delete(); + } else { + memdelete(mi); + } + + debug_shape = nullptr; +} + +ShapeCast3D::~ShapeCast3D() { + if (!shape.is_null()) { + shape->unregister_owner(this); + } +} diff --git a/scene/3d/shape_cast_3d.h b/scene/3d/shape_cast_3d.h new file mode 100644 index 0000000000..5bda15e4b0 --- /dev/null +++ b/scene/3d/shape_cast_3d.h @@ -0,0 +1,142 @@ +/*************************************************************************/ +/* shape_cast_3d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SHAPE_CAST_3D_H +#define SHAPE_CAST_3D_H + +#include "scene/3d/node_3d.h" +#include "scene/resources/shape_3d.h" + +class ShapeCast3D : public Node3D { + GDCLASS(ShapeCast3D, Node3D); + + bool enabled = true; + void resource_changed(Ref<Resource> p_res); + + Ref<Shape3D> shape; + RID shape_rid; + Vector3 target_position = Vector3(0, -1, 0); + + HashSet<RID> exclude; + real_t margin = 0.0; + uint32_t collision_mask = 1; + bool exclude_parent_body = true; + bool collide_with_areas = false; + bool collide_with_bodies = true; + + Node *debug_shape = nullptr; + Ref<Material> debug_material; + Color debug_shape_custom_color = Color(0.0, 0.0, 0.0); + Vector<Vector3> debug_shape_vertices; + Vector<Vector3> debug_line_vertices; + + void _create_debug_shape(); + void _update_debug_shape(); + void _update_debug_shape_material(bool p_check_collision = false); + void _update_debug_shape_vertices(); + void _clear_debug_shape(); + + // Result + int max_results = 32; + Vector<PhysicsDirectSpaceState3D::ShapeRestInfo> result; + bool collided = false; + real_t collision_safe_fraction = 1.0; + real_t collision_unsafe_fraction = 1.0; + + Array _get_collision_result() const; + + ~ShapeCast3D(); + +protected: + void _notification(int p_what); + void _update_shapecast_state(); + static void _bind_methods(); + +public: + void set_collide_with_areas(bool p_clip); + bool is_collide_with_areas_enabled() const; + + void set_collide_with_bodies(bool p_clip); + bool is_collide_with_bodies_enabled() const; + + void set_enabled(bool p_enabled); + bool is_enabled() const; + + void set_shape(const Ref<Shape3D> &p_shape); + Ref<Shape3D> get_shape() const; + + void set_target_position(const Vector3 &p_point); + Vector3 get_target_position() const; + + void set_margin(real_t p_margin); + real_t get_margin() const; + + void set_max_results(int p_max_results); + int get_max_results() const; + + void set_collision_mask(uint32_t p_mask); + uint32_t get_collision_mask() const; + + void set_collision_mask_value(int p_layer_number, bool p_value); + bool get_collision_mask_value(int p_layer_number) const; + + void set_exclude_parent_body(bool p_exclude_parent_body); + bool get_exclude_parent_body() const; + + const Color &get_debug_shape_custom_color() const; + void set_debug_shape_custom_color(const Color &p_color); + + const Vector<Vector3> &get_debug_shape_vertices() const; + const Vector<Vector3> &get_debug_line_vertices() const; + + Ref<StandardMaterial3D> get_debug_material(); + + int get_collision_count() const; + Object *get_collider(int p_idx) const; + int get_collider_shape(int p_idx) const; + Vector3 get_collision_point(int p_idx) const; + Vector3 get_collision_normal(int p_idx) const; + + real_t get_closest_collision_safe_fraction() const; + real_t get_closest_collision_unsafe_fraction() const; + + void force_shapecast_update(); + bool is_colliding() const; + + void add_exception_rid(const RID &p_rid); + void add_exception(const Object *p_object); + void remove_exception_rid(const RID &p_rid); + void remove_exception(const Object *p_object); + void clear_exceptions(); + + virtual TypedArray<String> get_configuration_warnings() const override; +}; + +#endif // SHAPE_CAST_3D_H diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index b342660b85..4c38fccc8b 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -493,6 +493,19 @@ int Skeleton3D::get_bone_axis_forward_enum(int p_bone) { return bones[p_bone].rest_bone_forward_axis; } +void Skeleton3D::set_motion_scale(float p_motion_scale) { + if (p_motion_scale <= 0) { + motion_scale = 1; + ERR_FAIL_MSG("Motion scale must be larger than 0."); + } + motion_scale = p_motion_scale; +} + +float Skeleton3D::get_motion_scale() const { + ERR_FAIL_COND_V(motion_scale <= 0, 1); + return motion_scale; +} + // Skeleton creation api void Skeleton3D::add_bone(const String &p_name) { @@ -1255,6 +1268,9 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("force_update_all_bone_transforms"), &Skeleton3D::force_update_all_bone_transforms); ClassDB::bind_method(D_METHOD("force_update_bone_child_transform", "bone_idx"), &Skeleton3D::force_update_bone_children_transforms); + ClassDB::bind_method(D_METHOD("set_motion_scale", "motion_scale"), &Skeleton3D::set_motion_scale); + ClassDB::bind_method(D_METHOD("get_motion_scale"), &Skeleton3D::get_motion_scale); + // Helper functions ClassDB::bind_method(D_METHOD("global_pose_to_world_transform", "global_pose"), &Skeleton3D::global_pose_to_world_transform); ClassDB::bind_method(D_METHOD("world_transform_to_global_pose", "world_transform"), &Skeleton3D::world_transform_to_global_pose); @@ -1278,15 +1294,13 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_modification_stack"), &Skeleton3D::get_modification_stack); ClassDB::bind_method(D_METHOD("execute_modifications", "delta", "execution_mode"), &Skeleton3D::execute_modifications); -#ifndef _3D_DISABLED + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "motion_scale", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater"), "set_motion_scale", "get_motion_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_rest_only"), "set_show_rest_only", "is_show_rest_only"); +#ifndef _3D_DISABLED ADD_PROPERTY(PropertyInfo(Variant::BOOL, "animate_physical_bones"), "set_animate_physical_bones", "get_animate_physical_bones"); #endif // _3D_DISABLED -#ifdef TOOLS_ENABLED ADD_SIGNAL(MethodInfo("pose_updated")); -#endif // TOOLS_ENABLED - ADD_SIGNAL(MethodInfo("bone_pose_changed", PropertyInfo(Variant::INT, "bone_idx"))); ADD_SIGNAL(MethodInfo("bone_enabled_changed", PropertyInfo(Variant::INT, "bone_idx"))); ADD_SIGNAL(MethodInfo("show_rest_only_changed")); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index fcb8774c3d..8b69410a39 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -146,6 +146,7 @@ private: bool rest_dirty = false; bool show_rest_only = false; + float motion_scale = 1.0; uint64_t version = 1; @@ -211,6 +212,9 @@ public: bool is_show_rest_only() const; void clear_bones(); + void set_motion_scale(float p_motion_scale); + float get_motion_scale() const; + // posing api void set_bone_pose_position(int p_bone, const Vector3 &p_position); diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index d68e7fd527..15f050defb 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -83,7 +83,16 @@ void SoftDynamicBodyRenderingServerHandler::set_vertex(int p_vertex_id, const vo } void SoftDynamicBodyRenderingServerHandler::set_normal(int p_vertex_id, const void *p_vector3) { - memcpy(&write_buffer[p_vertex_id * stride + offset_normal], p_vector3, sizeof(float) * 3); + // Store normal vector in A2B10G10R10 format. + Vector3 n; + memcpy(&n, p_vector3, sizeof(Vector3)); + n *= Vector3(0.5, 0.5, 0.5); + n += Vector3(0.5, 0.5, 0.5); + uint32_t value = 0; + value |= CLAMP(int(n.x * 1023.0), 0, 1023); + value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10; + value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20; + memcpy(&write_buffer[p_vertex_id * stride + offset_normal], &value, sizeof(uint32_t)); } void SoftDynamicBodyRenderingServerHandler::set_aabb(const AABB &p_aabb) { diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index cb6354f7a8..ef2b9e1ce5 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -377,7 +377,7 @@ SpriteBase3D::SpriteBase3D() { RS::get_singleton()->material_set_param(material, "uv1_scale", Vector3(1, 1, 1)); RS::get_singleton()->material_set_param(material, "uv2_offset", Vector3(0, 0, 0)); RS::get_singleton()->material_set_param(material, "uv2_scale", Vector3(1, 1, 1)); - RS::get_singleton()->material_set_param(material, "alpha_scissor_threshold", 0.98); + RS::get_singleton()->material_set_param(material, "alpha_scissor_threshold", 0.5); mesh = RenderingServer::get_singleton()->mesh_create(); diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 69917f6992..5af06cff29 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -227,8 +227,8 @@ const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringNa StringName *r = instance_uniform_property_remap.getptr(p_name); if (!r) { String s = p_name; - if (s.begins_with("shader_params/")) { - StringName name = s.replace("shader_params/", ""); + if (s.begins_with("shader_uniforms/")) { + StringName name = s.replace("shader_uniforms/", ""); instance_uniform_property_remap[p_name] = name; return instance_uniform_property_remap.getptr(p_name); } @@ -242,7 +242,7 @@ const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringNa bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) { const StringName *r = _instance_uniform_get_remap(p_name); if (r) { - set_shader_instance_uniform(*r, p_value); + set_instance_shader_uniform(*r, p_value); return true; } #ifndef DISABLE_DEPRECATED @@ -262,7 +262,7 @@ bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { const StringName *r = _instance_uniform_get_remap(p_name); if (r) { - r_ret = get_shader_instance_uniform(*r); + r_ret = get_instance_shader_uniform(*r); return true; } @@ -271,10 +271,10 @@ bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { List<PropertyInfo> pinfo; - RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo); + RS::get_singleton()->instance_geometry_get_shader_uniform_list(get_instance(), &pinfo); for (PropertyInfo &pi : pinfo) { bool has_def_value = false; - Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), pi.name); + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_uniform_default_value(get_instance(), pi.name); if (def_value.get_type() != Variant::NIL) { has_def_value = true; } @@ -284,7 +284,7 @@ void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { pi.usage = PROPERTY_USAGE_EDITOR | (has_def_value ? PROPERTY_USAGE_CHECKABLE : PROPERTY_USAGE_NONE); //do not save if not changed } - pi.name = "shader_params/" + pi.name; + pi.name = "shader_uniforms/" + pi.name; p_list->push_back(pi); } } @@ -319,24 +319,24 @@ float GeometryInstance3D::get_lod_bias() const { return lod_bias; } -void GeometryInstance3D::set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value) { +void GeometryInstance3D::set_instance_shader_uniform(const StringName &p_uniform, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { - Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_uniform); - RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, def_value); + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_uniform_default_value(get_instance(), p_uniform); + RS::get_singleton()->instance_geometry_set_shader_uniform(get_instance(), p_uniform, def_value); instance_uniforms.erase(p_value); } else { instance_uniforms[p_uniform] = p_value; if (p_value.get_type() == Variant::OBJECT) { RID tex_id = p_value; - RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, tex_id); + RS::get_singleton()->instance_geometry_set_shader_uniform(get_instance(), p_uniform, tex_id); } else { - RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, p_value); + RS::get_singleton()->instance_geometry_set_shader_uniform(get_instance(), p_uniform, p_value); } } } -Variant GeometryInstance3D::get_shader_instance_uniform(const StringName &p_uniform) const { - return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_uniform); +Variant GeometryInstance3D::get_instance_shader_uniform(const StringName &p_uniform) const { + return RS::get_singleton()->instance_geometry_get_shader_uniform(get_instance(), p_uniform); } void GeometryInstance3D::set_custom_aabb(AABB aabb) { @@ -434,8 +434,8 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_visibility_range_fade_mode", "mode"), &GeometryInstance3D::set_visibility_range_fade_mode); ClassDB::bind_method(D_METHOD("get_visibility_range_fade_mode"), &GeometryInstance3D::get_visibility_range_fade_mode); - ClassDB::bind_method(D_METHOD("set_shader_instance_uniform", "uniform", "value"), &GeometryInstance3D::set_shader_instance_uniform); - ClassDB::bind_method(D_METHOD("get_shader_instance_uniform", "uniform"), &GeometryInstance3D::get_shader_instance_uniform); + ClassDB::bind_method(D_METHOD("set_instance_shader_uniform", "uniform", "value"), &GeometryInstance3D::set_instance_shader_uniform); + ClassDB::bind_method(D_METHOD("get_instance_shader_uniform", "uniform"), &GeometryInstance3D::get_instance_shader_uniform); ClassDB::bind_method(D_METHOD("set_extra_cull_margin", "margin"), &GeometryInstance3D::set_extra_cull_margin); ClassDB::bind_method(D_METHOD("get_extra_cull_margin"), &GeometryInstance3D::get_extra_cull_margin); @@ -461,15 +461,16 @@ void GeometryInstance3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01,suffix:m"), "set_extra_cull_margin", "get_extra_cull_margin"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_bias", PROPERTY_HINT_RANGE, "0.001,128,0.001"), "set_lod_bias", "get_lod_bias"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_occlusion_culling"), "set_ignore_occlusion_culling", "is_ignoring_occlusion_culling"); + ADD_GROUP("Global Illumination", "gi_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode", PROPERTY_HINT_ENUM, "Disabled,Static (VoxelGI/SDFGI/LightmapGI),Dynamic (VoxelGI only)"), "set_gi_mode", "get_gi_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, String::utf8("1×,2×,4×,8×")), "set_lightmap_scale", "get_lightmap_scale"); ADD_GROUP("Visibility Range", "visibility_range_"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,suffix:m"), "set_visibility_range_begin", "get_visibility_range_begin"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,suffix:m"), "set_visibility_range_begin_margin", "get_visibility_range_begin_margin"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,suffix:m"), "set_visibility_range_end", "get_visibility_range_end"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,suffix:m"), "set_visibility_range_end_margin", "get_visibility_range_end_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_visibility_range_begin", "get_visibility_range_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_visibility_range_begin_margin", "get_visibility_range_begin_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_visibility_range_end", "get_visibility_range_end"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_visibility_range_end_margin", "get_visibility_range_end_margin"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_range_fade_mode", PROPERTY_HINT_ENUM, "Disabled,Self,Dependencies"), "set_visibility_range_fade_mode", "get_visibility_range_fade_mode"); BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_OFF); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index 159b14613c..f7cdcbf411 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -178,8 +178,8 @@ public: void set_lightmap_scale(LightmapScale p_scale); LightmapScale get_lightmap_scale() const; - void set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value); - Variant get_shader_instance_uniform(const StringName &p_uniform) const; + void set_instance_shader_uniform(const StringName &p_uniform, const Variant &p_value); + Variant get_instance_shader_uniform(const StringName &p_uniform) const; void set_custom_aabb(AABB aabb); diff --git a/scene/3d/voxel_gi.h b/scene/3d/voxel_gi.h index e1a38dd7a0..6d173dea87 100644 --- a/scene/3d/voxel_gi.h +++ b/scene/3d/voxel_gi.h @@ -49,9 +49,9 @@ class VoxelGIData : public Resource { float energy = 1.0; float bias = 1.5; float normal_bias = 0.0; - float propagation = 0.7; + float propagation = 0.5; bool interior = false; - bool use_two_bounces = false; + bool use_two_bounces = true; protected: static void _bind_methods(); diff --git a/scene/SCsub b/scene/SCsub index a7b23af598..92288211bb 100644 --- a/scene/SCsub +++ b/scene/SCsub @@ -9,7 +9,6 @@ env.add_source_files(env.scene_sources, "*.cpp") # Chain load SCsubs SConscript("main/SCsub") -SConscript("multiplayer/SCsub") SConscript("gui/SCsub") if not env["disable_3d"]: SConscript("3d/SCsub") diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index d9a5adc883..b42e426f51 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -121,7 +121,7 @@ void AnimationNodeBlendSpace1D::add_blend_point(const Ref<AnimationRootNode> &p_ blend_points[p_at_index].node = p_node; blend_points[p_at_index].position = p_position; - blend_points[p_at_index].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); + blend_points[p_at_index].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed), CONNECT_REFERENCE_COUNTED); blend_points_used++; emit_signal(SNAME("tree_changed")); @@ -142,7 +142,7 @@ void AnimationNodeBlendSpace1D::set_blend_point_node(int p_point, const Ref<Anim } blend_points[p_point].node = p_node; - blend_points[p_point].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); + blend_points[p_point].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed), CONNECT_REFERENCE_COUNTED); emit_signal(SNAME("tree_changed")); } diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index 0f77befd9d..6b5851a977 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -80,7 +80,7 @@ void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_ blend_points[p_at_index].node = p_node; blend_points[p_at_index].position = p_position; - blend_points[p_at_index].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); + blend_points[p_at_index].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed), CONNECT_REFERENCE_COUNTED); blend_points_used++; _queue_auto_triangles(); @@ -102,7 +102,7 @@ void AnimationNodeBlendSpace2D::set_blend_point_node(int p_point, const Ref<Anim blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed)); } blend_points[p_point].node = p_node; - blend_points[p_point].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); + blend_points[p_point].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed), CONNECT_REFERENCE_COUNTED); emit_signal(SNAME("tree_changed")); } diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index d0aac931c0..fe2fb1b7a1 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -844,8 +844,8 @@ void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNod emit_changed(); emit_signal(SNAME("tree_changed")); - p_node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendTree::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); - p_node->connect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed), varray(p_name), CONNECT_REFERENCE_COUNTED); + p_node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendTree::_tree_changed), CONNECT_REFERENCE_COUNTED); + p_node->connect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed).bind(p_name), CONNECT_REFERENCE_COUNTED); } Ref<AnimationNode> AnimationNodeBlendTree::get_node(const StringName &p_name) const { @@ -945,7 +945,7 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN } } //connection must be done with new name - nodes[p_new_name].node->connect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed), varray(p_new_name), CONNECT_REFERENCE_COUNTED); + nodes[p_new_name].node->connect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed).bind(p_new_name), CONNECT_REFERENCE_COUNTED); emit_signal(SNAME("tree_changed")); } diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index fbe23bedad..793967d9ad 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -723,7 +723,7 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation emit_changed(); emit_signal(SNAME("tree_changed")); - p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); + p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), CONNECT_REFERENCE_COUNTED); } void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<AnimationNode> p_node) { @@ -743,7 +743,7 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima emit_changed(); emit_signal(SNAME("tree_changed")); - p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); + p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), CONNECT_REFERENCE_COUNTED); } bool AnimationNodeStateMachine::can_edit_node(const StringName &p_name) const { @@ -830,20 +830,12 @@ void AnimationNodeStateMachine::rename_node(const StringName &p_name, const Stri anodesm->state_machine_name = p_new_name; } - for (int i = 0; i < transitions.size(); i++) { - if (transitions[i].local_from == p_name) { - _rename_transition(transitions[i].from, String(transitions[i].from).replace_first(p_name, p_new_name)); - } - - if (transitions[i].local_to == p_name) { - _rename_transition(transitions[i].to, String(transitions[i].to).replace_first(p_name, p_new_name)); - } - } + _rename_transitions(p_name, p_new_name); emit_signal("tree_changed"); } -void AnimationNodeStateMachine::_rename_transition(const StringName &p_name, const StringName &p_new_name) { +void AnimationNodeStateMachine::_rename_transitions(const StringName &p_name, const StringName &p_new_name) { if (updating_transitions) { return; } @@ -854,12 +846,16 @@ void AnimationNodeStateMachine::_rename_transition(const StringName &p_name, con Vector<String> path = String(transitions[i].to).split("/"); if (path.size() > 1) { if (path[0] == "..") { - prev_state_machine->_rename_transition(String(state_machine_name) + "/" + p_name, String(state_machine_name) + "/" + p_new_name); + prev_state_machine->_rename_transitions(String(state_machine_name) + "/" + p_name, String(state_machine_name) + "/" + p_new_name); } else { - ((Ref<AnimationNodeStateMachine>)states[transitions[i].local_to].node)->_rename_transition("../" + p_name, "../" + p_new_name); + ((Ref<AnimationNodeStateMachine>)states[transitions[i].local_to].node)->_rename_transitions("../" + p_name, "../" + p_new_name); } } + if (transitions[i].local_from == p_name) { + transitions.write[i].local_from = p_new_name; + } + transitions.write[i].from = p_new_name; } @@ -867,12 +863,16 @@ void AnimationNodeStateMachine::_rename_transition(const StringName &p_name, con Vector<String> path = String(transitions[i].from).split("/"); if (path.size() > 1) { if (path[0] == "..") { - prev_state_machine->_rename_transition(String(state_machine_name) + "/" + p_name, String(state_machine_name) + "/" + p_new_name); + prev_state_machine->_rename_transitions(String(state_machine_name) + "/" + p_name, String(state_machine_name) + "/" + p_new_name); } else { - ((Ref<AnimationNodeStateMachine>)states[transitions[i].local_from].node)->_rename_transition("../" + p_name, "../" + p_new_name); + ((Ref<AnimationNodeStateMachine>)states[transitions[i].local_from].node)->_rename_transitions("../" + p_name, "../" + p_new_name); } } + if (transitions[i].local_to == p_name) { + transitions.write[i].local_to = p_new_name; + } + transitions.write[i].to = p_new_name; } @@ -1032,7 +1032,7 @@ void AnimationNodeStateMachine::add_transition(const StringName &p_from, const S tr.local_to = local_to; tr.transition = p_transition; - tr.transition->connect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); + tr.transition->connect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), CONNECT_REFERENCE_COUNTED); transitions.push_back(tr); diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index d4e58ca3d3..ead914db7a 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -185,7 +185,7 @@ private: void _tree_changed(); void _remove_transition(const Ref<AnimationNodeStateMachineTransition> p_transition); - void _rename_transition(const StringName &p_name, const StringName &p_new_name); + void _rename_transitions(const StringName &p_name, const StringName &p_new_name); bool _can_connect(const StringName &p_name, Vector<AnimationNodeStateMachine *> p_parents = Vector<AnimationNodeStateMachine *>()); StringName _get_shortest_path(const StringName &p_path) const; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index df6ef16b4f..636c9e26a5 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -325,7 +325,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov { if (!child->is_connected("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed))) { - child->connect("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed), make_binds(child), CONNECT_ONESHOT); + child->connect("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed).bind(child), CONNECT_ONESHOT); } } @@ -454,6 +454,23 @@ static void _call_object(Object *p_object, const StringName &p_method, const Vec } } +Variant AnimationPlayer::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) { + switch (p_anim->track_get_type(p_track)) { +#ifndef _3D_DISABLED + case Animation::TYPE_POSITION_3D: { + if (p_object_idx >= 0) { + const Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_object); + return Vector3(p_value) * skel->get_motion_scale(); + } + return p_value; + } break; +#endif // _3D_DISABLED + default: { + } break; + } + return p_value; +} + void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double p_time, double p_delta, float p_interp, bool p_is_current, bool p_seeked, bool p_started, int p_pingponged) { _ensure_node_caches(p_anim); ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count()); @@ -498,6 +515,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + loc = _post_process_key_value(a, i, loc, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -525,6 +543,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + rot = _post_process_key_value(a, i, rot, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -552,6 +571,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + scale = _post_process_key_value(a, i, scale, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -579,6 +599,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + blend = _post_process_key_value(a, i, blend, nc->node_blend_shape, nc->blend_shape_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -631,9 +652,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (p_time < first_key_time) { double c = Math::ease(p_time / first_key_time, transition); Variant first_value = a->track_get_key_value(i, first_key); + first_value = _post_process_key_value(a, i, first_value, nc->node); Variant interp_value; Variant::interpolate(pa->capture, first_value, c, interp_value); - if (pa->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX); cache_update_prop[cache_update_prop_size++] = pa; @@ -653,6 +674,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (value == Variant()) { continue; } + value = _post_process_key_value(a, i, value, nc->node); if (pa->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX); @@ -669,6 +691,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double for (int &F : indices) { Variant value = a->track_get_key_value(i, F); + value = _post_process_key_value(a, i, value, nc->node); switch (pa->special) { case SP_NONE: { bool valid; @@ -753,6 +776,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double TrackNodeCache::BezierAnim *ba = &E->value; real_t bezier = a->bezier_track_interpolate(i, p_time); + bezier = _post_process_key_value(a, i, bezier, nc->node); if (ba->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_bezier_size >= NODE_CACHE_UPDATE_MAX); cache_update_bezier[cache_update_bezier_size++] = ba; @@ -1177,11 +1201,15 @@ void AnimationPlayer::_animation_process(double p_delta) { emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name); } } else { - //stop(); playing = false; _set_process(false); if (end_notify) { emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned); + + if (movie_quit_on_finish && OS::get_singleton()->has_feature("movie")) { + print_line(vformat("Movie Maker mode is enabled. Quitting on animation finish as requested by: %s", get_path())); + get_tree()->quit(); + } } } end_reached = false; @@ -1349,9 +1377,9 @@ Error AnimationPlayer::add_animation_library(const StringName &p_name, const Ref animation_libraries.insert(insert_pos, ald); - ald.library->connect(SNAME("animation_added"), callable_mp(this, &AnimationPlayer::_animation_added), varray(p_name)); - ald.library->connect(SNAME("animation_removed"), callable_mp(this, &AnimationPlayer::_animation_added), varray(p_name)); - ald.library->connect(SNAME("animation_renamed"), callable_mp(this, &AnimationPlayer::_animation_renamed), varray(p_name)); + ald.library->connect(SNAME("animation_added"), callable_mp(this, &AnimationPlayer::_animation_added).bind(p_name)); + ald.library->connect(SNAME("animation_removed"), callable_mp(this, &AnimationPlayer::_animation_added).bind(p_name)); + ald.library->connect(SNAME("animation_renamed"), callable_mp(this, &AnimationPlayer::_animation_renamed).bind(p_name)); _animation_set_cache_update(); @@ -1389,7 +1417,7 @@ void AnimationPlayer::remove_animation_library(const StringName &p_name) { } void AnimationPlayer::_ref_anim(const Ref<Animation> &p_anim) { - Ref<Animation>(p_anim)->connect(SceneStringNames::get_singleton()->tracks_changed, callable_mp(this, &AnimationPlayer::_animation_changed), varray(), CONNECT_REFERENCE_COUNTED); + Ref<Animation>(p_anim)->connect(SceneStringNames::get_singleton()->tracks_changed, callable_mp(this, &AnimationPlayer::_animation_changed), CONNECT_REFERENCE_COUNTED); } void AnimationPlayer::_unref_anim(const Ref<Animation> &p_anim) { @@ -1415,9 +1443,9 @@ void AnimationPlayer::rename_animation_library(const StringName &p_name, const S animation_libraries[i].library->disconnect(SNAME("animation_removed"), callable_mp(this, &AnimationPlayer::_animation_added)); animation_libraries[i].library->disconnect(SNAME("animation_renamed"), callable_mp(this, &AnimationPlayer::_animation_renamed)); - animation_libraries[i].library->connect(SNAME("animation_added"), callable_mp(this, &AnimationPlayer::_animation_added), varray(p_new_name)); - animation_libraries[i].library->connect(SNAME("animation_removed"), callable_mp(this, &AnimationPlayer::_animation_added), varray(p_new_name)); - animation_libraries[i].library->connect(SNAME("animation_renamed"), callable_mp(this, &AnimationPlayer::_animation_renamed), varray(p_new_name)); + animation_libraries[i].library->connect(SNAME("animation_added"), callable_mp(this, &AnimationPlayer::_animation_added).bind(p_new_name)); + animation_libraries[i].library->connect(SNAME("animation_removed"), callable_mp(this, &AnimationPlayer::_animation_added).bind(p_new_name)); + animation_libraries[i].library->connect(SNAME("animation_renamed"), callable_mp(this, &AnimationPlayer::_animation_renamed).bind(p_new_name)); for (const KeyValue<StringName, Ref<Animation>> &K : animation_libraries[i].library->animations) { StringName old_name = p_name == StringName() ? K.key : StringName(String(p_name) + "/" + String(K.key)); @@ -1868,6 +1896,14 @@ AnimationPlayer::AnimationMethodCallMode AnimationPlayer::get_method_call_mode() return method_call_mode; } +void AnimationPlayer::set_movie_quit_on_finish_enabled(bool p_enabled) { + movie_quit_on_finish = p_enabled; +} + +bool AnimationPlayer::is_movie_quit_on_finish_enabled() const { + return movie_quit_on_finish; +} + void AnimationPlayer::_set_process(bool p_process, bool p_force) { if (processing == p_process && !p_force) { return; @@ -2088,6 +2124,9 @@ void AnimationPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_method_call_mode", "mode"), &AnimationPlayer::set_method_call_mode); ClassDB::bind_method(D_METHOD("get_method_call_mode"), &AnimationPlayer::get_method_call_mode); + ClassDB::bind_method(D_METHOD("set_movie_quit_on_finish_enabled"), &AnimationPlayer::set_movie_quit_on_finish_enabled); + ClassDB::bind_method(D_METHOD("is_movie_quit_on_finish_enabled"), &AnimationPlayer::is_movie_quit_on_finish_enabled); + ClassDB::bind_method(D_METHOD("get_current_animation_position"), &AnimationPlayer::get_current_animation_position); ClassDB::bind_method(D_METHOD("get_current_animation_length"), &AnimationPlayer::get_current_animation_length); @@ -2109,6 +2148,8 @@ void AnimationPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "method_call_mode", PROPERTY_HINT_ENUM, "Deferred,Immediate"), "set_method_call_mode", "get_method_call_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "movie_quit_on_finish"), "set_movie_quit_on_finish_enabled", "is_movie_quit_on_finish_enabled"); + ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING_NAME, "anim_name"))); ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING_NAME, "old_name"), PropertyInfo(Variant::STRING_NAME, "new_name"))); ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING_NAME, "anim_name"))); diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 0d3ce5977e..b6d8dab1ed 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -262,6 +262,7 @@ private: bool reset_on_save = true; AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE; AnimationMethodCallMode method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; + bool movie_quit_on_finish = false; bool processing = false; bool active = true; @@ -316,6 +317,8 @@ protected: static void _bind_methods(); + virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1); + public: StringName find_animation(const Ref<Animation> &p_animation) const; StringName find_animation_library(const Ref<Animation> &p_animation) const; @@ -371,6 +374,9 @@ public: void set_method_call_mode(AnimationMethodCallMode p_mode); AnimationMethodCallMode get_method_call_mode() const; + void set_movie_quit_on_finish_enabled(bool p_enabled); + bool is_movie_quit_on_finish_enabled() const; + void seek(double p_time, bool p_update = false); void seek_delta(double p_time, float p_delta); float get_current_animation_position() const; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 4b80f571ae..14cf64afad 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -589,7 +589,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { } if (!child->is_connected("tree_exited", callable_mp(this, &AnimationTree::_node_removed))) { - child->connect("tree_exited", callable_mp(this, &AnimationTree::_node_removed), varray(child)); + child->connect("tree_exited", callable_mp(this, &AnimationTree::_node_removed).bind(child)); } switch (track_type) { @@ -1054,7 +1054,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, (double)a->get_length(), &loc[1]); + loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = 0; } @@ -1064,7 +1066,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, 0, &loc[1]); + loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = (double)a->get_length(); } @@ -1074,8 +1078,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, time, &loc[1]); + loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = !backward ? 0 : (double)a->get_length(); @@ -1092,6 +1098,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc = _post_process_key_value(a, i, loc, t->object, t->bone_idx); t->loc += (loc - t->init_loc) * blend; } @@ -1150,7 +1157,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, (double)a->get_length(), &rot[1]); + rot[1] = _post_process_key_value(a, i, rot[1], t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = 0; } @@ -1160,6 +1169,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, 0, &rot[1]); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = (double)a->get_length(); @@ -1170,8 +1180,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, time, &rot[1]); + rot[1] = _post_process_key_value(a, i, rot[1], t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = !backward ? 0 : (double)a->get_length(); @@ -1188,6 +1200,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot = _post_process_key_value(a, i, rot, t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(t->init_rot.inverse() * rot, blend)).normalized(); } @@ -1246,8 +1259,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, (double)a->get_length(), &scale[1]); t->scale += (scale[1] - scale[0]) * blend; + scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); prev_time = 0; } } else { @@ -1256,7 +1271,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, 0, &scale[1]); + scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); t->scale += (scale[1] - scale[0]) * blend; prev_time = (double)a->get_length(); } @@ -1266,8 +1283,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, time, &scale[1]); + scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); t->scale += (scale[1] - scale[0]) * blend; prev_time = !backward ? 0 : (double)a->get_length(); @@ -1284,6 +1303,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale = _post_process_key_value(a, i, scale, t->object, t->bone_idx); t->scale += (scale - t->init_scale) * blend; } @@ -1306,6 +1326,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + value = _post_process_key_value(a, i, value, t->object, t->shape_index); t->value += (value - t->init_value) * blend; #endif // _3D_DISABLED @@ -1317,6 +1338,7 @@ void AnimationTree::_process_graph(double p_delta) { if (update_mode == Animation::UPDATE_CONTINUOUS || update_mode == Animation::UPDATE_CAPTURE) { Variant value = a->value_track_interpolate(i, time); + value = _post_process_key_value(a, i, value, t->object); if (value == Variant()) { continue; @@ -1344,12 +1366,14 @@ void AnimationTree::_process_graph(double p_delta) { continue; } Variant value = a->track_get_key_value(i, idx); + value = _post_process_key_value(a, i, value, t->object); t->object->set_indexed(t->subpath, value); } else { List<int> indices; a->value_track_get_key_indices(i, time, delta, &indices, pingponged); for (int &F : indices) { Variant value = a->track_get_key_value(i, F); + value = _post_process_key_value(a, i, value, t->object); t->object->set_indexed(t->subpath, value); } } @@ -1388,6 +1412,7 @@ void AnimationTree::_process_graph(double p_delta) { TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track); real_t bezier = a->bezier_track_interpolate(i, time); + bezier = _post_process_key_value(a, i, bezier, t->object); if (t->process_pass != process_pass) { t->process_pass = process_pass; @@ -1663,6 +1688,23 @@ void AnimationTree::_process_graph(double p_delta) { } } +Variant AnimationTree::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) { + switch (p_anim->track_get_type(p_track)) { +#ifndef _3D_DISABLED + case Animation::TYPE_POSITION_3D: { + if (p_object_idx >= 0) { + const Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_object); + return Vector3(p_value) * skel->get_motion_scale(); + } + return p_value; + } break; +#endif // _3D_DISABLED + default: { + } break; + } + return p_value; +} + void AnimationTree::advance(real_t p_time) { _process_graph(p_time); } diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index d82fed9dc2..99851d140e 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -321,6 +321,8 @@ protected: void _notification(int p_what); static void _bind_methods(); + virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1); + public: void set_tree_root(const Ref<AnimationNode> &p_root); Ref<AnimationNode> get_tree_root() const; diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 72f7589224..dbc71cd9e7 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -864,7 +864,7 @@ bool CallbackTweener::step(float &r_delta) { if (elapsed_time >= delay) { Variant result; Callable::CallError ce; - callback.call(nullptr, 0, result, ce); + callback.callp(nullptr, 0, result, ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(false, "Error calling method from CallbackTweener: " + Variant::get_callable_error_text(callback, nullptr, 0, ce)); } @@ -935,7 +935,7 @@ bool MethodTweener::step(float &r_delta) { Variant result; Callable::CallError ce; - callback.call(argptr, 1, result, ce); + callback.callp(argptr, 1, result, ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(false, "Error calling method from MethodTweener: " + Variant::get_callable_error_text(callback, argptr, 1, ce)); } diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index e9c33b1839..4c5a63e52c 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -299,7 +299,7 @@ void SceneDebugger::_save_node(ObjectID id, const String &p_path) { Ref<PackedScene> ps = memnew(PackedScene); ps->pack(node); - ResourceSaver::save(p_path, ps); + ResourceSaver::save(ps, p_path); } void SceneDebugger::_send_object_id(ObjectID p_id, int p_max_size) { diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index a67f850a86..0a163b65ff 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -34,39 +34,14 @@ #include "servers/rendering_server.h" Size2 Button::get_minimum_size() const { - Size2 minsize = text_buf->get_size(); - if (clip_text || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) { - minsize.width = 0; - } - - if (!expand_icon) { - Ref<Texture2D> _icon; - if (icon.is_null() && has_theme_icon(SNAME("icon"))) { - _icon = Control::get_theme_icon(SNAME("icon")); - } else { - _icon = icon; - } - - if (!_icon.is_null()) { - minsize.height = MAX(minsize.height, _icon->get_height()); - - if (icon_alignment != HORIZONTAL_ALIGNMENT_CENTER) { - minsize.width += _icon->get_width(); - if (!xl_text.is_empty()) { - minsize.width += get_theme_constant(SNAME("h_separation")); - } - } else { - minsize.width = MAX(minsize.width, _icon->get_width()); - } - } - } - if (!xl_text.is_empty()) { - Ref<Font> font = get_theme_font(SNAME("font")); - float font_height = font->get_height(get_theme_font_size(SNAME("font_size"))); - minsize.height = MAX(font_height, minsize.height); + Ref<Texture2D> _icon; + if (icon.is_null() && has_theme_icon(SNAME("icon"))) { + _icon = Control::get_theme_icon(SNAME("icon")); + } else { + _icon = icon; } - return get_theme_stylebox(SNAME("normal"))->get_minimum_size() + minsize; + return get_minimum_size_for_text_and_icon("", _icon); } void Button::_set_internal_margin(Side p_side, float p_value) { @@ -283,7 +258,8 @@ void Button::_notification(int p_what) { } if (icon_region.size.width > 0) { - draw_texture_rect_region(_icon, icon_region, Rect2(Point2(), _icon->get_size()), color_icon); + Rect2 icon_region_rounded = Rect2(icon_region.position.round(), icon_region.size.round()); + draw_texture_rect(_icon, icon_region_rounded, false, color_icon); } } @@ -352,18 +328,62 @@ void Button::_notification(int p_what) { } } -void Button::_shape() { +Size2 Button::get_minimum_size_for_text_and_icon(const String &p_text, Ref<Texture2D> p_icon) const { + Ref<TextParagraph> paragraph; + if (p_text.is_empty()) { + paragraph = text_buf; + } else { + paragraph.instantiate(); + const_cast<Button *>(this)->_shape(paragraph, p_text); + } + + Size2 minsize = paragraph->get_size(); + if (clip_text || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) { + minsize.width = 0; + } + + if (!expand_icon && !p_icon.is_null()) { + minsize.height = MAX(minsize.height, p_icon->get_height()); + + if (icon_alignment != HORIZONTAL_ALIGNMENT_CENTER) { + minsize.width += p_icon->get_width(); + if (!xl_text.is_empty() || !p_text.is_empty()) { + minsize.width += get_theme_constant(SNAME("hseparation")); + } + } else { + minsize.width = MAX(minsize.width, p_icon->get_width()); + } + } + + if (!xl_text.is_empty() || !p_text.is_empty()) { + Ref<Font> font = get_theme_font(SNAME("font")); + float font_height = font->get_height(get_theme_font_size(SNAME("font_size"))); + minsize.height = MAX(font_height, minsize.height); + } + + return get_theme_stylebox(SNAME("normal"))->get_minimum_size() + minsize; +} + +void Button::_shape(Ref<TextParagraph> p_paragraph, String p_text) { + if (p_paragraph.is_null()) { + p_paragraph = text_buf; + } + + if (p_text.is_empty()) { + p_text = xl_text; + } + Ref<Font> font = get_theme_font(SNAME("font")); int font_size = get_theme_font_size(SNAME("font_size")); - text_buf->clear(); + p_paragraph->clear(); if (text_direction == Control::TEXT_DIRECTION_INHERITED) { - text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); + p_paragraph->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); } else { - text_buf->set_direction((TextServer::Direction)text_direction); + p_paragraph->set_direction((TextServer::Direction)text_direction); } - text_buf->add_string(xl_text, font, font_size, language); - text_buf->set_text_overrun_behavior(overrun_behavior); + p_paragraph->add_string(p_text, font, font_size, language); + p_paragraph->set_text_overrun_behavior(overrun_behavior); } void Button::set_text_overrun_behavior(TextServer::OverrunBehavior p_behavior) { diff --git a/scene/gui/button.h b/scene/gui/button.h index 9d8d457f7c..23b5c78166 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -54,7 +54,7 @@ private: HorizontalAlignment icon_alignment = HORIZONTAL_ALIGNMENT_LEFT; float _internal_margin[4] = {}; - void _shape(); + void _shape(Ref<TextParagraph> p_paragraph = Ref<TextParagraph>(), String p_text = ""); protected: void _set_internal_margin(Side p_side, float p_value); @@ -64,6 +64,8 @@ protected: public: virtual Size2 get_minimum_size() const override; + Size2 get_minimum_size_for_text_and_icon(const String &p_text, Ref<Texture2D> p_icon) const; + void set_text(const String &p_text); String get_text() const; diff --git a/scene/gui/color_mode.cpp b/scene/gui/color_mode.cpp index af78d67e5a..ebd86e0937 100644 --- a/scene/gui/color_mode.cpp +++ b/scene/gui/color_mode.cpp @@ -159,7 +159,7 @@ void ColorModeHSV::slider_draw(int p_which) { } else if (p_which == 0) { Ref<Texture2D> hue = color_picker->get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker")); slider->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0)); - slider->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(slider->get_size().x, margin)), false, Color(1, 1, 1), true); + slider->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(margin, size.x)), false); return; } else { Color s_col; @@ -306,7 +306,7 @@ void ColorModeOKHSL::slider_draw(int p_which) { } else if (p_which == 0) { Ref<Texture2D> hue = color_picker->get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker")); slider->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0)); - slider->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(slider->get_size().x, margin)), false, Color(1, 1, 1), true); + slider->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(margin, size.x)), false); return; } else { Color s_col; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index bfe5ee335b..8cbe14c492 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -171,6 +171,9 @@ uniform float v = 1.0; void fragment() { float x = UV.x - 0.5; float y = UV.y - 0.5; + float h = atan(y, x) / (2.0 * M_PI); + float s = sqrt(x * x + y * y) * 2.0; + vec3 col = okhsl_to_srgb(vec3(h, s, v)); x += 0.001; y += 0.001; float b = float(sqrt(x * x + y * y) < 0.5); @@ -180,9 +183,6 @@ void fragment() { float b3 = float(sqrt(x * x + y * y) < 0.5); x += 0.002; float b4 = float(sqrt(x * x + y * y) < 0.5); - float s = sqrt(x * x + y * y); - float h = atan(y, x) / (2.0*M_PI); - vec3 col = okhsl_to_srgb(vec3(h, s, v)); COLOR = vec4(col, (b + b2 + b3 + b4) / 4.00); })"); } @@ -264,15 +264,7 @@ void ColorPicker::_update_controls() { void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) { color = p_color; if (color != last_color) { - if (_get_actual_shape() == SHAPE_OKHSL_CIRCLE) { - h = color.get_ok_hsl_h(); - s = color.get_ok_hsl_s(); - v = color.get_ok_hsl_l(); - } else { - h = color.get_h(); - s = color.get_s(); - v = color.get_v(); - } + _copy_color_to_hsv(); last_color = color; } @@ -357,7 +349,7 @@ void ColorPicker::create_slider(GridContainer *gc, int idx) { s->set_h_size_flags(SIZE_EXPAND_FILL); s->connect("value_changed", callable_mp(this, &ColorPicker::_value_changed)); - s->connect("draw", callable_mp(this, &ColorPicker::_slider_draw), make_binds(idx)); + s->connect("draw", callable_mp(this, &ColorPicker::_slider_draw).bind(idx)); if (idx < SLIDER_COUNT) { sliders[idx] = s; @@ -386,6 +378,26 @@ Vector<float> ColorPicker::get_active_slider_values() { return values; } +void ColorPicker::_copy_color_to_hsv() { + if (_get_actual_shape() == SHAPE_OKHSL_CIRCLE) { + h = color.get_ok_hsl_h(); + s = color.get_ok_hsl_s(); + v = color.get_ok_hsl_l(); + } else { + h = color.get_h(); + s = color.get_s(); + v = color.get_v(); + } +} + +void ColorPicker::_copy_hsv_to_color() { + if (_get_actual_shape() == SHAPE_OKHSL_CIRCLE) { + color.set_ok_hsl(h, s, v, color.a); + } else { + color.set_hsv(h, s, v, color.a); + } +} + ColorPicker::PickerShapeType ColorPicker::_get_actual_shape() const { return modes[current_mode]->get_shape_override() != SHAPE_MAX ? modes[current_mode]->get_shape_override() : current_shape; } @@ -499,6 +511,8 @@ void ColorPicker::set_picker_shape(PickerShapeType p_shape) { ERR_FAIL_INDEX(p_shape, SHAPE_MAX); current_shape = p_shape; + _copy_color_to_hsv(); + _update_controls(); _update_color(); } @@ -515,7 +529,7 @@ void ColorPicker::_add_preset_button(int p_size, const Color &p_color) { ColorPresetButton *btn_preset = memnew(ColorPresetButton(p_color)); btn_preset->set_preset_color(p_color); btn_preset->set_custom_minimum_size(Size2(p_size, p_size)); - btn_preset->connect("gui_input", callable_mp(this, &ColorPicker::_preset_input), varray(p_color)); + btn_preset->connect("gui_input", callable_mp(this, &ColorPicker::_preset_input).bind(p_color)); btn_preset->set_tooltip(vformat(RTR("Color: #%s\nLMB: Apply color\nRMB: Remove preset"), p_color.to_html(p_color.a < 1))); preset_container->add_child(btn_preset); } @@ -640,8 +654,7 @@ void ColorPicker::_sample_input(const Ref<InputEvent> &p_event) { const Rect2 rect_old = Rect2(Point2(), Size2(sample->get_size().width * 0.5, sample->get_size().height * 0.95)); if (rect_old.has_point(mb->get_position())) { // Revert to the old color when left-clicking the old color sample. - color = old_color; - _update_color(); + set_pick_color(old_color); emit_signal(SNAME("color_changed"), color); } } @@ -834,7 +847,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) { } else if (p_which == 2) { c->draw_rect(Rect2(Point2(), c->get_size()), Color(1, 1, 1)); if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) { - circle_mat->set_shader_param("v", v); + circle_mat->set_shader_uniform("v", v); } } } @@ -887,17 +900,14 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) { v = 1.0 - (y - c->get_position().y - corner_y) / real_size.y; } } + changing_color = true; - if (current_picker == SHAPE_OKHSL_CIRCLE) { - color.set_ok_hsl(h, s, v, color.a); - } else { - color.set_hsv(h, s, v, color.a); - } + _copy_hsv_to_color(); last_color = color; - set_pick_color(color); _update_color(); + if (!deferred_mode_enabled) { emit_signal(SNAME("color_changed"), color); } @@ -940,14 +950,12 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) { v = 1.0 - (y - corner_y) / real_size.y; } } - if (current_picker != SHAPE_OKHSL_CIRCLE) { - color.set_hsv(h, s, v, color.a); - } else { - color.set_ok_hsl(h, s, v, color.a); - } + + _copy_hsv_to_color(); last_color = color; set_pick_color(color); _update_color(); + if (!deferred_mode_enabled) { emit_signal(SNAME("color_changed"), color); } @@ -970,14 +978,12 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) { } else { changing_color = false; } - if (actual_shape != SHAPE_OKHSL_CIRCLE) { - color.set_hsv(h, s, v, color.a); - } else { - color.set_ok_hsl(h, s, v, color.a); - } + + _copy_hsv_to_color(); last_color = color; set_pick_color(color); _update_color(); + if (!deferred_mode_enabled) { emit_signal(SNAME("color_changed"), color); } else if (!bev->is_pressed() && bev->get_button_index() == MouseButton::LEFT) { @@ -998,15 +1004,11 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) { h = y / w_edit->get_size().height; } - if (current_mode == MODE_HSV) { - color.set_hsv(h, s, v, color.a); - } else if (current_mode == MODE_OKHSL) { - color.set_ok_hsl(h, s, v, color.a); - } - + _copy_hsv_to_color(); last_color = color; set_pick_color(color); _update_color(); + if (!deferred_mode_enabled) { emit_signal(SNAME("color_changed"), color); } @@ -1019,7 +1021,6 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event, const Color &p_c if (bev.is_valid()) { if (bev->is_pressed() && bev->get_button_index() == MouseButton::LEFT) { set_pick_color(p_color); - _update_color(); emit_signal(SNAME("color_changed"), p_color); } else if (bev->is_pressed() && bev->get_button_index() == MouseButton::RIGHT && presets_enabled) { erase_preset(p_color); @@ -1075,7 +1076,7 @@ void ColorPicker::_screen_pick_pressed() { screen->set_default_cursor_shape(CURSOR_POINTING_HAND); screen->connect("gui_input", callable_mp(this, &ColorPicker::_screen_input)); // It immediately toggles off in the first press otherwise. - screen->call_deferred(SNAME("connect"), "hidden", Callable(btn_pick, "set_pressed"), varray(false)); + screen->call_deferred(SNAME("connect"), "hidden", Callable(btn_pick, "set_pressed").bind(false)); } else { screen->show(); } @@ -1204,11 +1205,11 @@ ColorPicker::ColorPicker() : uv_edit = memnew(Control); hb_edit->add_child(uv_edit); - uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input), make_binds(uv_edit)); + uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input).bind(uv_edit)); uv_edit->set_mouse_filter(MOUSE_FILTER_PASS); uv_edit->set_h_size_flags(SIZE_EXPAND_FILL); uv_edit->set_v_size_flags(SIZE_EXPAND_FILL); - uv_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, uv_edit)); + uv_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(0, uv_edit)); HBoxContainer *hb_smpl = memnew(HBoxContainer); add_child(hb_smpl, false, INTERNAL_MODE_FRONT); @@ -1295,19 +1296,19 @@ ColorPicker::ColorPicker() : wheel = memnew(Control); wheel_margin->add_child(wheel); wheel->set_mouse_filter(MOUSE_FILTER_PASS); - wheel->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(2, wheel)); + wheel->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(2, wheel)); wheel_uv = memnew(Control); wheel_margin->add_child(wheel_uv); - wheel_uv->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input), make_binds(wheel_uv)); - wheel_uv->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, wheel_uv)); + wheel_uv->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input).bind(wheel_uv)); + wheel_uv->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(0, wheel_uv)); w_edit = memnew(Control); hb_edit->add_child(w_edit); w_edit->set_h_size_flags(SIZE_FILL); w_edit->set_v_size_flags(SIZE_EXPAND_FILL); w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input)); - w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(1, w_edit)); + w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(1, w_edit)); _update_controls(); updating = false; diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 8e65ee1861..05b760b109 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -156,6 +156,9 @@ private: float v = 0.0; Color last_color; + void _copy_color_to_hsv(); + void _copy_hsv_to_color(); + PickerShapeType _get_actual_shape() const; void create_slider(GridContainer *gc, int idx); void _reset_theme(); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 686045901c..06aa913eb1 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -50,6 +50,9 @@ #include "editor/plugins/control_editor_plugin.h" #endif +// Editor plugin interoperability. + +// TODO: Decouple controls from their editor plugin and get rid of this. #ifdef TOOLS_ENABLED Dictionary Control::_edit_get_state() const { Dictionary s; @@ -181,6 +184,49 @@ Size2 Control::_edit_get_minimum_size() const { } #endif +// Editor integration. + +void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { + Node::get_argument_options(p_function, p_idx, r_options); + + if (p_idx == 0) { + List<StringName> sn; + String pf = p_function; + if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color") { + Theme::get_default()->get_color_list(get_class(), &sn); + } else if (pf == "add_theme_style_override" || pf == "has_theme_style" || pf == "has_theme_style_override" || pf == "get_theme_style") { + Theme::get_default()->get_stylebox_list(get_class(), &sn); + } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font") { + Theme::get_default()->get_font_list(get_class(), &sn); + } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size") { + Theme::get_default()->get_font_size_list(get_class(), &sn); + } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant") { + Theme::get_default()->get_constant_list(get_class(), &sn); + } + + sn.sort_custom<StringName::AlphCompare>(); + for (const StringName &name : sn) { + r_options->push_back(String(name).quote()); + } + } +} + +TypedArray<String> Control::get_configuration_warnings() const { + TypedArray<String> warnings = Node::get_configuration_warnings(); + + if (data.mouse_filter == MOUSE_FILTER_IGNORE && !data.tooltip.is_empty()) { + warnings.push_back(RTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\".")); + } + + return warnings; +} + +bool Control::is_text_field() const { + return false; +} + +// Dynamic properties. + String Control::properties_managed_by_container[] = { "offset_left", "offset_top", @@ -196,58 +242,6 @@ String Control::properties_managed_by_container[] = { "size" }; -void Control::accept_event() { - if (is_inside_tree()) { - get_viewport()->_gui_accept_event(); - } -} - -void Control::set_custom_minimum_size(const Size2 &p_custom) { - if (p_custom == data.custom_minimum_size) { - return; - } - data.custom_minimum_size = p_custom; - update_minimum_size(); -} - -Size2 Control::get_custom_minimum_size() const { - return data.custom_minimum_size; -} - -void Control::_update_minimum_size_cache() { - Size2 minsize = get_minimum_size(); - minsize.x = MAX(minsize.x, data.custom_minimum_size.x); - minsize.y = MAX(minsize.y, data.custom_minimum_size.y); - - bool size_changed = false; - if (data.minimum_size_cache != minsize) { - size_changed = true; - } - - data.minimum_size_cache = minsize; - data.minimum_size_valid = true; - - if (size_changed) { - update_minimum_size(); - } -} - -Size2 Control::get_combined_minimum_size() const { - if (!data.minimum_size_valid) { - const_cast<Control *>(this)->_update_minimum_size_cache(); - } - return data.minimum_size_cache; -} - -Transform2D Control::_get_internal_transform() const { - Transform2D rot_scale; - rot_scale.set_rotation_and_scale(data.rotation, data.scale); - Transform2D offset; - offset.set_origin(-data.pivot_offset); - - return offset.affine_inverse() * (rot_scale * offset); -} - bool Control::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (!name.begins_with("theme_override")) { @@ -258,21 +252,21 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) { if (name.begins_with("theme_override_icons/")) { String dname = name.get_slicec('/', 1); if (data.icon_override.has(dname)) { - data.icon_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); + data.icon_override[dname]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); } data.icon_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("theme_override_styles/")) { String dname = name.get_slicec('/', 1); if (data.style_override.has(dname)) { - data.style_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); + data.style_override[dname]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); } data.style_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("theme_override_fonts/")) { String dname = name.get_slicec('/', 1); if (data.font_override.has(dname)) { - data.font_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); + data.font_override[dname]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); } data.font_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); @@ -318,21 +312,6 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) { return true; } -void Control::_update_minimum_size() { - if (!is_inside_tree()) { - return; - } - - Size2 minsize = get_combined_minimum_size(); - data.updating_last_minimum_size = false; - - if (minsize != data.last_minimum_size) { - data.last_minimum_size = minsize; - _size_changed(); - emit_signal(SceneStringNames::get_singleton()->minimum_size_changed); - } -} - bool Control::_get(const StringName &p_name, Variant &r_ret) const { String sname = p_name; if (!sname.begins_with("theme_override")) { @@ -586,6 +565,12 @@ void Control::_validate_property(PropertyInfo &property) const { } } +// Global relations. + +bool Control::is_top_level_control() const { + return is_inside_tree() && (!data.parent_canvas_item && !data.RI && is_set_as_top_level()); +} + Control *Control::get_parent_control() const { return data.parent; } @@ -594,97 +579,64 @@ Window *Control::get_parent_window() const { return data.parent_window; } -void Control::set_layout_direction(Control::LayoutDirection p_direction) { - ERR_FAIL_INDEX((int)p_direction, 4); - - data.layout_dir = p_direction; - data.is_rtl_dirty = true; - - propagate_notification(NOTIFICATION_LAYOUT_DIRECTION_CHANGED); -} +Control *Control::get_root_parent_control() const { + const CanvasItem *ci = this; + const Control *root = this; -Control::LayoutDirection Control::get_layout_direction() const { - return data.layout_dir; -} + while (ci) { + const Control *c = Object::cast_to<Control>(ci); + if (c) { + root = c; -bool Control::is_layout_rtl() const { - if (data.is_rtl_dirty) { - const_cast<Control *>(this)->data.is_rtl_dirty = false; - if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) { - Window *parent_window = get_parent_window(); - Control *parent_control = get_parent_control(); - if (parent_control) { - const_cast<Control *>(this)->data.is_rtl = parent_control->is_layout_rtl(); - } else if (parent_window) { - const_cast<Control *>(this)->data.is_rtl = parent_window->is_layout_rtl(); - } else { - if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { - const_cast<Control *>(this)->data.is_rtl = true; - } else { - String locale = TranslationServer::get_singleton()->get_tool_locale(); - const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); - } - } - } else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) { - if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { - const_cast<Control *>(this)->data.is_rtl = true; - } else { - String locale = TranslationServer::get_singleton()->get_tool_locale(); - const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); + if (c->data.RI || c->is_top_level_control()) { + break; } - } else { - const_cast<Control *>(this)->data.is_rtl = (data.layout_dir == LAYOUT_DIRECTION_RTL); } - } - return data.is_rtl; -} -void Control::set_auto_translate(bool p_enable) { - if (p_enable == data.auto_translate) { - return; + ci = ci->get_parent_item(); } - data.auto_translate = p_enable; - - notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); -} - -bool Control::is_auto_translating() const { - return data.auto_translate; -} - -void Control::_clear_size_warning() { - data.size_warning = false; + return const_cast<Control *>(root); } -//moved theme configuration here, so controls can set up even if still not inside active scene - -void Control::add_child_notify(Node *p_child) { - Control *child_c = Object::cast_to<Control>(p_child); - - if (child_c && child_c->data.theme.is_null() && (data.theme_owner || data.theme_owner_window)) { - _propagate_theme_changed(child_c, data.theme_owner, data.theme_owner_window); //need to propagate here, since many controls may require setting up stuff +Rect2 Control::get_parent_anchorable_rect() const { + if (!is_inside_tree()) { + return Rect2(); } - Window *child_w = Object::cast_to<Window>(p_child); + Rect2 parent_rect; + if (data.parent_canvas_item) { + parent_rect = data.parent_canvas_item->get_anchorable_rect(); + } else { +#ifdef TOOLS_ENABLED + Node *edited_root = get_tree()->get_edited_scene_root(); + if (edited_root && (this == edited_root || edited_root->is_ancestor_of(this))) { + parent_rect.size = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); + } else { + parent_rect = get_viewport()->get_visible_rect(); + } - if (child_w && child_w->theme.is_null() && (data.theme_owner || data.theme_owner_window)) { - _propagate_theme_changed(child_w, data.theme_owner, data.theme_owner_window); //need to propagate here, since many controls may require setting up stuff +#else + parent_rect = get_viewport()->get_visible_rect(); +#endif } + + return parent_rect; } -void Control::remove_child_notify(Node *p_child) { - Control *child_c = Object::cast_to<Control>(p_child); +Size2 Control::get_parent_area_size() const { + return get_parent_anchorable_rect().size; +} - if (child_c && (child_c->data.theme_owner || child_c->data.theme_owner_window) && child_c->data.theme.is_null()) { - _propagate_theme_changed(child_c, nullptr, nullptr); - } +// Positioning and sizing. - Window *child_w = Object::cast_to<Window>(p_child); +Transform2D Control::_get_internal_transform() const { + Transform2D rot_scale; + rot_scale.set_rotation_and_scale(data.rotation, data.scale); + Transform2D offset; + offset.set_origin(-data.pivot_offset); - if (child_w && (child_w->theme_owner || child_w->theme_owner_window) && child_w->theme.is_null()) { - _propagate_theme_changed(child_w, nullptr, nullptr); - } + return offset.affine_inverse() * (rot_scale * offset); } void Control::_update_canvas_item_transform() { @@ -699,815 +651,146 @@ void Control::_update_canvas_item_transform() { RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), xform); } -void Control::_notification(int p_notification) { - switch (p_notification) { - case NOTIFICATION_POST_ENTER_TREE: { - data.minimum_size_valid = false; - data.is_rtl_dirty = true; - _size_changed(); - } break; - - case NOTIFICATION_EXIT_TREE: { - release_focus(); - get_viewport()->_gui_remove_control(this); - } break; - - case NOTIFICATION_READY: { -#ifdef DEBUG_ENABLED - connect("ready", callable_mp(this, &Control::_clear_size_warning), varray(), CONNECT_DEFERRED | CONNECT_ONESHOT); -#endif - } break; - - case NOTIFICATION_ENTER_CANVAS: { - data.parent = Object::cast_to<Control>(get_parent()); - data.parent_window = Object::cast_to<Window>(get_parent()); - data.is_rtl_dirty = true; - - if (data.theme.is_null()) { - if (data.parent && (data.parent->data.theme_owner || data.parent->data.theme_owner_window)) { - data.theme_owner = data.parent->data.theme_owner; - data.theme_owner_window = data.parent->data.theme_owner_window; - notification(NOTIFICATION_THEME_CHANGED); - } else if (data.parent_window && (data.parent_window->theme_owner || data.parent_window->theme_owner_window)) { - data.theme_owner = data.parent_window->theme_owner; - data.theme_owner_window = data.parent_window->theme_owner_window; - notification(NOTIFICATION_THEME_CHANGED); - } - } - - CanvasItem *node = this; - bool has_parent_control = false; - - while (!node->is_set_as_top_level()) { - CanvasItem *parent = Object::cast_to<CanvasItem>(node->get_parent()); - if (!parent) { - break; - } - - Control *parent_control = Object::cast_to<Control>(parent); - if (parent_control) { - has_parent_control = true; - break; - } - - node = parent; - } - - if (has_parent_control) { - // Do nothing, has a parent control. - } else { - // Is a regular root control or top_level. - Viewport *viewport = get_viewport(); - ERR_FAIL_COND(!viewport); - data.RI = viewport->_gui_add_root_control(this); - } - - data.parent_canvas_item = get_parent_item(); - - if (data.parent_canvas_item) { - data.parent_canvas_item->connect("item_rect_changed", callable_mp(this, &Control::_size_changed)); - } else { - // Connect viewport. - Viewport *viewport = get_viewport(); - ERR_FAIL_COND(!viewport); - viewport->connect("size_changed", callable_mp(this, &Control::_size_changed)); - } - } break; - - case NOTIFICATION_EXIT_CANVAS: { - if (data.parent_canvas_item) { - data.parent_canvas_item->disconnect("item_rect_changed", callable_mp(this, &Control::_size_changed)); - data.parent_canvas_item = nullptr; - } else if (!is_set_as_top_level()) { - //disconnect viewport - Viewport *viewport = get_viewport(); - ERR_FAIL_COND(!viewport); - viewport->disconnect("size_changed", callable_mp(this, &Control::_size_changed)); - } - - if (data.RI) { - get_viewport()->_gui_remove_root_control(data.RI); - data.RI = nullptr; - } - - data.parent = nullptr; - data.parent_canvas_item = nullptr; - data.parent_window = nullptr; - data.is_rtl_dirty = true; - } break; - - case NOTIFICATION_MOVED_IN_PARENT: { - // some parents need to know the order of the children to draw (like TabContainer) - // update if necessary - if (data.parent) { - data.parent->update(); - } - update(); - - if (data.RI) { - get_viewport()->_gui_set_root_order_dirty(); - } - } break; - - case NOTIFICATION_RESIZED: { - emit_signal(SceneStringNames::get_singleton()->resized); - } break; - - case NOTIFICATION_DRAW: { - _update_canvas_item_transform(); - RenderingServer::get_singleton()->canvas_item_set_custom_rect(get_canvas_item(), !data.disable_visibility_clip, Rect2(Point2(), get_size())); - RenderingServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), data.clip_contents); - } break; - - case NOTIFICATION_MOUSE_ENTER: { - emit_signal(SceneStringNames::get_singleton()->mouse_entered); - } break; - - case NOTIFICATION_MOUSE_EXIT: { - emit_signal(SceneStringNames::get_singleton()->mouse_exited); - } break; - - case NOTIFICATION_FOCUS_ENTER: { - emit_signal(SceneStringNames::get_singleton()->focus_entered); - update(); - } break; - - case NOTIFICATION_FOCUS_EXIT: { - emit_signal(SceneStringNames::get_singleton()->focus_exited); - update(); - } break; - - case NOTIFICATION_THEME_CHANGED: { - update_minimum_size(); - update(); - } break; - - case NOTIFICATION_VISIBILITY_CHANGED: { - if (!is_visible_in_tree()) { - if (get_viewport() != nullptr) { - get_viewport()->_gui_hide_control(this); - } - } else { - data.minimum_size_valid = false; - _update_minimum_size(); - _size_changed(); - } - } break; - - case NOTIFICATION_TRANSLATION_CHANGED: - case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { - if (is_inside_tree()) { - data.is_rtl_dirty = true; - _size_changed(); - } - } break; - } -} - -bool Control::has_point(const Point2 &p_point) const { - bool ret; - if (GDVIRTUAL_CALL(_has_point, p_point, ret)) { - return ret; - } - return Rect2(Point2(), get_size()).has_point(p_point); -} - -void Control::set_drag_forwarding(Object *p_target) { - if (p_target) { - data.drag_owner = p_target->get_instance_id(); - } else { - data.drag_owner = ObjectID(); - } -} - -Variant Control::get_drag_data(const Point2 &p_point) { - if (data.drag_owner.is_valid()) { - Object *obj = ObjectDB::get_instance(data.drag_owner); - if (obj) { - return obj->call("_get_drag_data_fw", p_point, this); - } - } - - Variant dd; - if (GDVIRTUAL_CALL(_get_drag_data, p_point, dd)) { - return dd; - } - - return Variant(); -} - -bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const { - if (data.drag_owner.is_valid()) { - Object *obj = ObjectDB::get_instance(data.drag_owner); - if (obj) { - return obj->call("_can_drop_data_fw", p_point, p_data, this); - } - } - - bool ret; - if (GDVIRTUAL_CALL(_can_drop_data, p_point, p_data, ret)) { - return ret; - } - return false; -} - -void Control::drop_data(const Point2 &p_point, const Variant &p_data) { - if (data.drag_owner.is_valid()) { - Object *obj = ObjectDB::get_instance(data.drag_owner); - if (obj) { - obj->call("_drop_data_fw", p_point, p_data, this); - return; - } - } - - GDVIRTUAL_CALL(_drop_data, p_point, p_data); -} - -void Control::force_drag(const Variant &p_data, Control *p_control) { - ERR_FAIL_COND(!is_inside_tree()); - ERR_FAIL_COND(p_data.get_type() == Variant::NIL); - - get_viewport()->_gui_force_drag(this, p_data, p_control); -} - -void Control::set_drag_preview(Control *p_control) { - ERR_FAIL_COND(!is_inside_tree()); - ERR_FAIL_COND(!get_viewport()->gui_is_dragging()); - get_viewport()->_gui_set_drag_preview(this, p_control); -} - -bool Control::is_drag_successful() const { - return is_inside_tree() && get_viewport()->gui_is_drag_successful(); -} - -void Control::_call_gui_input(const Ref<InputEvent> &p_event) { - emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); //signal should be first, so it's possible to override an event (and then accept it) - if (!is_inside_tree() || get_viewport()->is_input_handled()) { - return; //input was handled, abort - } - GDVIRTUAL_CALL(_gui_input, p_event); - if (!is_inside_tree() || get_viewport()->is_input_handled()) { - return; //input was handled, abort - } - gui_input(p_event); -} -void Control::gui_input(const Ref<InputEvent> &p_event) { +Transform2D Control::get_transform() const { + Transform2D xform = _get_internal_transform(); + xform[2] += get_position(); + return xform; } -Size2 Control::get_minimum_size() const { - Vector2 ms; - if (GDVIRTUAL_CALL(_get_minimum_size, ms)) { - return ms; - } - return Vector2(); -} +/// Anchors and offsets. -template <class T> -T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { - ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, T(), "At least one theme type must be specified."); - - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - // For each theme resource check the theme types provided and see if p_name exists with any of them. - for (const StringName &E : p_theme_types) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { - return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E); - } - - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { - return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E); - } - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - for (const StringName &E : p_theme_types) { - if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { - return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E); - } - } - } - - // Lastly, fall back on the items defined in the default Theme, if they exist. - for (const StringName &E : p_theme_types) { - if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { - return Theme::get_default()->get_theme_item(p_data_type, p_name, E); - } - } - // If they don't exist, use any type to return the default/empty value. - return Theme::get_default()->get_theme_item(p_data_type, p_name, p_theme_types[0]); +void Control::_set_anchor(Side p_side, real_t p_anchor) { + set_anchor(p_side, p_anchor); } -bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { - ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified."); - - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - // For each theme resource check the theme types provided and see if p_name exists with any of them. - for (const StringName &E : p_theme_types) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { - return true; - } - - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } +void Control::set_anchor(Side p_side, real_t p_anchor, bool p_keep_offset, bool p_push_opposite_anchor) { + ERR_FAIL_INDEX((int)p_side, 4); - // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - for (const StringName &E : p_theme_types) { - if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - } + Rect2 parent_rect = get_parent_anchorable_rect(); + real_t parent_range = (p_side == SIDE_LEFT || p_side == SIDE_RIGHT) ? parent_rect.size.x : parent_rect.size.y; + real_t previous_pos = data.offset[p_side] + data.anchor[p_side] * parent_range; + real_t previous_opposite_pos = data.offset[(p_side + 2) % 4] + data.anchor[(p_side + 2) % 4] * parent_range; - // Lastly, fall back on the items defined in the default Theme, if they exist. - for (const StringName &E : p_theme_types) { - if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - return false; -} + data.anchor[p_side] = p_anchor; -void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(data.theme_type_variation) != StringName()) { - Theme::get_project_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); + if (((p_side == SIDE_LEFT || p_side == SIDE_TOP) && data.anchor[p_side] > data.anchor[(p_side + 2) % 4]) || + ((p_side == SIDE_RIGHT || p_side == SIDE_BOTTOM) && data.anchor[p_side] < data.anchor[(p_side + 2) % 4])) { + if (p_push_opposite_anchor) { + data.anchor[(p_side + 2) % 4] = data.anchor[p_side]; } else { - Theme::get_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); - } - } else { - Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list); - } -} - -Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); - if (tex) { - return *tex; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<Ref<Texture2D>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); -} - -Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const Ref<StyleBox> *style = data.style_override.getptr(p_name); - if (style) { - return *style; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<Ref<StyleBox>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); -} - -Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const Ref<Font> *font = data.font_override.getptr(p_name); - if (font) { - return *font; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<Ref<Font>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); -} - -int Control::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const int *font_size = data.font_size_override.getptr(p_name); - if (font_size && (*font_size) > 0) { - return *font_size; + data.anchor[p_side] = data.anchor[(p_side + 2) % 4]; } } - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); -} - -Color Control::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const Color *color = data.color_override.getptr(p_name); - if (color) { - return *color; + if (!p_keep_offset) { + data.offset[p_side] = previous_pos - data.anchor[p_side] * parent_range; + if (p_push_opposite_anchor) { + data.offset[(p_side + 2) % 4] = previous_opposite_pos - data.anchor[(p_side + 2) % 4] * parent_range; } } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<Color>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); -} - -int Control::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const int *constant = data.constant_override.getptr(p_name); - if (constant) { - return *constant; - } + if (is_inside_tree()) { + _size_changed(); } - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); -} - -bool Control::has_theme_icon_override(const StringName &p_name) const { - const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); - return tex != nullptr; -} - -bool Control::has_theme_stylebox_override(const StringName &p_name) const { - const Ref<StyleBox> *style = data.style_override.getptr(p_name); - return style != nullptr; -} - -bool Control::has_theme_font_override(const StringName &p_name) const { - const Ref<Font> *font = data.font_override.getptr(p_name); - return font != nullptr; -} - -bool Control::has_theme_font_size_override(const StringName &p_name) const { - const int *font_size = data.font_size_override.getptr(p_name); - return font_size != nullptr; -} - -bool Control::has_theme_color_override(const StringName &p_name) const { - const Color *color = data.color_override.getptr(p_name); - return color != nullptr; -} - -bool Control::has_theme_constant_override(const StringName &p_name) const { - const int *constant = data.constant_override.getptr(p_name); - return constant != nullptr; + update(); } -bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_icon_override(p_name)) { - return true; - } - } +real_t Control::get_anchor(Side p_side) const { + ERR_FAIL_INDEX_V(int(p_side), 4, 0.0); - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); + return data.anchor[p_side]; } -bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_stylebox_override(p_name)) { - return true; - } - } +void Control::set_offset(Side p_side, real_t p_value) { + ERR_FAIL_INDEX((int)p_side, 4); - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + data.offset[p_side] = p_value; + _size_changed(); } -bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_font_override(p_name)) { - return true; - } - } +real_t Control::get_offset(Side p_side) const { + ERR_FAIL_INDEX_V((int)p_side, 4, 0); - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); + return data.offset[p_side]; } -bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_font_size_override(p_name)) { - return true; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); +void Control::set_anchor_and_offset(Side p_side, real_t p_anchor, real_t p_pos, bool p_push_opposite_anchor) { + set_anchor(p_side, p_anchor, false, p_push_opposite_anchor); + set_offset(p_side, p_pos); } -bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_color_override(p_name)) { - return true; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); +void Control::set_begin(const Size2 &p_point) { + data.offset[0] = p_point.x; + data.offset[1] = p_point.y; + _size_changed(); } -bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_constant_override(p_name)) { - return true; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); +Size2 Control::get_begin() const { + return Size2(data.offset[0], data.offset[1]); } -float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_base_scale()) { - return theme_owner->data.theme->get_default_base_scale(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_base_scale()) { - return theme_owner_window->theme->get_default_base_scale(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_base_scale()) { - return Theme::get_project_default()->get_default_base_scale(); - } - } - - // Lastly, fall back on the default Theme. - if (Theme::get_default()->has_default_base_scale()) { - return Theme::get_default()->get_default_base_scale(); - } - return Theme::get_fallback_base_scale(); +void Control::set_end(const Size2 &p_point) { + data.offset[2] = p_point.x; + data.offset[3] = p_point.y; + _size_changed(); } -float Control::get_theme_default_base_scale() const { - return fetch_theme_default_base_scale(data.theme_owner, data.theme_owner_window); +Size2 Control::get_end() const { + return Size2(data.offset[2], data.offset[3]); } -Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_font()) { - return theme_owner->data.theme->get_default_font(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_font()) { - return theme_owner_window->theme->get_default_font(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_font()) { - return Theme::get_project_default()->get_default_font(); - } - } +void Control::set_h_grow_direction(GrowDirection p_direction) { + ERR_FAIL_INDEX((int)p_direction, 3); - // Lastly, fall back on the default Theme. - if (Theme::get_default()->has_default_font()) { - return Theme::get_default()->get_default_font(); - } - return Theme::get_fallback_font(); + data.h_grow = p_direction; + _size_changed(); } -Ref<Font> Control::get_theme_default_font() const { - return fetch_theme_default_font(data.theme_owner, data.theme_owner_window); +Control::GrowDirection Control::get_h_grow_direction() const { + return data.h_grow; } -int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_font_size()) { - return theme_owner->data.theme->get_default_font_size(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_font_size()) { - return theme_owner_window->theme->get_default_font_size(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_font_size()) { - return Theme::get_project_default()->get_default_font_size(); - } - } +void Control::set_v_grow_direction(GrowDirection p_direction) { + ERR_FAIL_INDEX((int)p_direction, 3); - // Lastly, fall back on the default Theme. - if (Theme::get_default()->has_default_font_size()) { - return Theme::get_default()->get_default_font_size(); - } - return Theme::get_fallback_font_size(); + data.v_grow = p_direction; + _size_changed(); } -int Control::get_theme_default_font_size() const { - return fetch_theme_default_font_size(data.theme_owner, data.theme_owner_window); +Control::GrowDirection Control::get_v_grow_direction() const { + return data.v_grow; } -Rect2 Control::get_parent_anchorable_rect() const { - if (!is_inside_tree()) { - return Rect2(); - } - - Rect2 parent_rect; - if (data.parent_canvas_item) { - parent_rect = data.parent_canvas_item->get_anchorable_rect(); - } else { -#ifdef TOOLS_ENABLED - Node *edited_root = get_tree()->get_edited_scene_root(); - if (edited_root && (this == edited_root || edited_root->is_ancestor_of(this))) { - parent_rect.size = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); - } else { - parent_rect = get_viewport()->get_visible_rect(); - } +void Control::_compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]) { + Size2 parent_rect_size = get_parent_anchorable_rect().size; + ERR_FAIL_COND(parent_rect_size.x == 0.0); + ERR_FAIL_COND(parent_rect_size.y == 0.0); -#else - parent_rect = get_viewport()->get_visible_rect(); -#endif + real_t x = p_rect.position.x; + if (is_layout_rtl()) { + x = parent_rect_size.x - x - p_rect.size.x; } - - return parent_rect; -} - -Size2 Control::get_parent_area_size() const { - return get_parent_anchorable_rect().size; + r_anchors[0] = (x - p_offsets[0]) / parent_rect_size.x; + r_anchors[1] = (p_rect.position.y - p_offsets[1]) / parent_rect_size.y; + r_anchors[2] = (x + p_rect.size.x - p_offsets[2]) / parent_rect_size.x; + r_anchors[3] = (p_rect.position.y + p_rect.size.y - p_offsets[3]) / parent_rect_size.y; } -void Control::_size_changed() { - Rect2 parent_rect = get_parent_anchorable_rect(); - - real_t edge_pos[4]; - - for (int i = 0; i < 4; i++) { - real_t area = parent_rect.size[i & 1]; - edge_pos[i] = data.offset[i] + (data.anchor[i] * area); - } - - Point2 new_pos_cache = Point2(edge_pos[0], edge_pos[1]); - Size2 new_size_cache = Point2(edge_pos[2], edge_pos[3]) - new_pos_cache; - - Size2 minimum_size = get_combined_minimum_size(); - - if (minimum_size.width > new_size_cache.width) { - if (data.h_grow == GROW_DIRECTION_BEGIN) { - new_pos_cache.x += new_size_cache.width - minimum_size.width; - } else if (data.h_grow == GROW_DIRECTION_BOTH) { - new_pos_cache.x += 0.5 * (new_size_cache.width - minimum_size.width); - } - - new_size_cache.width = minimum_size.width; - } +void Control::_compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]) { + Size2 parent_rect_size = get_parent_anchorable_rect().size; + real_t x = p_rect.position.x; if (is_layout_rtl()) { - new_pos_cache.x = parent_rect.size.x - new_pos_cache.x - new_size_cache.x; - } - - if (minimum_size.height > new_size_cache.height) { - if (data.v_grow == GROW_DIRECTION_BEGIN) { - new_pos_cache.y += new_size_cache.height - minimum_size.height; - } else if (data.v_grow == GROW_DIRECTION_BOTH) { - new_pos_cache.y += 0.5 * (new_size_cache.height - minimum_size.height); - } - - new_size_cache.height = minimum_size.height; - } - - bool pos_changed = new_pos_cache != data.pos_cache; - bool size_changed = new_size_cache != data.size_cache; - - data.pos_cache = new_pos_cache; - data.size_cache = new_size_cache; - - if (is_inside_tree()) { - if (size_changed) { - notification(NOTIFICATION_RESIZED); - } - if (pos_changed || size_changed) { - item_rect_changed(size_changed); - _notify_transform(); - } - - if (pos_changed && !size_changed) { - _update_canvas_item_transform(); //move because it won't be updated - } + x = parent_rect_size.x - x - p_rect.size.x; } + r_offsets[0] = x - (p_anchors[0] * parent_rect_size.x); + r_offsets[1] = p_rect.position.y - (p_anchors[1] * parent_rect_size.y); + r_offsets[2] = x + p_rect.size.x - (p_anchors[2] * parent_rect_size.x); + r_offsets[3] = p_rect.position.y + p_rect.size.y - (p_anchors[3] * parent_rect_size.y); } +/// Presets and layout modes. + void Control::_set_layout_mode(LayoutMode p_mode) { bool list_changed = false; @@ -1557,47 +840,6 @@ Control::LayoutMode Control::_get_layout_mode() const { return LayoutMode::LAYOUT_MODE_POSITION; } -void Control::set_anchor(Side p_side, real_t p_anchor, bool p_keep_offset, bool p_push_opposite_anchor) { - ERR_FAIL_INDEX((int)p_side, 4); - - Rect2 parent_rect = get_parent_anchorable_rect(); - real_t parent_range = (p_side == SIDE_LEFT || p_side == SIDE_RIGHT) ? parent_rect.size.x : parent_rect.size.y; - real_t previous_pos = data.offset[p_side] + data.anchor[p_side] * parent_range; - real_t previous_opposite_pos = data.offset[(p_side + 2) % 4] + data.anchor[(p_side + 2) % 4] * parent_range; - - data.anchor[p_side] = p_anchor; - - if (((p_side == SIDE_LEFT || p_side == SIDE_TOP) && data.anchor[p_side] > data.anchor[(p_side + 2) % 4]) || - ((p_side == SIDE_RIGHT || p_side == SIDE_BOTTOM) && data.anchor[p_side] < data.anchor[(p_side + 2) % 4])) { - if (p_push_opposite_anchor) { - data.anchor[(p_side + 2) % 4] = data.anchor[p_side]; - } else { - data.anchor[p_side] = data.anchor[(p_side + 2) % 4]; - } - } - - if (!p_keep_offset) { - data.offset[p_side] = previous_pos - data.anchor[p_side] * parent_range; - if (p_push_opposite_anchor) { - data.offset[(p_side + 2) % 4] = previous_opposite_pos - data.anchor[(p_side + 2) % 4] * parent_range; - } - } - if (is_inside_tree()) { - _size_changed(); - } - - update(); -} - -void Control::_set_anchor(Side p_side, real_t p_anchor) { - set_anchor(p_side, p_anchor); -} - -void Control::set_anchor_and_offset(Side p_side, real_t p_anchor, real_t p_pos, bool p_push_opposite_anchor) { - set_anchor(p_side, p_anchor, false, p_push_opposite_anchor); - set_offset(p_side, p_pos); -} - void Control::_set_anchors_layout_preset(int p_preset) { bool list_changed = false; @@ -2037,43 +1279,37 @@ void Control::set_grow_direction_preset(LayoutPreset p_preset) { } } -real_t Control::get_anchor(Side p_side) const { - ERR_FAIL_INDEX_V(int(p_side), 4, 0.0); +/// Manual positioning. - return data.anchor[p_side]; +void Control::_set_position(const Size2 &p_point) { + set_position(p_point); } -void Control::set_offset(Side p_side, real_t p_value) { - ERR_FAIL_INDEX((int)p_side, 4); - - data.offset[p_side] = p_value; +void Control::set_position(const Size2 &p_point, bool p_keep_offsets) { + if (p_keep_offsets) { + _compute_anchors(Rect2(p_point, data.size_cache), data.offset, data.anchor); + } else { + _compute_offsets(Rect2(p_point, data.size_cache), data.anchor, data.offset); + } _size_changed(); } -void Control::set_begin(const Size2 &p_point) { - data.offset[0] = p_point.x; - data.offset[1] = p_point.y; - _size_changed(); +Size2 Control::get_position() const { + return data.pos_cache; } -void Control::set_end(const Size2 &p_point) { - data.offset[2] = p_point.x; - data.offset[3] = p_point.y; - _size_changed(); +void Control::_set_global_position(const Point2 &p_point) { + set_global_position(p_point); } -real_t Control::get_offset(Side p_side) const { - ERR_FAIL_INDEX_V((int)p_side, 4, 0); - - return data.offset[p_side]; -} +void Control::set_global_position(const Point2 &p_point, bool p_keep_offsets) { + Transform2D inv; -Size2 Control::get_begin() const { - return Size2(data.offset[0], data.offset[1]); -} + if (data.parent_canvas_item) { + inv = data.parent_canvas_item->get_global_transform().affine_inverse(); + } -Size2 Control::get_end() const { - return Size2(data.offset[2], data.offset[3]); + set_position(inv.xform(p_point), p_keep_offsets); } Point2 Control::get_global_position() const { @@ -2091,72 +1327,6 @@ Point2 Control::get_screen_position() const { return global_pos; } -void Control::_set_global_position(const Point2 &p_point) { - set_global_position(p_point); -} - -void Control::set_global_position(const Point2 &p_point, bool p_keep_offsets) { - Transform2D inv; - - if (data.parent_canvas_item) { - inv = data.parent_canvas_item->get_global_transform().affine_inverse(); - } - - set_position(inv.xform(p_point), p_keep_offsets); -} - -void Control::_compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]) { - Size2 parent_rect_size = get_parent_anchorable_rect().size; - ERR_FAIL_COND(parent_rect_size.x == 0.0); - ERR_FAIL_COND(parent_rect_size.y == 0.0); - - real_t x = p_rect.position.x; - if (is_layout_rtl()) { - x = parent_rect_size.x - x - p_rect.size.x; - } - r_anchors[0] = (x - p_offsets[0]) / parent_rect_size.x; - r_anchors[1] = (p_rect.position.y - p_offsets[1]) / parent_rect_size.y; - r_anchors[2] = (x + p_rect.size.x - p_offsets[2]) / parent_rect_size.x; - r_anchors[3] = (p_rect.position.y + p_rect.size.y - p_offsets[3]) / parent_rect_size.y; -} - -void Control::_compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]) { - Size2 parent_rect_size = get_parent_anchorable_rect().size; - - real_t x = p_rect.position.x; - if (is_layout_rtl()) { - x = parent_rect_size.x - x - p_rect.size.x; - } - r_offsets[0] = x - (p_anchors[0] * parent_rect_size.x); - r_offsets[1] = p_rect.position.y - (p_anchors[1] * parent_rect_size.y); - r_offsets[2] = x + p_rect.size.x - (p_anchors[2] * parent_rect_size.x); - r_offsets[3] = p_rect.position.y + p_rect.size.y - (p_anchors[3] * parent_rect_size.y); -} - -void Control::_set_position(const Size2 &p_point) { - set_position(p_point); -} - -void Control::set_position(const Size2 &p_point, bool p_keep_offsets) { - if (p_keep_offsets) { - _compute_anchors(Rect2(p_point, data.size_cache), data.offset, data.anchor); - } else { - _compute_offsets(Rect2(p_point, data.size_cache), data.anchor, data.offset); - } - _size_changed(); -} - -void Control::set_rect(const Rect2 &p_rect) { - for (int i = 0; i < 4; i++) { - data.anchor[i] = ANCHOR_BEGIN; - } - - _compute_offsets(p_rect, data.anchor, data.offset); - if (is_inside_tree()) { - _size_changed(); - } -} - void Control::_set_size(const Size2 &p_size) { #ifdef DEBUG_ENABLED if (data.size_warning && (data.anchor[SIDE_LEFT] != data.anchor[SIDE_RIGHT] || data.anchor[SIDE_TOP] != data.anchor[SIDE_BOTTOM])) { @@ -2184,10 +1354,6 @@ void Control::set_size(const Size2 &p_size, bool p_keep_offsets) { _size_changed(); } -Size2 Control::get_position() const { - return data.pos_cache; -} - Size2 Control::get_size() const { return data.size_cache; } @@ -2196,6 +1362,21 @@ void Control::reset_size() { set_size(Size2()); } +void Control::set_rect(const Rect2 &p_rect) { + for (int i = 0; i < 4; i++) { + data.anchor[i] = ANCHOR_BEGIN; + } + + _compute_offsets(p_rect, data.anchor, data.offset); + if (is_inside_tree()) { + _size_changed(); + } +} + +Rect2 Control::get_rect() const { + return Rect2(get_position(), get_size()); +} + Rect2 Control::get_global_rect() const { return Rect2(get_global_position(), get_size()); } @@ -2220,118 +1401,382 @@ Rect2 Control::get_window_rect() const { return gr; } -Rect2 Control::get_rect() const { - return Rect2(get_position(), get_size()); -} - Rect2 Control::get_anchorable_rect() const { return Rect2(Point2(), get_size()); } -void Control::begin_bulk_theme_override() { - data.bulk_theme_override = true; +void Control::set_scale(const Vector2 &p_scale) { + data.scale = p_scale; + // Avoid having 0 scale values, can lead to errors in physics and rendering. + if (data.scale.x == 0) { + data.scale.x = CMP_EPSILON; + } + if (data.scale.y == 0) { + data.scale.y = CMP_EPSILON; + } + update(); + _notify_transform(); } -void Control::end_bulk_theme_override() { - ERR_FAIL_COND(!data.bulk_theme_override); +Vector2 Control::get_scale() const { + return data.scale; +} - data.bulk_theme_override = false; - _notify_theme_changed(); +void Control::set_rotation(real_t p_radians) { + data.rotation = p_radians; + update(); + _notify_transform(); } -void Control::add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) { - ERR_FAIL_COND(!p_icon.is_valid()); +real_t Control::get_rotation() const { + return data.rotation; +} - if (data.icon_override.has(p_name)) { - data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); +void Control::set_pivot_offset(const Vector2 &p_pivot) { + data.pivot_offset = p_pivot; + update(); + _notify_transform(); +} + +Vector2 Control::get_pivot_offset() const { + return data.pivot_offset; +} + +/// Sizes. + +void Control::_update_minimum_size() { + if (!is_inside_tree()) { + return; } - data.icon_override[p_name] = p_icon; - data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - _notify_theme_changed(); + Size2 minsize = get_combined_minimum_size(); + data.updating_last_minimum_size = false; + + if (minsize != data.last_minimum_size) { + data.last_minimum_size = minsize; + _size_changed(); + emit_signal(SceneStringNames::get_singleton()->minimum_size_changed); + } } -void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) { - ERR_FAIL_COND(!p_style.is_valid()); +void Control::update_minimum_size() { + if (!is_inside_tree() || data.block_minimum_size_adjust) { + return; + } - if (data.style_override.has(p_name)) { - data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); + Control *invalidate = this; + + //invalidate cache upwards + while (invalidate && invalidate->data.minimum_size_valid) { + invalidate->data.minimum_size_valid = false; + if (invalidate->is_set_as_top_level()) { + break; // do not go further up + } + if (!invalidate->data.parent && get_parent()) { + Window *parent_window = Object::cast_to<Window>(get_parent()); + if (parent_window && parent_window->is_wrapping_controls()) { + parent_window->child_controls_changed(); + } + } + invalidate = invalidate->data.parent; } - data.style_override[p_name] = p_style; - data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - _notify_theme_changed(); + if (!is_visible_in_tree()) { + return; + } + + if (data.updating_last_minimum_size) { + return; + } + + data.updating_last_minimum_size = true; + + MessageQueue::get_singleton()->push_call(this, "_update_minimum_size"); } -void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) { - ERR_FAIL_COND(!p_font.is_valid()); +void Control::set_block_minimum_size_adjust(bool p_block) { + data.block_minimum_size_adjust = p_block; +} - if (data.font_override.has(p_name)) { - data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); +bool Control::is_minimum_size_adjust_blocked() const { + return data.block_minimum_size_adjust; +} + +Size2 Control::get_minimum_size() const { + Vector2 ms; + if (GDVIRTUAL_CALL(_get_minimum_size, ms)) { + return ms; } + return Vector2(); +} - data.font_override[p_name] = p_font; - data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - _notify_theme_changed(); +void Control::set_custom_minimum_size(const Size2 &p_custom) { + if (p_custom == data.custom_minimum_size) { + return; + } + data.custom_minimum_size = p_custom; + update_minimum_size(); } -void Control::add_theme_font_size_override(const StringName &p_name, int p_font_size) { - data.font_size_override[p_name] = p_font_size; - _notify_theme_changed(); +Size2 Control::get_custom_minimum_size() const { + return data.custom_minimum_size; } -void Control::add_theme_color_override(const StringName &p_name, const Color &p_color) { - data.color_override[p_name] = p_color; - _notify_theme_changed(); +void Control::_update_minimum_size_cache() { + Size2 minsize = get_minimum_size(); + minsize.x = MAX(minsize.x, data.custom_minimum_size.x); + minsize.y = MAX(minsize.y, data.custom_minimum_size.y); + + bool size_changed = false; + if (data.minimum_size_cache != minsize) { + size_changed = true; + } + + data.minimum_size_cache = minsize; + data.minimum_size_valid = true; + + if (size_changed) { + update_minimum_size(); + } } -void Control::add_theme_constant_override(const StringName &p_name, int p_constant) { - data.constant_override[p_name] = p_constant; - _notify_theme_changed(); +Size2 Control::get_combined_minimum_size() const { + if (!data.minimum_size_valid) { + const_cast<Control *>(this)->_update_minimum_size_cache(); + } + return data.minimum_size_cache; } -void Control::remove_theme_icon_override(const StringName &p_name) { - if (data.icon_override.has(p_name)) { - data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); +void Control::_size_changed() { + Rect2 parent_rect = get_parent_anchorable_rect(); + + real_t edge_pos[4]; + + for (int i = 0; i < 4; i++) { + real_t area = parent_rect.size[i & 1]; + edge_pos[i] = data.offset[i] + (data.anchor[i] * area); } - data.icon_override.erase(p_name); - _notify_theme_changed(); + Point2 new_pos_cache = Point2(edge_pos[0], edge_pos[1]); + Size2 new_size_cache = Point2(edge_pos[2], edge_pos[3]) - new_pos_cache; + + Size2 minimum_size = get_combined_minimum_size(); + + if (minimum_size.width > new_size_cache.width) { + if (data.h_grow == GROW_DIRECTION_BEGIN) { + new_pos_cache.x += new_size_cache.width - minimum_size.width; + } else if (data.h_grow == GROW_DIRECTION_BOTH) { + new_pos_cache.x += 0.5 * (new_size_cache.width - minimum_size.width); + } + + new_size_cache.width = minimum_size.width; + } + + if (is_layout_rtl()) { + new_pos_cache.x = parent_rect.size.x - new_pos_cache.x - new_size_cache.x; + } + + if (minimum_size.height > new_size_cache.height) { + if (data.v_grow == GROW_DIRECTION_BEGIN) { + new_pos_cache.y += new_size_cache.height - minimum_size.height; + } else if (data.v_grow == GROW_DIRECTION_BOTH) { + new_pos_cache.y += 0.5 * (new_size_cache.height - minimum_size.height); + } + + new_size_cache.height = minimum_size.height; + } + + bool pos_changed = new_pos_cache != data.pos_cache; + bool size_changed = new_size_cache != data.size_cache; + + data.pos_cache = new_pos_cache; + data.size_cache = new_size_cache; + + if (is_inside_tree()) { + if (size_changed) { + notification(NOTIFICATION_RESIZED); + } + if (pos_changed || size_changed) { + item_rect_changed(size_changed); + _notify_transform(); + } + + if (pos_changed && !size_changed) { + _update_canvas_item_transform(); //move because it won't be updated + } + } } -void Control::remove_theme_style_override(const StringName &p_name) { - if (data.style_override.has(p_name)) { - data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); +void Control::_clear_size_warning() { + data.size_warning = false; +} + +// Container sizing. + +void Control::set_h_size_flags(int p_flags) { + if (data.h_size_flags == p_flags) { + return; } + data.h_size_flags = p_flags; + emit_signal(SceneStringNames::get_singleton()->size_flags_changed); +} - data.style_override.erase(p_name); - _notify_theme_changed(); +int Control::get_h_size_flags() const { + return data.h_size_flags; } -void Control::remove_theme_font_override(const StringName &p_name) { - if (data.font_override.has(p_name)) { - data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); +void Control::set_v_size_flags(int p_flags) { + if (data.v_size_flags == p_flags) { + return; } + data.v_size_flags = p_flags; + emit_signal(SceneStringNames::get_singleton()->size_flags_changed); +} - data.font_override.erase(p_name); - _notify_theme_changed(); +int Control::get_v_size_flags() const { + return data.v_size_flags; } -void Control::remove_theme_font_size_override(const StringName &p_name) { - data.font_size_override.erase(p_name); - _notify_theme_changed(); +void Control::set_stretch_ratio(real_t p_ratio) { + if (data.expand == p_ratio) { + return; + } + + data.expand = p_ratio; + emit_signal(SceneStringNames::get_singleton()->size_flags_changed); } -void Control::remove_theme_color_override(const StringName &p_name) { - data.color_override.erase(p_name); - _notify_theme_changed(); +real_t Control::get_stretch_ratio() const { + return data.expand; } -void Control::remove_theme_constant_override(const StringName &p_name) { - data.constant_override.erase(p_name); - _notify_theme_changed(); +// Input events. + +void Control::_call_gui_input(const Ref<InputEvent> &p_event) { + emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); //signal should be first, so it's possible to override an event (and then accept it) + if (!is_inside_tree() || get_viewport()->is_input_handled()) { + return; //input was handled, abort + } + GDVIRTUAL_CALL(_gui_input, p_event); + if (!is_inside_tree() || get_viewport()->is_input_handled()) { + return; //input was handled, abort + } + gui_input(p_event); +} + +void Control::gui_input(const Ref<InputEvent> &p_event) { +} + +void Control::accept_event() { + if (is_inside_tree()) { + get_viewport()->_gui_accept_event(); + } +} + +bool Control::has_point(const Point2 &p_point) const { + bool ret; + if (GDVIRTUAL_CALL(_has_point, p_point, ret)) { + return ret; + } + return Rect2(Point2(), get_size()).has_point(p_point); +} + +void Control::set_mouse_filter(MouseFilter p_filter) { + ERR_FAIL_INDEX(p_filter, 3); + data.mouse_filter = p_filter; + notify_property_list_changed(); + update_configuration_warnings(); +} + +Control::MouseFilter Control::get_mouse_filter() const { + return data.mouse_filter; +} + +void Control::set_force_pass_scroll_events(bool p_force_pass_scroll_events) { + data.force_pass_scroll_events = p_force_pass_scroll_events; +} + +bool Control::is_force_pass_scroll_events() const { + return data.force_pass_scroll_events; +} + +void Control::warp_mouse(const Point2 &p_position) { + ERR_FAIL_COND(!is_inside_tree()); + get_viewport()->warp_mouse(get_global_transform_with_canvas().xform(p_position)); +} + +// Drag and drop handling. + +void Control::set_drag_forwarding(Object *p_target) { + if (p_target) { + data.drag_owner = p_target->get_instance_id(); + } else { + data.drag_owner = ObjectID(); + } +} + +Variant Control::get_drag_data(const Point2 &p_point) { + if (data.drag_owner.is_valid()) { + Object *obj = ObjectDB::get_instance(data.drag_owner); + if (obj) { + return obj->call("_get_drag_data_fw", p_point, this); + } + } + + Variant dd; + if (GDVIRTUAL_CALL(_get_drag_data, p_point, dd)) { + return dd; + } + + return Variant(); +} + +bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const { + if (data.drag_owner.is_valid()) { + Object *obj = ObjectDB::get_instance(data.drag_owner); + if (obj) { + return obj->call("_can_drop_data_fw", p_point, p_data, this); + } + } + + bool ret; + if (GDVIRTUAL_CALL(_can_drop_data, p_point, p_data, ret)) { + return ret; + } + return false; +} + +void Control::drop_data(const Point2 &p_point, const Variant &p_data) { + if (data.drag_owner.is_valid()) { + Object *obj = ObjectDB::get_instance(data.drag_owner); + if (obj) { + obj->call("_drop_data_fw", p_point, p_data, this); + return; + } + } + + GDVIRTUAL_CALL(_drop_data, p_point, p_data); +} + +void Control::force_drag(const Variant &p_data, Control *p_control) { + ERR_FAIL_COND(!is_inside_tree()); + ERR_FAIL_COND(p_data.get_type() == Variant::NIL); + + get_viewport()->_gui_force_drag(this, p_data, p_control); +} + +void Control::set_drag_preview(Control *p_control) { + ERR_FAIL_COND(!is_inside_tree()); + ERR_FAIL_COND(!get_viewport()->gui_is_dragging()); + get_viewport()->_gui_set_drag_preview(this, p_control); +} + +bool Control::is_drag_successful() const { + return is_inside_tree() && get_viewport()->gui_is_drag_successful(); } +// Focus. + void Control::set_focus_mode(FocusMode p_focus_mode) { ERR_FAIL_INDEX((int)p_focus_mode, 3); @@ -2342,6 +1787,41 @@ void Control::set_focus_mode(FocusMode p_focus_mode) { data.focus_mode = p_focus_mode; } +Control::FocusMode Control::get_focus_mode() const { + return data.focus_mode; +} + +bool Control::has_focus() const { + return is_inside_tree() && get_viewport()->_gui_control_has_focus(this); +} + +void Control::grab_focus() { + ERR_FAIL_COND(!is_inside_tree()); + + if (data.focus_mode == FOCUS_NONE) { + WARN_PRINT("This control can't grab focus. Use set_focus_mode() to allow a control to get focus."); + return; + } + + get_viewport()->_gui_control_grab_focus(this); +} + +void Control::grab_click_focus() { + ERR_FAIL_COND(!is_inside_tree()); + + get_viewport()->_gui_grab_click_focus(this); +} + +void Control::release_focus() { + ERR_FAIL_COND(!is_inside_tree()); + + if (!has_focus()) { + return; + } + + get_viewport()->gui_release_focus(); +} + static Control *_next_control(Control *p_from) { if (p_from->is_set_as_top_level()) { return nullptr; // Can't go above. @@ -2520,181 +2000,6 @@ Control *Control::find_prev_valid_focus() const { return nullptr; } -Control::FocusMode Control::get_focus_mode() const { - return data.focus_mode; -} - -bool Control::has_focus() const { - return is_inside_tree() && get_viewport()->_gui_control_has_focus(this); -} - -void Control::grab_focus() { - ERR_FAIL_COND(!is_inside_tree()); - - if (data.focus_mode == FOCUS_NONE) { - WARN_PRINT("This control can't grab focus. Use set_focus_mode() to allow a control to get focus."); - return; - } - - get_viewport()->_gui_control_grab_focus(this); -} - -void Control::release_focus() { - ERR_FAIL_COND(!is_inside_tree()); - - if (!has_focus()) { - return; - } - - get_viewport()->gui_release_focus(); -} - -bool Control::is_top_level_control() const { - return is_inside_tree() && (!data.parent_canvas_item && !data.RI && is_set_as_top_level()); -} - -void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign) { - Control *c = Object::cast_to<Control>(p_at); - - if (c && c != p_owner && c->data.theme.is_valid()) { // has a theme, this can't be propagated - return; - } - - Window *w = c == nullptr ? Object::cast_to<Window>(p_at) : nullptr; - - if (w && w != p_owner_window && w->theme.is_valid()) { // has a theme, this can't be propagated - return; - } - - for (int i = 0; i < p_at->get_child_count(); i++) { - CanvasItem *child = Object::cast_to<CanvasItem>(p_at->get_child(i)); - if (child) { - _propagate_theme_changed(child, p_owner, p_owner_window, p_assign); - } else { - Window *window = Object::cast_to<Window>(p_at->get_child(i)); - if (window) { - _propagate_theme_changed(window, p_owner, p_owner_window, p_assign); - } - } - } - - if (c) { - if (p_assign) { - c->data.theme_owner = p_owner; - c->data.theme_owner_window = p_owner_window; - } - c->notification(Control::NOTIFICATION_THEME_CHANGED); - c->emit_signal(SceneStringNames::get_singleton()->theme_changed); - } - - if (w) { - if (p_assign) { - w->theme_owner = p_owner; - w->theme_owner_window = p_owner_window; - } - w->notification(Window::NOTIFICATION_THEME_CHANGED); - w->emit_signal(SceneStringNames::get_singleton()->theme_changed); - } -} - -void Control::_theme_changed() { - _propagate_theme_changed(this, this, nullptr, false); -} - -void Control::_notify_theme_changed() { - if (!data.bulk_theme_override) { - notification(NOTIFICATION_THEME_CHANGED); - } -} - -void Control::set_theme(const Ref<Theme> &p_theme) { - if (data.theme == p_theme) { - return; - } - - if (data.theme.is_valid()) { - data.theme->disconnect("changed", callable_mp(this, &Control::_theme_changed)); - } - - data.theme = p_theme; - if (!p_theme.is_null()) { - data.theme_owner = this; - data.theme_owner_window = nullptr; - _propagate_theme_changed(this, this, nullptr); - } else { - Control *parent_c = Object::cast_to<Control>(get_parent()); - - if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window); - } else { - Window *parent_w = cast_to<Window>(get_parent()); - if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window); - } else { - Control::_propagate_theme_changed(this, nullptr, nullptr); - } - } - } - - if (data.theme.is_valid()) { - data.theme->connect("changed", callable_mp(this, &Control::_theme_changed), varray(), CONNECT_DEFERRED); - } -} - -Ref<Theme> Control::get_theme() const { - return data.theme; -} - -void Control::set_theme_type_variation(const StringName &p_theme_type) { - data.theme_type_variation = p_theme_type; - _propagate_theme_changed(this, data.theme_owner, data.theme_owner_window); -} - -StringName Control::get_theme_type_variation() const { - return data.theme_type_variation; -} - -void Control::set_tooltip(const String &p_tooltip) { - data.tooltip = p_tooltip; - update_configuration_warnings(); -} - -String Control::get_tooltip(const Point2 &p_pos) const { - return data.tooltip; -} - -Control *Control::make_custom_tooltip(const String &p_text) const { - Object *ret = nullptr; - if (GDVIRTUAL_CALL(_make_custom_tooltip, p_text, ret)) { - return Object::cast_to<Control>(ret); - } - return nullptr; -} - -void Control::set_default_cursor_shape(CursorShape p_shape) { - ERR_FAIL_INDEX(int(p_shape), CURSOR_MAX); - - data.default_cursor = p_shape; -} - -Control::CursorShape Control::get_default_cursor_shape() const { - return data.default_cursor; -} - -Control::CursorShape Control::get_cursor_shape(const Point2 &p_pos) const { - return data.default_cursor; -} - -Transform2D Control::get_transform() const { - Transform2D xform = _get_internal_transform(); - xform[2] += get_position(); - return xform; -} - -String Control::_get_tooltip() const { - return data.tooltip; -} - void Control::set_focus_neighbor(Side p_side, const NodePath &p_neighbor) { ERR_FAIL_INDEX((int)p_side, 4); data.focus_neighbor[p_side] = p_neighbor; @@ -2861,273 +2166,1011 @@ void Control::_window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, cons } } -void Control::set_h_size_flags(int p_flags) { - if (data.h_size_flags == p_flags) { +// Rendering. + +void Control::set_default_cursor_shape(CursorShape p_shape) { + ERR_FAIL_INDEX(int(p_shape), CURSOR_MAX); + + data.default_cursor = p_shape; +} + +Control::CursorShape Control::get_default_cursor_shape() const { + return data.default_cursor; +} + +Control::CursorShape Control::get_cursor_shape(const Point2 &p_pos) const { + return data.default_cursor; +} + +void Control::set_disable_visibility_clip(bool p_ignore) { + data.disable_visibility_clip = p_ignore; + update(); +} + +bool Control::is_visibility_clip_disabled() const { + return data.disable_visibility_clip; +} + +void Control::set_clip_contents(bool p_clip) { + data.clip_contents = p_clip; + update(); +} + +bool Control::is_clipping_contents() { + return data.clip_contents; +} + +// Theming. + +void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign) { + Control *c = Object::cast_to<Control>(p_at); + + if (c && c != p_owner && c->data.theme.is_valid()) { // has a theme, this can't be propagated return; } - data.h_size_flags = p_flags; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); + + Window *w = c == nullptr ? Object::cast_to<Window>(p_at) : nullptr; + + if (w && w != p_owner_window && w->theme.is_valid()) { // has a theme, this can't be propagated + return; + } + + for (int i = 0; i < p_at->get_child_count(); i++) { + CanvasItem *child = Object::cast_to<CanvasItem>(p_at->get_child(i)); + if (child) { + _propagate_theme_changed(child, p_owner, p_owner_window, p_assign); + } else { + Window *window = Object::cast_to<Window>(p_at->get_child(i)); + if (window) { + _propagate_theme_changed(window, p_owner, p_owner_window, p_assign); + } + } + } + + if (c) { + if (p_assign) { + c->data.theme_owner = p_owner; + c->data.theme_owner_window = p_owner_window; + } + c->notification(Control::NOTIFICATION_THEME_CHANGED); + c->emit_signal(SceneStringNames::get_singleton()->theme_changed); + } + + if (w) { + if (p_assign) { + w->theme_owner = p_owner; + w->theme_owner_window = p_owner_window; + } + w->notification(Window::NOTIFICATION_THEME_CHANGED); + w->emit_signal(SceneStringNames::get_singleton()->theme_changed); + } } -int Control::get_h_size_flags() const { - return data.h_size_flags; +void Control::_theme_changed() { + _propagate_theme_changed(this, this, nullptr, false); } -void Control::set_v_size_flags(int p_flags) { - if (data.v_size_flags == p_flags) { - return; +void Control::_theme_property_override_changed() { + notification(NOTIFICATION_THEME_CHANGED); + emit_signal(SceneStringNames::get_singleton()->theme_changed); + update_minimum_size(); // Overrides are likely to affect minimum size. +} + +void Control::_notify_theme_changed() { + if (!data.bulk_theme_override) { + notification(NOTIFICATION_THEME_CHANGED); } - data.v_size_flags = p_flags; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); } -void Control::set_stretch_ratio(real_t p_ratio) { - if (data.expand == p_ratio) { +void Control::set_theme(const Ref<Theme> &p_theme) { + if (data.theme == p_theme) { return; } - data.expand = p_ratio; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); + if (data.theme.is_valid()) { + data.theme->disconnect("changed", callable_mp(this, &Control::_theme_changed)); + } + + data.theme = p_theme; + if (!p_theme.is_null()) { + data.theme_owner = this; + data.theme_owner_window = nullptr; + _propagate_theme_changed(this, this, nullptr); + } else { + Control *parent_c = Object::cast_to<Control>(get_parent()); + + if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { + Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window); + } else { + Window *parent_w = cast_to<Window>(get_parent()); + if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { + Control::_propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window); + } else { + Control::_propagate_theme_changed(this, nullptr, nullptr); + } + } + } + + if (data.theme.is_valid()) { + data.theme->connect("changed", callable_mp(this, &Control::_theme_changed), CONNECT_DEFERRED); + } } -real_t Control::get_stretch_ratio() const { - return data.expand; +Ref<Theme> Control::get_theme() const { + return data.theme; } -void Control::grab_click_focus() { - ERR_FAIL_COND(!is_inside_tree()); +void Control::set_theme_type_variation(const StringName &p_theme_type) { + data.theme_type_variation = p_theme_type; + _propagate_theme_changed(this, data.theme_owner, data.theme_owner_window); +} - get_viewport()->_gui_grab_click_focus(this); +StringName Control::get_theme_type_variation() const { + return data.theme_type_variation; } -void Control::update_minimum_size() { - if (!is_inside_tree() || data.block_minimum_size_adjust) { - return; +/// Theme property lookup. + +template <class T> +T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { + ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, T(), "At least one theme type must be specified."); + + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; + + while (theme_owner || theme_owner_window) { + // For each theme resource check the theme types provided and see if p_name exists with any of them. + for (const StringName &E : p_theme_types) { + if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { + return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E); + } + + if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { + return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E); + } + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; + } + } } - Control *invalidate = this; + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + for (const StringName &E : p_theme_types) { + if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { + return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E); + } + } + } - //invalidate cache upwards - while (invalidate && invalidate->data.minimum_size_valid) { - invalidate->data.minimum_size_valid = false; - if (invalidate->is_set_as_top_level()) { - break; // do not go further up + // Lastly, fall back on the items defined in the default Theme, if they exist. + for (const StringName &E : p_theme_types) { + if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { + return Theme::get_default()->get_theme_item(p_data_type, p_name, E); } - if (!invalidate->data.parent && get_parent()) { - Window *parent_window = Object::cast_to<Window>(get_parent()); - if (parent_window && parent_window->is_wrapping_controls()) { - parent_window->child_controls_changed(); + } + // If they don't exist, use any type to return the default/empty value. + return Theme::get_default()->get_theme_item(p_data_type, p_name, p_theme_types[0]); +} + +bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { + ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified."); + + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; + + while (theme_owner || theme_owner_window) { + // For each theme resource check the theme types provided and see if p_name exists with any of them. + for (const StringName &E : p_theme_types) { + if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { + return true; + } + + if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { + return true; + } + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; } } - invalidate = invalidate->data.parent; } - if (!is_visible_in_tree()) { - return; + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + for (const StringName &E : p_theme_types) { + if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { + return true; + } + } } - if (data.updating_last_minimum_size) { - return; + // Lastly, fall back on the items defined in the default Theme, if they exist. + for (const StringName &E : p_theme_types) { + if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { + return true; + } } + return false; +} - data.updating_last_minimum_size = true; +void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(data.theme_type_variation) != StringName()) { + Theme::get_project_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); + } else { + Theme::get_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); + } + } else { + Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list); + } +} - MessageQueue::get_singleton()->push_call(this, "_update_minimum_size"); +Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); + if (tex) { + return *tex; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Ref<Texture2D>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); } -int Control::get_v_size_flags() const { - return data.v_size_flags; +Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const Ref<StyleBox> *style = data.style_override.getptr(p_name); + if (style) { + return *style; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Ref<StyleBox>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } -void Control::set_mouse_filter(MouseFilter p_filter) { - ERR_FAIL_INDEX(p_filter, 3); - data.mouse_filter = p_filter; - notify_property_list_changed(); - update_configuration_warnings(); +Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const Ref<Font> *font = data.font_override.getptr(p_name); + if (font) { + return *font; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Ref<Font>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); } -Control::MouseFilter Control::get_mouse_filter() const { - return data.mouse_filter; +int Control::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const int *font_size = data.font_size_override.getptr(p_name); + if (font_size && (*font_size) > 0) { + return *font_size; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } -void Control::set_force_pass_scroll_events(bool p_force_pass_scroll_events) { - data.force_pass_scroll_events = p_force_pass_scroll_events; +Color Control::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const Color *color = data.color_override.getptr(p_name); + if (color) { + return *color; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Color>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); } -bool Control::is_force_pass_scroll_events() const { - return data.force_pass_scroll_events; +int Control::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const int *constant = data.constant_override.getptr(p_name); + if (constant) { + return *constant; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } -void Control::warp_mouse(const Point2 &p_position) { - ERR_FAIL_COND(!is_inside_tree()); - get_viewport()->warp_mouse(get_global_transform_with_canvas().xform(p_position)); +bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_icon_override(p_name)) { + return true; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); } -bool Control::is_text_field() const { - return false; +bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_stylebox_override(p_name)) { + return true; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } -Array Control::structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const { - if (p_parser_type == TextServer::STRUCTURED_TEXT_CUSTOM) { - Array ret; - if (GDVIRTUAL_CALL(_structured_text_parser, p_args, p_text, ret)) { - return ret; - } else { - return Array(); +bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_font_override(p_name)) { + return true; } - } else { - return TS->parse_structured_text(p_parser_type, p_args, p_text); } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); } -void Control::set_rotation(real_t p_radians) { - data.rotation = p_radians; - update(); - _notify_transform(); +bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_font_size_override(p_name)) { + return true; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } -real_t Control::get_rotation() const { - return data.rotation; +bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_color_override(p_name)) { + return true; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); } -void Control::_override_changed() { - notification(NOTIFICATION_THEME_CHANGED); - emit_signal(SceneStringNames::get_singleton()->theme_changed); - update_minimum_size(); // Overrides are likely to affect minimum size. +bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_constant_override(p_name)) { + return true; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } -void Control::set_pivot_offset(const Vector2 &p_pivot) { - data.pivot_offset = p_pivot; - update(); - _notify_transform(); +/// Local property overrides. + +void Control::add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) { + ERR_FAIL_COND(!p_icon.is_valid()); + + if (data.icon_override.has(p_name)) { + data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + } + + data.icon_override[p_name] = p_icon; + data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_theme_property_override_changed), CONNECT_REFERENCE_COUNTED); + _notify_theme_changed(); } -Vector2 Control::get_pivot_offset() const { - return data.pivot_offset; +void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) { + ERR_FAIL_COND(!p_style.is_valid()); + + if (data.style_override.has(p_name)) { + data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + } + + data.style_override[p_name] = p_style; + data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_theme_property_override_changed), CONNECT_REFERENCE_COUNTED); + _notify_theme_changed(); } -void Control::set_scale(const Vector2 &p_scale) { - data.scale = p_scale; - // Avoid having 0 scale values, can lead to errors in physics and rendering. - if (data.scale.x == 0) { - data.scale.x = CMP_EPSILON; +void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) { + ERR_FAIL_COND(!p_font.is_valid()); + + if (data.font_override.has(p_name)) { + data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); } - if (data.scale.y == 0) { - data.scale.y = CMP_EPSILON; + + data.font_override[p_name] = p_font; + data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_theme_property_override_changed), CONNECT_REFERENCE_COUNTED); + _notify_theme_changed(); +} + +void Control::add_theme_font_size_override(const StringName &p_name, int p_font_size) { + data.font_size_override[p_name] = p_font_size; + _notify_theme_changed(); +} + +void Control::add_theme_color_override(const StringName &p_name, const Color &p_color) { + data.color_override[p_name] = p_color; + _notify_theme_changed(); +} + +void Control::add_theme_constant_override(const StringName &p_name, int p_constant) { + data.constant_override[p_name] = p_constant; + _notify_theme_changed(); +} + +void Control::remove_theme_icon_override(const StringName &p_name) { + if (data.icon_override.has(p_name)) { + data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); } - update(); - _notify_transform(); + + data.icon_override.erase(p_name); + _notify_theme_changed(); } -Vector2 Control::get_scale() const { - return data.scale; +void Control::remove_theme_style_override(const StringName &p_name) { + if (data.style_override.has(p_name)) { + data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + } + + data.style_override.erase(p_name); + _notify_theme_changed(); } -Control *Control::get_root_parent_control() const { - const CanvasItem *ci = this; - const Control *root = this; +void Control::remove_theme_font_override(const StringName &p_name) { + if (data.font_override.has(p_name)) { + data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + } - while (ci) { - const Control *c = Object::cast_to<Control>(ci); - if (c) { - root = c; + data.font_override.erase(p_name); + _notify_theme_changed(); +} - if (c->data.RI || c->is_top_level_control()) { - break; +void Control::remove_theme_font_size_override(const StringName &p_name) { + data.font_size_override.erase(p_name); + _notify_theme_changed(); +} + +void Control::remove_theme_color_override(const StringName &p_name) { + data.color_override.erase(p_name); + _notify_theme_changed(); +} + +void Control::remove_theme_constant_override(const StringName &p_name) { + data.constant_override.erase(p_name); + _notify_theme_changed(); +} + +bool Control::has_theme_icon_override(const StringName &p_name) const { + const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); + return tex != nullptr; +} + +bool Control::has_theme_stylebox_override(const StringName &p_name) const { + const Ref<StyleBox> *style = data.style_override.getptr(p_name); + return style != nullptr; +} + +bool Control::has_theme_font_override(const StringName &p_name) const { + const Ref<Font> *font = data.font_override.getptr(p_name); + return font != nullptr; +} + +bool Control::has_theme_font_size_override(const StringName &p_name) const { + const int *font_size = data.font_size_override.getptr(p_name); + return font_size != nullptr; +} + +bool Control::has_theme_color_override(const StringName &p_name) const { + const Color *color = data.color_override.getptr(p_name); + return color != nullptr; +} + +bool Control::has_theme_constant_override(const StringName &p_name) const { + const int *constant = data.constant_override.getptr(p_name); + return constant != nullptr; +} + +/// Default theme properties. + +float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_theme_owner_window) { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; + + while (theme_owner || theme_owner_window) { + if (theme_owner && theme_owner->data.theme->has_default_base_scale()) { + return theme_owner->data.theme->get_default_base_scale(); + } + + if (theme_owner_window && theme_owner_window->theme->has_default_base_scale()) { + return theme_owner_window->theme->get_default_base_scale(); + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; } } + } - ci = ci->get_parent_item(); + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + if (Theme::get_project_default()->has_default_base_scale()) { + return Theme::get_project_default()->get_default_base_scale(); + } } - return const_cast<Control *>(root); + // Lastly, fall back on the default Theme. + if (Theme::get_default()->has_default_base_scale()) { + return Theme::get_default()->get_default_base_scale(); + } + return Theme::get_fallback_base_scale(); } -void Control::set_block_minimum_size_adjust(bool p_block) { - data.block_minimum_size_adjust = p_block; +float Control::get_theme_default_base_scale() const { + return fetch_theme_default_base_scale(data.theme_owner, data.theme_owner_window); } -bool Control::is_minimum_size_adjust_blocked() const { - return data.block_minimum_size_adjust; -} +Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_theme_owner_window) { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; -void Control::set_disable_visibility_clip(bool p_ignore) { - data.disable_visibility_clip = p_ignore; - update(); + while (theme_owner || theme_owner_window) { + if (theme_owner && theme_owner->data.theme->has_default_font()) { + return theme_owner->data.theme->get_default_font(); + } + + if (theme_owner_window && theme_owner_window->theme->has_default_font()) { + return theme_owner_window->theme->get_default_font(); + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; + } + } + } + + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + if (Theme::get_project_default()->has_default_font()) { + return Theme::get_project_default()->get_default_font(); + } + } + + // Lastly, fall back on the default Theme. + if (Theme::get_default()->has_default_font()) { + return Theme::get_default()->get_default_font(); + } + return Theme::get_fallback_font(); } -bool Control::is_visibility_clip_disabled() const { - return data.disable_visibility_clip; +Ref<Font> Control::get_theme_default_font() const { + return fetch_theme_default_font(data.theme_owner, data.theme_owner_window); } -void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { - Node::get_argument_options(p_function, p_idx, r_options); +int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_theme_owner_window) { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; - if (p_idx == 0) { - List<StringName> sn; - String pf = p_function; - if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color") { - Theme::get_default()->get_color_list(get_class(), &sn); - } else if (pf == "add_theme_style_override" || pf == "has_theme_style" || pf == "has_theme_style_override" || pf == "get_theme_style") { - Theme::get_default()->get_stylebox_list(get_class(), &sn); - } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font") { - Theme::get_default()->get_font_list(get_class(), &sn); - } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size") { - Theme::get_default()->get_font_size_list(get_class(), &sn); - } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant") { - Theme::get_default()->get_constant_list(get_class(), &sn); + while (theme_owner || theme_owner_window) { + if (theme_owner && theme_owner->data.theme->has_default_font_size()) { + return theme_owner->data.theme->get_default_font_size(); } - sn.sort_custom<StringName::AlphCompare>(); - for (const StringName &name : sn) { - r_options->push_back(String(name).quote()); + if (theme_owner_window && theme_owner_window->theme->has_default_font_size()) { + return theme_owner_window->theme->get_default_font_size(); + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; + } } } + + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + if (Theme::get_project_default()->has_default_font_size()) { + return Theme::get_project_default()->get_default_font_size(); + } + } + + // Lastly, fall back on the default Theme. + if (Theme::get_default()->has_default_font_size()) { + return Theme::get_default()->get_default_font_size(); + } + return Theme::get_fallback_font_size(); } -TypedArray<String> Control::get_configuration_warnings() const { - TypedArray<String> warnings = Node::get_configuration_warnings(); +int Control::get_theme_default_font_size() const { + return fetch_theme_default_font_size(data.theme_owner, data.theme_owner_window); +} - if (data.mouse_filter == MOUSE_FILTER_IGNORE && !data.tooltip.is_empty()) { - warnings.push_back(RTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\".")); +/// Bulk actions. + +void Control::begin_bulk_theme_override() { + data.bulk_theme_override = true; +} + +void Control::end_bulk_theme_override() { + ERR_FAIL_COND(!data.bulk_theme_override); + + data.bulk_theme_override = false; + _notify_theme_changed(); +} + +// Internationalization. + +Array Control::structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const { + if (p_parser_type == TextServer::STRUCTURED_TEXT_CUSTOM) { + Array ret; + if (GDVIRTUAL_CALL(_structured_text_parser, p_args, p_text, ret)) { + return ret; + } else { + return Array(); + } + } else { + return TS->parse_structured_text(p_parser_type, p_args, p_text); } +} - return warnings; +void Control::set_layout_direction(Control::LayoutDirection p_direction) { + ERR_FAIL_INDEX((int)p_direction, 4); + + data.layout_dir = p_direction; + data.is_rtl_dirty = true; + + propagate_notification(NOTIFICATION_LAYOUT_DIRECTION_CHANGED); } -void Control::set_clip_contents(bool p_clip) { - data.clip_contents = p_clip; - update(); +Control::LayoutDirection Control::get_layout_direction() const { + return data.layout_dir; } -bool Control::is_clipping_contents() { - return data.clip_contents; +bool Control::is_layout_rtl() const { + if (data.is_rtl_dirty) { + const_cast<Control *>(this)->data.is_rtl_dirty = false; + if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) { + Window *parent_window = get_parent_window(); + Control *parent_control = get_parent_control(); + if (parent_control) { + const_cast<Control *>(this)->data.is_rtl = parent_control->is_layout_rtl(); + } else if (parent_window) { + const_cast<Control *>(this)->data.is_rtl = parent_window->is_layout_rtl(); + } else { + if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { + const_cast<Control *>(this)->data.is_rtl = true; + } else { + String locale = TranslationServer::get_singleton()->get_tool_locale(); + const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); + } + } + } else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) { + if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { + const_cast<Control *>(this)->data.is_rtl = true; + } else { + String locale = TranslationServer::get_singleton()->get_tool_locale(); + const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); + } + } else { + const_cast<Control *>(this)->data.is_rtl = (data.layout_dir == LAYOUT_DIRECTION_RTL); + } + } + return data.is_rtl; } -void Control::set_h_grow_direction(GrowDirection p_direction) { - ERR_FAIL_INDEX((int)p_direction, 3); +void Control::set_auto_translate(bool p_enable) { + if (p_enable == data.auto_translate) { + return; + } - data.h_grow = p_direction; - _size_changed(); + data.auto_translate = p_enable; + + notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); } -Control::GrowDirection Control::get_h_grow_direction() const { - return data.h_grow; +bool Control::is_auto_translating() const { + return data.auto_translate; } -void Control::set_v_grow_direction(GrowDirection p_direction) { - ERR_FAIL_INDEX((int)p_direction, 3); +// Extra properties. - data.v_grow = p_direction; - _size_changed(); +void Control::set_tooltip(const String &p_tooltip) { + data.tooltip = p_tooltip; + update_configuration_warnings(); } -Control::GrowDirection Control::get_v_grow_direction() const { - return data.v_grow; +String Control::_get_tooltip() const { + return data.tooltip; +} + +String Control::get_tooltip(const Point2 &p_pos) const { + return data.tooltip; +} + +Control *Control::make_custom_tooltip(const String &p_text) const { + Object *ret = nullptr; + if (GDVIRTUAL_CALL(_make_custom_tooltip, p_text, ret)) { + return Object::cast_to<Control>(ret); + } + return nullptr; +} + +// Base object overrides. + +void Control::add_child_notify(Node *p_child) { + Control *child_c = Object::cast_to<Control>(p_child); + + if (child_c && child_c->data.theme.is_null() && (data.theme_owner || data.theme_owner_window)) { + _propagate_theme_changed(child_c, data.theme_owner, data.theme_owner_window); //need to propagate here, since many controls may require setting up stuff + } + + Window *child_w = Object::cast_to<Window>(p_child); + + if (child_w && child_w->theme.is_null() && (data.theme_owner || data.theme_owner_window)) { + _propagate_theme_changed(child_w, data.theme_owner, data.theme_owner_window); //need to propagate here, since many controls may require setting up stuff + } +} + +void Control::remove_child_notify(Node *p_child) { + Control *child_c = Object::cast_to<Control>(p_child); + + if (child_c && (child_c->data.theme_owner || child_c->data.theme_owner_window) && child_c->data.theme.is_null()) { + _propagate_theme_changed(child_c, nullptr, nullptr); + } + + Window *child_w = Object::cast_to<Window>(p_child); + + if (child_w && (child_w->theme_owner || child_w->theme_owner_window) && child_w->theme.is_null()) { + _propagate_theme_changed(child_w, nullptr, nullptr); + } +} + +void Control::_notification(int p_notification) { + switch (p_notification) { + case NOTIFICATION_POST_ENTER_TREE: { + data.minimum_size_valid = false; + data.is_rtl_dirty = true; + _size_changed(); + } break; + + case NOTIFICATION_EXIT_TREE: { + release_focus(); + get_viewport()->_gui_remove_control(this); + } break; + + case NOTIFICATION_READY: { +#ifdef DEBUG_ENABLED + connect("ready", callable_mp(this, &Control::_clear_size_warning), CONNECT_DEFERRED | CONNECT_ONESHOT); +#endif + } break; + + case NOTIFICATION_ENTER_CANVAS: { + data.parent = Object::cast_to<Control>(get_parent()); + data.parent_window = Object::cast_to<Window>(get_parent()); + data.is_rtl_dirty = true; + + if (data.theme.is_null()) { + if (data.parent && (data.parent->data.theme_owner || data.parent->data.theme_owner_window)) { + data.theme_owner = data.parent->data.theme_owner; + data.theme_owner_window = data.parent->data.theme_owner_window; + notification(NOTIFICATION_THEME_CHANGED); + } else if (data.parent_window && (data.parent_window->theme_owner || data.parent_window->theme_owner_window)) { + data.theme_owner = data.parent_window->theme_owner; + data.theme_owner_window = data.parent_window->theme_owner_window; + notification(NOTIFICATION_THEME_CHANGED); + } + } + + CanvasItem *node = this; + bool has_parent_control = false; + + while (!node->is_set_as_top_level()) { + CanvasItem *parent = Object::cast_to<CanvasItem>(node->get_parent()); + if (!parent) { + break; + } + + Control *parent_control = Object::cast_to<Control>(parent); + if (parent_control) { + has_parent_control = true; + break; + } + + node = parent; + } + + if (has_parent_control) { + // Do nothing, has a parent control. + } else { + // Is a regular root control or top_level. + Viewport *viewport = get_viewport(); + ERR_FAIL_COND(!viewport); + data.RI = viewport->_gui_add_root_control(this); + } + + data.parent_canvas_item = get_parent_item(); + + if (data.parent_canvas_item) { + data.parent_canvas_item->connect("item_rect_changed", callable_mp(this, &Control::_size_changed)); + } else { + // Connect viewport. + Viewport *viewport = get_viewport(); + ERR_FAIL_COND(!viewport); + viewport->connect("size_changed", callable_mp(this, &Control::_size_changed)); + } + } break; + + case NOTIFICATION_EXIT_CANVAS: { + if (data.parent_canvas_item) { + data.parent_canvas_item->disconnect("item_rect_changed", callable_mp(this, &Control::_size_changed)); + data.parent_canvas_item = nullptr; + } else if (!is_set_as_top_level()) { + //disconnect viewport + Viewport *viewport = get_viewport(); + ERR_FAIL_COND(!viewport); + viewport->disconnect("size_changed", callable_mp(this, &Control::_size_changed)); + } + + if (data.RI) { + get_viewport()->_gui_remove_root_control(data.RI); + data.RI = nullptr; + } + + data.parent = nullptr; + data.parent_canvas_item = nullptr; + data.parent_window = nullptr; + data.is_rtl_dirty = true; + } break; + + case NOTIFICATION_MOVED_IN_PARENT: { + // some parents need to know the order of the children to draw (like TabContainer) + // update if necessary + if (data.parent) { + data.parent->update(); + } + update(); + + if (data.RI) { + get_viewport()->_gui_set_root_order_dirty(); + } + } break; + + case NOTIFICATION_RESIZED: { + emit_signal(SceneStringNames::get_singleton()->resized); + } break; + + case NOTIFICATION_DRAW: { + _update_canvas_item_transform(); + RenderingServer::get_singleton()->canvas_item_set_custom_rect(get_canvas_item(), !data.disable_visibility_clip, Rect2(Point2(), get_size())); + RenderingServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), data.clip_contents); + } break; + + case NOTIFICATION_MOUSE_ENTER: { + emit_signal(SceneStringNames::get_singleton()->mouse_entered); + } break; + + case NOTIFICATION_MOUSE_EXIT: { + emit_signal(SceneStringNames::get_singleton()->mouse_exited); + } break; + + case NOTIFICATION_FOCUS_ENTER: { + emit_signal(SceneStringNames::get_singleton()->focus_entered); + update(); + } break; + + case NOTIFICATION_FOCUS_EXIT: { + emit_signal(SceneStringNames::get_singleton()->focus_exited); + update(); + } break; + + case NOTIFICATION_THEME_CHANGED: { + update_minimum_size(); + update(); + } break; + + case NOTIFICATION_VISIBILITY_CHANGED: { + if (!is_visible_in_tree()) { + if (get_viewport() != nullptr) { + get_viewport()->_gui_hide_control(this); + } + } else { + data.minimum_size_valid = false; + _update_minimum_size(); + _size_changed(); + } + } break; + + case NOTIFICATION_TRANSLATION_CHANGED: + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { + if (is_inside_tree()) { + data.is_rtl_dirty = true; + _size_changed(); + } + } break; + } } void Control::_bind_methods() { - //ClassDB::bind_method(D_METHOD("_window_resize_event"),&Control::_window_resize_event); ClassDB::bind_method(D_METHOD("_update_minimum_size"), &Control::_update_minimum_size); ClassDB::bind_method(D_METHOD("accept_event"), &Control::accept_event); diff --git a/scene/gui/control.h b/scene/gui/control.h index d9c29a9c87..9f17eccc3b 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -159,13 +159,16 @@ private: }; struct Data { - Point2 pos_cache; - Size2 size_cache; - Size2 minimum_size_cache; - bool minimum_size_valid = false; + // Global relations. - Size2 last_minimum_size; - bool updating_last_minimum_size = false; + List<Control *>::Element *RI = nullptr; + + Control *parent = nullptr; + Window *parent_window = nullptr; + CanvasItem *parent_canvas_item = nullptr; + ObjectID drag_owner; + + // Positioning and sizing. real_t offset[4] = { 0.0, 0.0, 0.0, 0.0 }; real_t anchor[4] = { ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN }; @@ -173,49 +176,51 @@ private: GrowDirection h_grow = GROW_DIRECTION_END; GrowDirection v_grow = GROW_DIRECTION_END; - LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED; - bool is_rtl_dirty = true; - bool is_rtl = false; - - bool auto_translate = true; - real_t rotation = 0.0; Vector2 scale = Vector2(1, 1); Vector2 pivot_offset; + + Point2 pos_cache; + Size2 size_cache; + Size2 minimum_size_cache; + bool minimum_size_valid = false; + + Size2 last_minimum_size; + bool updating_last_minimum_size = false; + bool block_minimum_size_adjust = false; + bool size_warning = true; + // Container sizing. + int h_size_flags = SIZE_FILL; int v_size_flags = SIZE_FILL; real_t expand = 1.0; Point2 custom_minimum_size; + // Input events and rendering. + MouseFilter mouse_filter = MOUSE_FILTER_STOP; bool force_pass_scroll_events = true; bool clip_contents = false; - - bool block_minimum_size_adjust = false; bool disable_visibility_clip = false; - Control *parent = nullptr; - ObjectID drag_owner; - Ref<Theme> theme; - Control *theme_owner = nullptr; - Window *theme_owner_window = nullptr; - Window *parent_window = nullptr; - StringName theme_type_variation; - - String tooltip; CursorShape default_cursor = CURSOR_ARROW; - List<Control *>::Element *RI = nullptr; - - CanvasItem *parent_canvas_item = nullptr; + // Focus. NodePath focus_neighbor[4]; NodePath focus_next; NodePath focus_prev; + // Theming. + + Ref<Theme> theme; + Control *theme_owner = nullptr; + Window *theme_owner_window = nullptr; + StringName theme_type_variation; + bool bulk_theme_override = false; Theme::ThemeIconMap icon_override; Theme::ThemeStyleMap style_override; @@ -224,50 +229,69 @@ private: Theme::ThemeColorMap color_override; Theme::ThemeConstantMap constant_override; + // Internationalization. + + LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED; + bool is_rtl_dirty = true; + bool is_rtl = false; + + bool auto_translate = true; + + // Extra properties. + + String tooltip; + } data; + // Dynamic properties. + static constexpr unsigned properties_managed_by_container_count = 12; static String properties_managed_by_container[properties_managed_by_container_count]; - void _window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, real_t p_min, real_t &r_closest_dist, Control **r_closest); - Control *_get_focus_neighbor(Side p_side, int p_count = 0); + // Global relations. + + friend class Viewport; + friend class Window; + + // Positioning and sizing. + + void _update_canvas_item_transform(); + Transform2D _get_internal_transform() const; void _set_anchor(Side p_side, real_t p_anchor); void _set_position(const Point2 &p_point); void _set_global_position(const Point2 &p_point); void _set_size(const Size2 &p_size); + void _compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]); + void _compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]); + void _set_layout_mode(LayoutMode p_mode); LayoutMode _get_layout_mode() const; - void _set_anchors_layout_preset(int p_preset); int _get_anchors_layout_preset() const; - void _theme_changed(); - void _notify_theme_changed(); - + void _update_minimum_size_cache(); void _update_minimum_size(); + void _size_changed(); void _clear_size_warning(); - void _compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]); - void _compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]); - - void _size_changed(); - String _get_tooltip() const; + // Input events. - void _override_changed(); + void _call_gui_input(const Ref<InputEvent> &p_event); - void _update_canvas_item_transform(); + // Focus. - Transform2D _get_internal_transform() const; + void _window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, real_t p_min, real_t &r_closest_dist, Control **r_closest); + Control *_get_focus_neighbor(Side p_side, int p_count = 0); - friend class Viewport; + // Theming. - void _call_gui_input(const Ref<InputEvent> &p_event); + void _theme_changed(); + void _theme_property_override_changed(); + void _notify_theme_changed(); - void _update_minimum_size_cache(); - friend class Window; static void _propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign = true); template <class T> @@ -275,24 +299,31 @@ private: static bool has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); _FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const; -protected: - virtual void add_child_notify(Node *p_child) override; - virtual void remove_child_notify(Node *p_child) override; + // Extra properties. - //virtual void _window_gui_input(InputEvent p_event); + String _get_tooltip() const; - virtual Array structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; +protected: + // Dynamic properties. bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; - virtual void _validate_property(PropertyInfo &property) const override; + // Internationalization. + + virtual Array structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; + + // Base object overrides. + + virtual void add_child_notify(Node *p_child) override; + virtual void remove_child_notify(Node *p_child) override; + void _notification(int p_notification); static void _bind_methods(); - //bind helpers + // Exposed virtual methods. GDVIRTUAL1RC(bool, _has_point, Vector2) GDVIRTUAL2RC(Array, _structured_text_parser, Array, String) @@ -307,8 +338,6 @@ protected: public: enum { - /* NOTIFICATION_DRAW=30, - NOTIFICATION_VISIBILITY_CHANGED=38*/ NOTIFICATION_RESIZED = 40, NOTIFICATION_MOUSE_ENTER = 41, NOTIFICATION_MOUSE_EXIT = 42, @@ -318,10 +347,11 @@ public: NOTIFICATION_SCROLL_BEGIN = 47, NOTIFICATION_SCROLL_END = 48, NOTIFICATION_LAYOUT_DIRECTION_CHANGED = 49, - }; - /* EDITOR */ + // Editor plugin interoperability. + + // TODO: Decouple controls from their editor plugin and get rid of this. #ifdef TOOLS_ENABLED virtual Dictionary _edit_get_state() const override; virtual void _edit_set_state(const Dictionary &p_state) override; @@ -347,56 +377,50 @@ public: virtual Size2 _edit_get_minimum_size() const override; #endif - virtual void gui_input(const Ref<InputEvent> &p_event); + // Editor integration. - void accept_event(); + virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override; + TypedArray<String> get_configuration_warnings() const override; - virtual Size2 get_minimum_size() const; - virtual Size2 get_combined_minimum_size() const; - virtual bool has_point(const Point2 &p_point) const; - virtual void set_drag_forwarding(Object *p_target); - virtual Variant get_drag_data(const Point2 &p_point); - virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const; - virtual void drop_data(const Point2 &p_point, const Variant &p_data); - void set_drag_preview(Control *p_control); - void force_drag(const Variant &p_data, Control *p_control); - bool is_drag_successful() const; + virtual bool is_text_field() const; - void set_custom_minimum_size(const Size2 &p_custom); - Size2 get_custom_minimum_size() const; + // Global relations. + + bool is_top_level_control() const; Control *get_parent_control() const; Window *get_parent_window() const; + Control *get_root_parent_control() const; - void set_layout_direction(LayoutDirection p_direction); - LayoutDirection get_layout_direction() const; - virtual bool is_layout_rtl() const; - - void set_auto_translate(bool p_enable); - bool is_auto_translating() const; - _FORCE_INLINE_ String atr(const String p_string) const { return is_auto_translating() ? tr(p_string) : p_string; }; + Size2 get_parent_area_size() const; + Rect2 get_parent_anchorable_rect() const; - /* POSITIONING */ + // Positioning and sizing. - void set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets = true); - void set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0); - void set_anchors_and_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0); - void set_grow_direction_preset(LayoutPreset p_preset); + virtual Transform2D get_transform() const override; void set_anchor(Side p_side, real_t p_anchor, bool p_keep_offset = true, bool p_push_opposite_anchor = true); real_t get_anchor(Side p_side) const; - void set_offset(Side p_side, real_t p_value); real_t get_offset(Side p_side) const; - void set_anchor_and_offset(Side p_side, real_t p_anchor, real_t p_pos, bool p_push_opposite_anchor = true); - void set_begin(const Point2 &p_point); // helper - void set_end(const Point2 &p_point); // helper - + // TODO: Rename to set_begin/end_offsets ? + void set_begin(const Point2 &p_point); Point2 get_begin() const; + void set_end(const Point2 &p_point); Point2 get_end() const; + void set_h_grow_direction(GrowDirection p_direction); + GrowDirection get_h_grow_direction() const; + void set_v_grow_direction(GrowDirection p_direction); + GrowDirection get_v_grow_direction() const; + + void set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets = true); + void set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0); + void set_anchors_and_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0); + void set_grow_direction_preset(LayoutPreset p_preset); + void set_position(const Point2 &p_point, bool p_keep_offsets = false); void set_global_position(const Point2 &p_point, bool p_keep_offsets = false); Point2 get_position() const; @@ -407,52 +431,72 @@ public: Size2 get_size() const; void reset_size(); + void set_rect(const Rect2 &p_rect); // Reset anchors to begin and set rect, for faster container children sorting. Rect2 get_rect() const; Rect2 get_global_rect() const; Rect2 get_screen_rect() const; Rect2 get_window_rect() const; ///< use with care, as it blocks waiting for the rendering server Rect2 get_anchorable_rect() const override; - void set_rect(const Rect2 &p_rect); // Reset anchors to begin and set rect, for faster container children sorting. - + void set_scale(const Vector2 &p_scale); + Vector2 get_scale() const; void set_rotation(real_t p_radians); real_t get_rotation() const; - - void set_h_grow_direction(GrowDirection p_direction); - GrowDirection get_h_grow_direction() const; - - void set_v_grow_direction(GrowDirection p_direction); - GrowDirection get_v_grow_direction() const; - void set_pivot_offset(const Vector2 &p_pivot); Vector2 get_pivot_offset() const; - void set_scale(const Vector2 &p_scale); - Vector2 get_scale() const; + void update_minimum_size(); - void set_theme(const Ref<Theme> &p_theme); - Ref<Theme> get_theme() const; + void set_block_minimum_size_adjust(bool p_block); + bool is_minimum_size_adjust_blocked() const; - void set_theme_type_variation(const StringName &p_theme_type); - StringName get_theme_type_variation() const; + virtual Size2 get_minimum_size() const; + virtual Size2 get_combined_minimum_size() const; + + void set_custom_minimum_size(const Size2 &p_custom); + Size2 get_custom_minimum_size() const; + + // Container sizing. void set_h_size_flags(int p_flags); int get_h_size_flags() const; - void set_v_size_flags(int p_flags); int get_v_size_flags() const; - void set_stretch_ratio(real_t p_ratio); real_t get_stretch_ratio() const; - void update_minimum_size(); + // Input events. - /* FOCUS */ + virtual void gui_input(const Ref<InputEvent> &p_event); + void accept_event(); + + virtual bool has_point(const Point2 &p_point) const; + + void set_mouse_filter(MouseFilter p_filter); + MouseFilter get_mouse_filter() const; + + void set_force_pass_scroll_events(bool p_force_pass_scroll_events); + bool is_force_pass_scroll_events() const; + + void warp_mouse(const Point2 &p_position); + + // Drag and drop handling. + + virtual void set_drag_forwarding(Object *p_target); + virtual Variant get_drag_data(const Point2 &p_point); + virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const; + virtual void drop_data(const Point2 &p_point, const Variant &p_data); + void set_drag_preview(Control *p_control); + void force_drag(const Variant &p_data, Control *p_control); + bool is_drag_successful() const; + + // Focus. void set_focus_mode(FocusMode p_focus_mode); FocusMode get_focus_mode() const; bool has_focus() const; void grab_focus(); + void grab_click_focus(); void release_focus(); Control *find_next_valid_focus() const; @@ -466,13 +510,25 @@ public: void set_focus_previous(const NodePath &p_prev); NodePath get_focus_previous() const; - void set_mouse_filter(MouseFilter p_filter); - MouseFilter get_mouse_filter() const; + // Rendering. - void set_force_pass_scroll_events(bool p_force_pass_scroll_events); - bool is_force_pass_scroll_events() const; + void set_default_cursor_shape(CursorShape p_shape); + CursorShape get_default_cursor_shape() const; + virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const; + + void set_clip_contents(bool p_clip); + bool is_clipping_contents(); - /* SKINNING */ + void set_disable_visibility_clip(bool p_ignore); + bool is_visibility_clip_disabled() const; + + // Theming. + + void set_theme(const Ref<Theme> &p_theme); + Ref<Theme> get_theme() const; + + void set_theme_type_variation(const StringName &p_theme_type); + StringName get_theme_type_variation() const; void begin_bulk_theme_override(); void end_bulk_theme_override(); @@ -520,44 +576,23 @@ public: Ref<Font> get_theme_default_font() const; int get_theme_default_font_size() const; - /* TOOLTIP */ + // Internationalization. - void set_tooltip(const String &p_tooltip); - virtual String get_tooltip(const Point2 &p_pos) const; - virtual Control *make_custom_tooltip(const String &p_text) const; - - /* CURSOR */ - - void set_default_cursor_shape(CursorShape p_shape); - CursorShape get_default_cursor_shape() const; - virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const; - - virtual Transform2D get_transform() const override; - - bool is_top_level_control() const; - - Size2 get_parent_area_size() const; - Rect2 get_parent_anchorable_rect() const; - - void grab_click_focus(); - - void warp_mouse(const Point2 &p_position); - - virtual bool is_text_field() const; - - Control *get_root_parent_control() const; - - void set_clip_contents(bool p_clip); - bool is_clipping_contents(); + void set_layout_direction(LayoutDirection p_direction); + LayoutDirection get_layout_direction() const; + virtual bool is_layout_rtl() const; - void set_block_minimum_size_adjust(bool p_block); - bool is_minimum_size_adjust_blocked() const; + void set_auto_translate(bool p_enable); + bool is_auto_translating() const; + _FORCE_INLINE_ String atr(const String p_string) const { + return is_auto_translating() ? tr(p_string) : p_string; + }; - void set_disable_visibility_clip(bool p_ignore); - bool is_visibility_clip_disabled() const; + // Extra properties. - virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override; - TypedArray<String> get_configuration_warnings() const override; + void set_tooltip(const String &p_tooltip); + virtual String get_tooltip(const Point2 &p_pos) const; + virtual Control *make_custom_tooltip(const String &p_text) const; Control() {} }; diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 44e2bb89eb..942b7d0bf9 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -261,7 +261,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin } if (!p_action.is_empty()) { - button->connect("pressed", callable_mp(this, &AcceptDialog::_custom_action), varray(p_action)); + button->connect("pressed", callable_mp(this, &AcceptDialog::_custom_action).bind(p_action)); } return button; diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 65bc359e2e..e26976a402 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -1083,9 +1083,9 @@ FileDialog::FileDialog() { _update_drives(); connect("confirmed", callable_mp(this, &FileDialog::_action_pressed)); - tree->connect("multi_selected", callable_mp(this, &FileDialog::_tree_multi_selected), varray(), CONNECT_DEFERRED); - tree->connect("cell_selected", callable_mp(this, &FileDialog::_tree_selected), varray(), CONNECT_DEFERRED); - tree->connect("item_activated", callable_mp(this, &FileDialog::_tree_item_activated), varray()); + tree->connect("multi_selected", callable_mp(this, &FileDialog::_tree_multi_selected), CONNECT_DEFERRED); + tree->connect("cell_selected", callable_mp(this, &FileDialog::_tree_selected), CONNECT_DEFERRED); + tree->connect("item_activated", callable_mp(this, &FileDialog::_tree_item_activated)); tree->connect("nothing_selected", callable_mp(this, &FileDialog::deselect_all)); dir->connect("text_submitted", callable_mp(this, &FileDialog::_dir_submitted)); file->connect("text_submitted", callable_mp(this, &FileDialog::_file_submitted)); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index e30759aa3e..09efee71a3 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -382,9 +382,9 @@ void GraphEdit::add_child_notify(Node *p_child) { GraphNode *gn = Object::cast_to<GraphNode>(p_child); if (gn) { gn->set_scale(Vector2(zoom, zoom)); - gn->connect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved), varray(gn)); - gn->connect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated), varray(gn)); - gn->connect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised), varray(gn)); + gn->connect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved).bind(gn)); + gn->connect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated).bind(gn)); + gn->connect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised).bind(gn)); gn->connect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::update)); gn->connect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::update)); _graph_node_moved(gn); @@ -710,6 +710,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { int type = gn->get_connection_output_type(j); if ((type == connecting_type || valid_connection_types.has(ConnType(connecting_type, type))) && is_in_output_hotzone(gn, j, mpos, port_size)) { + if (!is_node_hover_valid(gn->get_name(), j, connecting_from, connecting_index)) { + continue; + } connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); @@ -725,6 +728,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { int type = gn->get_connection_input_type(j); if ((type == connecting_type || valid_connection_types.has(ConnType(connecting_type, type))) && is_in_input_hotzone(gn, j, mpos, port_size)) { + if (!is_node_hover_valid(connecting_from, connecting_index, gn->get_name(), j)) { + continue; + } connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); @@ -1453,6 +1459,14 @@ void GraphEdit::force_connection_drag_end() { emit_signal(SNAME("connection_drag_ended")); } +bool GraphEdit::is_node_hover_valid(const StringName &p_from, const int p_from_port, const StringName &p_to, const int p_to_port) { + bool valid; + if (GDVIRTUAL_CALL(_is_node_hover_valid, p_from, p_from_port, p_to, p_to_port, valid)) { + return valid; + } + return true; +} + void GraphEdit::set_panning_scheme(PanningScheme p_scheme) { panning_scheme = p_scheme; panner->set_control_scheme((ViewPanner::ControlScheme)p_scheme); @@ -1809,7 +1823,20 @@ HashMap<int, Vector<StringName>> GraphEdit::_layering(const HashSet<StringName> } if (!selected) { current_layer++; + uint32_t previous_size_z = z.size(); _set_operations(GraphEdit::UNION, z, u); + if (z.size() == previous_size_z) { + WARN_PRINT("Graph contains cycle(s). The cycle(s) will not be rearranged accurately."); + Vector<StringName> t; + if (l.has(0)) { + t.append_array(l[0]); + } + for (const StringName &E : p) { + t.push_back(E); + } + l.insert(0, t); + break; + } } selected = false; } @@ -2124,7 +2151,7 @@ void GraphEdit::arrange_nodes() { HashSet<StringName> s; for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { GraphNode *p_from = Object::cast_to<GraphNode>(node_names[E->get().from]); - if (E->get().to == gn->get_name() && p_from->is_selected()) { + if (E->get().to == gn->get_name() && p_from->is_selected() && E->get().to != E->get().from) { if (!s.has(p_from->get_name())) { s.insert(p_from->get_name()); } @@ -2315,6 +2342,7 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_selected", "node"), &GraphEdit::set_selected); GDVIRTUAL_BIND(_get_connection_line, "from", "to") + GDVIRTUAL_BIND(_is_node_hover_valid, "from", "from_slot", "to", "to_slot"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "right_disconnects"), "set_right_disconnects", "is_right_disconnects_enabled"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_scroll_ofs", "get_scroll_ofs"); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index beb17ec4cf..cf35aeb8b2 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -280,6 +280,7 @@ protected: GDVIRTUAL2RC(Vector<Vector2>, _get_connection_line, Vector2, Vector2) GDVIRTUAL3R(bool, _is_in_input_hotzone, Object *, int, Vector2) GDVIRTUAL3R(bool, _is_in_output_hotzone, Object *, int, Vector2) + GDVIRTUAL4R(bool, _is_node_hover_valid, StringName, int, StringName, int); public: Error connect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port); @@ -287,6 +288,7 @@ public: void disconnect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port); void clear_connections(); void force_connection_drag_end(); + virtual bool is_node_hover_valid(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port); void set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 92016ca42e..112b8c74af 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -450,7 +450,7 @@ void GraphNode::_validate_property(PropertyInfo &property) const { Control::_validate_property(property); GraphEdit *graph = Object::cast_to<GraphEdit>(get_parent()); if (graph) { - if (property.name == "rect_position") { + if (property.name == "position") { property.usage |= PROPERTY_USAGE_READ_ONLY; } } @@ -1051,6 +1051,7 @@ void GraphNode::_bind_methods() { ADD_GROUP("BiDi", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language"); + ADD_GROUP("", ""); ADD_SIGNAL(MethodInfo("position_offset_changed")); ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "idx"))); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 8094812203..e7f48beb00 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -657,7 +657,7 @@ void Label::set_label_settings(const Ref<LabelSettings> &p_settings) { } settings = p_settings; if (settings.is_valid()) { - settings->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate), varray(), CONNECT_REFERENCE_COUNTED); + settings->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate), CONNECT_REFERENCE_COUNTED); } _invalidate(); } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 39f8f23cd8..f315b2bbf1 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -1513,9 +1513,9 @@ void LineEdit::clear() { void LineEdit::show_virtual_keyboard() { if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) { if (selection.enabled) { - DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end); + DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), DisplayServer::VirtualKeyboardType(virtual_keyboard_type), max_length, selection.begin, selection.end); } else { - DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, caret_column); + DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), DisplayServer::VirtualKeyboardType(virtual_keyboard_type), max_length, caret_column); } } } @@ -2040,6 +2040,14 @@ bool LineEdit::is_virtual_keyboard_enabled() const { return virtual_keyboard_enabled; } +void LineEdit::set_virtual_keyboard_type(VirtualKeyboardType p_type) { + virtual_keyboard_type = p_type; +} + +LineEdit::VirtualKeyboardType LineEdit::get_virtual_keyboard_type() const { + return virtual_keyboard_type; +} + void LineEdit::set_middle_mouse_paste_enabled(bool p_enabled) { middle_mouse_paste_enabled = p_enabled; } @@ -2280,6 +2288,8 @@ void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_context_menu_enabled"), &LineEdit::is_context_menu_enabled); ClassDB::bind_method(D_METHOD("set_virtual_keyboard_enabled", "enable"), &LineEdit::set_virtual_keyboard_enabled); ClassDB::bind_method(D_METHOD("is_virtual_keyboard_enabled"), &LineEdit::is_virtual_keyboard_enabled); + ClassDB::bind_method(D_METHOD("set_virtual_keyboard_type", "type"), &LineEdit::set_virtual_keyboard_type); + ClassDB::bind_method(D_METHOD("get_virtual_keyboard_type"), &LineEdit::get_virtual_keyboard_type); ClassDB::bind_method(D_METHOD("set_clear_button_enabled", "enable"), &LineEdit::set_clear_button_enabled); ClassDB::bind_method(D_METHOD("is_clear_button_enabled"), &LineEdit::is_clear_button_enabled); ClassDB::bind_method(D_METHOD("set_shortcut_keys_enabled", "enable"), &LineEdit::set_shortcut_keys_enabled); @@ -2329,6 +2339,15 @@ void LineEdit::_bind_methods() { BIND_ENUM_CONSTANT(MENU_INSERT_SHY); BIND_ENUM_CONSTANT(MENU_MAX); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_DEFAULT); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_MULTILINE); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_NUMBER); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_NUMBER_DECIMAL); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_PHONE); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_EMAIL_ADDRESS); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_PASSWORD); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_URL); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder"); ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment"); @@ -2339,6 +2358,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand_to_text_length"), "set_expand_to_text_length_enabled", "is_expand_to_text_length_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_keyboard_enabled"), "set_virtual_keyboard_enabled", "is_virtual_keyboard_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "virtual_keyboard_type", PROPERTY_HINT_ENUM, "Default,Multiline,Number,Decimal,Phone,Email,Password,URL"), "set_virtual_keyboard_type", "get_virtual_keyboard_type"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clear_button_enabled"), "set_clear_button_enabled", "is_clear_button_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "middle_mouse_paste_enabled"), "set_middle_mouse_paste_enabled", "is_middle_mouse_paste_enabled"); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 6aa1694f1f..a828479b0c 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -70,6 +70,17 @@ public: MENU_MAX }; + enum VirtualKeyboardType { + KEYBOARD_TYPE_DEFAULT, + KEYBOARD_TYPE_MULTILINE, + KEYBOARD_TYPE_NUMBER, + KEYBOARD_TYPE_NUMBER_DECIMAL, + KEYBOARD_TYPE_PHONE, + KEYBOARD_TYPE_EMAIL_ADDRESS, + KEYBOARD_TYPE_PASSWORD, + KEYBOARD_TYPE_URL + }; + private: HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT; @@ -120,6 +131,7 @@ private: bool shortcut_keys_enabled = true; bool virtual_keyboard_enabled = true; + VirtualKeyboardType virtual_keyboard_type = KEYBOARD_TYPE_DEFAULT; bool middle_mouse_paste_enabled = true; @@ -311,6 +323,9 @@ public: void set_virtual_keyboard_enabled(bool p_enable); bool is_virtual_keyboard_enabled() const; + void set_virtual_keyboard_type(VirtualKeyboardType p_type); + VirtualKeyboardType get_virtual_keyboard_type() const; + void set_middle_mouse_paste_enabled(bool p_enabled); bool is_middle_mouse_paste_enabled() const; @@ -335,5 +350,6 @@ public: }; VARIANT_ENUM_CAST(LineEdit::MenuItems); +VARIANT_ENUM_CAST(LineEdit::VirtualKeyboardType); #endif // LINE_EDIT_H diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 316fee53fe..069a31d9d2 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -239,8 +239,8 @@ MenuButton::MenuButton(const String &p_text) : popup = memnew(PopupMenu); popup->hide(); add_child(popup, false, INTERNAL_MODE_FRONT); - popup->connect("about_to_popup", callable_mp(this, &MenuButton::_popup_visibility_changed), varray(true)); - popup->connect("popup_hide", callable_mp(this, &MenuButton::_popup_visibility_changed), varray(false)); + popup->connect("about_to_popup", callable_mp(this, &MenuButton::_popup_visibility_changed).bind(true)); + popup->connect("popup_hide", callable_mp(this, &MenuButton::_popup_visibility_changed).bind(false)); } MenuButton::~MenuButton() { diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index a86f2bdbc1..c58513df17 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -35,7 +35,12 @@ static const int NONE_SELECTED = -1; Size2 OptionButton::get_minimum_size() const { - Size2 minsize = Button::get_minimum_size(); + Size2 minsize; + if (fit_to_longest_item) { + minsize = _cached_size; + } else { + minsize = Button::get_minimum_size(); + } if (has_theme_icon(SNAME("arrow"))) { const Size2 padding = get_theme_stylebox(SNAME("normal"))->get_minimum_size(); @@ -107,6 +112,7 @@ void OptionButton::_notification(int p_what) { _set_internal_margin(SIDE_RIGHT, Control::get_theme_icon(SNAME("arrow"))->get_width()); } } + _refresh_size_cache(); } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -135,6 +141,10 @@ bool OptionButton::_set(const StringName &p_name, const Variant &p_value) { _select(idx, false); } + if (property == "text" || property == "icon") { + _queue_refresh_cache(); + } + return valid; } return false; @@ -208,6 +218,7 @@ void OptionButton::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_l if (first_selectable) { select(get_item_count() - 1); } + _queue_refresh_cache(); } void OptionButton::add_item(const String &p_label, int p_id) { @@ -216,6 +227,7 @@ void OptionButton::add_item(const String &p_label, int p_id) { if (first_selectable) { select(get_item_count() - 1); } + _queue_refresh_cache(); } void OptionButton::set_item_text(int p_idx, const String &p_text) { @@ -224,6 +236,7 @@ void OptionButton::set_item_text(int p_idx, const String &p_text) { if (current == p_idx) { set_text(p_text); } + _queue_refresh_cache(); } void OptionButton::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) { @@ -232,6 +245,7 @@ void OptionButton::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) { if (current == p_idx) { set_icon(p_icon); } + _queue_refresh_cache(); } void OptionButton::set_item_id(int p_idx, int p_id) { @@ -301,6 +315,7 @@ void OptionButton::set_item_count(int p_count) { } } + _refresh_size_cache(); notify_property_list_changed(); } @@ -333,6 +348,19 @@ int OptionButton::get_item_count() const { return popup->get_item_count(); } +void OptionButton::set_fit_to_longest_item(bool p_fit) { + if (p_fit == fit_to_longest_item) { + return; + } + fit_to_longest_item = p_fit; + + _refresh_size_cache(); +} + +bool OptionButton::is_fit_to_longest_item() const { + return fit_to_longest_item; +} + void OptionButton::add_separator(const String &p_text) { popup->add_separator(p_text); } @@ -341,6 +369,7 @@ void OptionButton::clear() { popup->clear(); set_text(""); current = NONE_SELECTED; + _refresh_size_cache(); } void OptionButton::_select(int p_which, bool p_emit) { @@ -380,6 +409,29 @@ void OptionButton::_select_int(int p_which) { _select(p_which, false); } +void OptionButton::_refresh_size_cache() { + cache_refresh_pending = false; + + if (!fit_to_longest_item) { + return; + } + + _cached_size = Vector2(); + for (int i = 0; i < get_item_count(); i++) { + _cached_size = _cached_size.max(get_minimum_size_for_text_and_icon(get_item_text(i), get_item_icon(i))); + } + update_minimum_size(); +} + +void OptionButton::_queue_refresh_cache() { + if (cache_refresh_pending) { + return; + } + cache_refresh_pending = true; + + callable_mp(this, &OptionButton::_refresh_size_cache).call_deferredp(nullptr, 0); +} + void OptionButton::select(int p_idx) { _select(p_idx, false); } @@ -405,6 +457,7 @@ void OptionButton::remove_item(int p_idx) { if (current == p_idx) { _select(NONE_SELECTED); } + _queue_refresh_cache(); } PopupMenu *OptionButton::get_popup() const { @@ -453,10 +506,13 @@ void OptionButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_count"), &OptionButton::get_item_count); ClassDB::bind_method(D_METHOD("has_selectable_items"), &OptionButton::has_selectable_items); ClassDB::bind_method(D_METHOD("get_selectable_item", "from_last"), &OptionButton::get_selectable_item, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("set_fit_to_longest_item", "fit"), &OptionButton::set_fit_to_longest_item); + ClassDB::bind_method(D_METHOD("is_fit_to_longest_item"), &OptionButton::is_fit_to_longest_item); // "selected" property must come after "item_count", otherwise GH-10213 occurs. ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "popup/item_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "selected"), "_select_int", "get_selected"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fit_to_longest_item"), "set_fit_to_longest_item", "is_fit_to_longest_item"); ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "index"))); ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "index"))); } @@ -481,7 +537,8 @@ OptionButton::OptionButton(const String &p_text) : add_child(popup, false, INTERNAL_MODE_FRONT); popup->connect("index_pressed", callable_mp(this, &OptionButton::_selected)); popup->connect("id_focused", callable_mp(this, &OptionButton::_focused)); - popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(false)); + popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed).bind(false)); + _refresh_size_cache(); } OptionButton::~OptionButton() { diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 5665296699..49b5eee910 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -39,11 +39,16 @@ class OptionButton : public Button { PopupMenu *popup = nullptr; int current = -1; + bool fit_to_longest_item = true; + Vector2 _cached_size; + bool cache_refresh_pending = false; void _focused(int p_which); void _selected(int p_which); void _select(int p_which, bool p_emit = false); void _select_int(int p_which); + void _refresh_size_cache(); + void _queue_refresh_cache(); virtual void pressed() override; @@ -85,6 +90,8 @@ public: void set_item_count(int p_count); int get_item_count() const; + void set_fit_to_longest_item(bool p_fit); + bool is_fit_to_longest_item() const; void add_separator(const String &p_text = ""); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 8e424977c4..984f20ee58 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -821,17 +821,18 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o off.y += line_spacing; } - RID rid = l.text_buf->get_line_rid(line); if (p_ofs.y + off.y >= ctrl_size.height) { break; } - if (p_ofs.y + off.y + TS->shaped_text_get_size(rid).y <= 0) { - off.y += TS->shaped_text_get_size(rid).y; + + const Size2 line_size = l.text_buf->get_line_size(line); + if (p_ofs.y + off.y + line_size.y <= 0) { + off.y += line_size.y; continue; } float width = l.text_buf->get_width(); - float length = TS->shaped_text_get_width(rid); + float length = line_size.x; // Draw line. line_count++; @@ -874,6 +875,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } } + RID rid = l.text_buf->get_line_rid(line); //draw_rect(Rect2(p_ofs + off, TS->shaped_text_get_size(rid)), Color(1,0,0), false, 2); //DEBUG_RECTS off.y += TS->shaped_text_get_ascent(rid); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index f387f91a8b..48c57d9b1b 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -303,7 +303,7 @@ void ScrollBar::_notification(int p_what) { if (drag_node) { drag_node->connect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); - drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), varray(), CONNECT_ONESHOT); + drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONESHOT); } } break; @@ -595,7 +595,7 @@ void ScrollBar::set_drag_node(const NodePath &p_path) { if (drag_node) { drag_node->connect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); - drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), varray(), CONNECT_ONESHOT); + drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONESHOT); } } } diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 9efab27e3a..8fd547813d 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -37,7 +37,10 @@ Size2 ScrollContainer::get_minimum_size() const { Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg")); Size2 min_size; - Size2 content_min_size; + + // Calculated in this function, as it needs to traverse all child controls once to calculate; + // and needs to be calculated before being used by update_scrollbars(). + largest_child_min_size = Size2(); for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); @@ -50,25 +53,27 @@ Size2 ScrollContainer::get_minimum_size() const { if (c == h_scroll || c == v_scroll) { continue; } - Size2 minsize = c->get_combined_minimum_size(); - content_min_size.x = MAX(content_min_size.x, minsize.x); - content_min_size.y = MAX(content_min_size.y, minsize.y); + Size2 child_min_size = c->get_combined_minimum_size(); + + largest_child_min_size.x = MAX(largest_child_min_size.x, child_min_size.x); + largest_child_min_size.y = MAX(largest_child_min_size.y, child_min_size.y); } if (horizontal_scroll_mode == SCROLL_MODE_DISABLED) { - min_size.x = MAX(min_size.x, content_min_size.x); + min_size.x = MAX(min_size.x, largest_child_min_size.x); } if (vertical_scroll_mode == SCROLL_MODE_DISABLED) { - min_size.y = MAX(min_size.y, content_min_size.y); + min_size.y = MAX(min_size.y, largest_child_min_size.y); } - bool h_scroll_show = horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (horizontal_scroll_mode == SCROLL_MODE_AUTO && content_min_size.x > min_size.x); - bool v_scroll_show = vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (vertical_scroll_mode == SCROLL_MODE_AUTO && content_min_size.y > min_size.y); - if (h_scroll_show) { + bool h_scroll_show = horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (horizontal_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.x > min_size.x); + bool v_scroll_show = vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (vertical_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.y > min_size.y); + + if (h_scroll_show && h_scroll->get_parent() == this) { min_size.y += h_scroll->get_minimum_size().y; } - if (v_scroll_show) { + if (v_scroll_show && v_scroll->get_parent() == this) { min_size.x += v_scroll->get_minimum_size().x; } @@ -261,8 +266,8 @@ void ScrollContainer::ensure_control_visible(Control *p_control) { set_v_scroll(get_v_scroll() + (diff.y - global_rect.position.y)); } -void ScrollContainer::_update_dimensions() { - child_max_size = Size2(0, 0); +void ScrollContainer::_reposition_children() { + update_scrollbars(); Size2 size = get_size(); Point2 ofs; @@ -291,25 +296,13 @@ void ScrollContainer::_update_dimensions() { continue; } Size2 minsize = c->get_combined_minimum_size(); - child_max_size.x = MAX(child_max_size.x, minsize.x); - child_max_size.y = MAX(child_max_size.y, minsize.y); Rect2 r = Rect2(-Size2(get_h_scroll(), get_v_scroll()), minsize); - if (horizontal_scroll_mode == SCROLL_MODE_DISABLED || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) { - r.position.x = 0; - if (c->get_h_size_flags() & SIZE_EXPAND) { - r.size.width = MAX(size.width, minsize.width); - } else { - r.size.width = minsize.width; - } + if (c->get_h_size_flags() & SIZE_EXPAND) { + r.size.width = MAX(size.width, minsize.width); } - if (vertical_scroll_mode == SCROLL_MODE_DISABLED || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) { - r.position.y = 0; - if (c->get_v_size_flags() & SIZE_EXPAND) { - r.size.height = MAX(size.height, minsize.height); - } else { - r.size.height = minsize.height; - } + if (c->get_v_size_flags() & SIZE_EXPAND) { + r.size.height = MAX(size.height, minsize.height); } r.position += ofs; if (rtl && v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) { @@ -319,7 +312,6 @@ void ScrollContainer::_update_dimensions() { fit_child_in_rect(c, r); } - update_scrollbars(); update(); } @@ -337,18 +329,16 @@ void ScrollContainer::_notification(int p_what) { Viewport *viewport = get_viewport(); ERR_FAIL_COND(!viewport); viewport->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_gui_focus_changed)); - _update_dimensions(); + _reposition_children(); } break; case NOTIFICATION_SORT_CHILDREN: { - _update_dimensions(); + _reposition_children(); } break; case NOTIFICATION_DRAW: { Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg")); draw_style_box(sb, Rect2(Vector2(), get_size())); - - update_scrollbars(); } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { @@ -426,36 +416,25 @@ void ScrollContainer::update_scrollbars() { Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg")); size -= sb->get_minimum_size(); - Size2 hmin; - Size2 vmin; - if (horizontal_scroll_mode != SCROLL_MODE_DISABLED) { - hmin = h_scroll->get_combined_minimum_size(); - } - if (vertical_scroll_mode != SCROLL_MODE_DISABLED) { - vmin = v_scroll->get_combined_minimum_size(); - } - - Size2 min = child_max_size; + Size2 hmin = h_scroll->get_combined_minimum_size(); + Size2 vmin = v_scroll->get_combined_minimum_size(); - bool hide_scroll_h = horizontal_scroll_mode != SCROLL_MODE_SHOW_ALWAYS && (horizontal_scroll_mode == SCROLL_MODE_DISABLED || horizontal_scroll_mode == SCROLL_MODE_SHOW_NEVER || (horizontal_scroll_mode == SCROLL_MODE_AUTO && min.width <= size.width)); - bool hide_scroll_v = vertical_scroll_mode != SCROLL_MODE_SHOW_ALWAYS && (vertical_scroll_mode == SCROLL_MODE_DISABLED || vertical_scroll_mode == SCROLL_MODE_SHOW_NEVER || (vertical_scroll_mode == SCROLL_MODE_AUTO && min.height <= size.height)); + h_scroll->set_visible(horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (horizontal_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.width > size.width)); + v_scroll->set_visible(vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (vertical_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.height > size.height)); - h_scroll->set_max(min.width); - h_scroll->set_page(size.width - (hide_scroll_v ? 0 : vmin.width)); - h_scroll->set_visible(!hide_scroll_h); + h_scroll->set_max(largest_child_min_size.width); + h_scroll->set_page((v_scroll->is_visible() && v_scroll->get_parent() == this) ? size.width - vmin.width : size.width); - v_scroll->set_max(min.height); - v_scroll->set_page(size.height - (hide_scroll_h ? 0 : hmin.height)); - v_scroll->set_visible(!hide_scroll_v); + v_scroll->set_max(largest_child_min_size.height); + v_scroll->set_page((h_scroll->is_visible() && h_scroll->get_parent() == this) ? size.height - hmin.height : size.height); // Avoid scrollbar overlapping. - h_scroll->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, hide_scroll_v ? 0 : -vmin.width); - v_scroll->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, hide_scroll_h ? 0 : -hmin.height); + h_scroll->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, (v_scroll->is_visible() && v_scroll->get_parent() == this) ? -vmin.width : 0); + v_scroll->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, (h_scroll->is_visible() && h_scroll->get_parent() == this) ? -hmin.height : 0); } void ScrollContainer::_scroll_moved(float) { queue_sort(); - update(); }; void ScrollContainer::set_h_scroll(int p_pos) { diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index 7c8690538d..bfa74cfd0f 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -50,7 +50,7 @@ private: HScrollBar *h_scroll = nullptr; VScrollBar *v_scroll = nullptr; - Size2 child_max_size; + mutable Size2 largest_child_min_size; // The largest one among the min sizes of all available child controls. void update_scrollbars(); @@ -75,7 +75,7 @@ protected: Size2 get_minimum_size() const override; void _gui_focus_changed(Control *p_control); - void _update_dimensions(); + void _reposition_children(); void _notification(int p_what); void _scroll_moved(float); diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index a4733c455f..8a7f52b0d9 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -88,7 +88,8 @@ void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) { void SpinBox::_range_click_timeout() { if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) { bool up = get_local_mouse_position().y < (get_size().height / 2); - set_value(get_value() + (up ? get_step() : -get_step())); + double step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step(); + set_value(get_value() + (up ? step : -step)); if (range_click_timer->is_one_shot()) { range_click_timer->set_wait_time(0.075); @@ -118,6 +119,8 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; + double step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step(); + if (mb.is_valid() && mb->is_pressed()) { bool up = mb->get_position().y < (get_size().height / 2); @@ -125,7 +128,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) { case MouseButton::LEFT: { line_edit->grab_focus(); - set_value(get_value() + (up ? get_step() : -get_step())); + set_value(get_value() + (up ? step : -step)); range_click_timer->set_wait_time(0.6); range_click_timer->set_one_shot(true); @@ -140,13 +143,13 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) { } break; case MouseButton::WHEEL_UP: { if (line_edit->has_focus()) { - set_value(get_value() + get_step() * mb->get_factor()); + set_value(get_value() + step * mb->get_factor()); accept_event(); } } break; case MouseButton::WHEEL_DOWN: { if (line_edit->has_focus()) { - set_value(get_value() - get_step() * mb->get_factor()); + set_value(get_value() - step * mb->get_factor()); accept_event(); } } break; @@ -168,7 +171,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) { if (drag.enabled) { drag.diff_y += mm->get_relative().y; double diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8) * SIGN(drag.diff_y); - set_value(CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max())); + set_value(CLAMP(drag.base_val + step * diff_y, get_min(), get_max())); } else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) { Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); drag.enabled = true; @@ -272,7 +275,7 @@ void SpinBox::set_update_on_text_changed(bool p_enabled) { update_on_text_changed = p_enabled; if (p_enabled) { - line_edit->connect("text_changed", callable_mp(this, &SpinBox::_text_changed), Vector<Variant>(), CONNECT_DEFERRED); + line_edit->connect("text_changed", callable_mp(this, &SpinBox::_text_changed), CONNECT_DEFERRED); } else { line_edit->disconnect("text_changed", callable_mp(this, &SpinBox::_text_changed)); } @@ -294,6 +297,14 @@ void SpinBox::apply() { _text_submitted(line_edit->get_text()); } +void SpinBox::set_custom_arrow_step(double p_custom_arrow_step) { + custom_arrow_step = p_custom_arrow_step; +} + +double SpinBox::get_custom_arrow_step() const { + return custom_arrow_step; +} + void SpinBox::_bind_methods() { ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &SpinBox::set_horizontal_alignment); ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &SpinBox::get_horizontal_alignment); @@ -302,6 +313,8 @@ void SpinBox::_bind_methods() { ClassDB::bind_method(D_METHOD("set_prefix", "prefix"), &SpinBox::set_prefix); ClassDB::bind_method(D_METHOD("get_prefix"), &SpinBox::get_prefix); ClassDB::bind_method(D_METHOD("set_editable", "enabled"), &SpinBox::set_editable); + ClassDB::bind_method(D_METHOD("set_custom_arrow_step", "arrow_step"), &SpinBox::set_custom_arrow_step); + ClassDB::bind_method(D_METHOD("get_custom_arrow_step"), &SpinBox::get_custom_arrow_step); ClassDB::bind_method(D_METHOD("is_editable"), &SpinBox::is_editable); ClassDB::bind_method(D_METHOD("set_update_on_text_changed", "enabled"), &SpinBox::set_update_on_text_changed); ClassDB::bind_method(D_METHOD("get_update_on_text_changed"), &SpinBox::get_update_on_text_changed); @@ -313,6 +326,7 @@ void SpinBox::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "update_on_text_changed"), "set_update_on_text_changed", "get_update_on_text_changed"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "prefix"), "set_prefix", "get_prefix"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "suffix"), "set_suffix", "get_suffix"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_arrow_step"), "set_custom_arrow_step", "get_custom_arrow_step"); } SpinBox::SpinBox() { @@ -323,8 +337,8 @@ SpinBox::SpinBox() { line_edit->set_mouse_filter(MOUSE_FILTER_PASS); line_edit->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT); - line_edit->connect("text_submitted", callable_mp(this, &SpinBox::_text_submitted), Vector<Variant>(), CONNECT_DEFERRED); - line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), Vector<Variant>(), CONNECT_DEFERRED); + line_edit->connect("text_submitted", callable_mp(this, &SpinBox::_text_submitted), CONNECT_DEFERRED); + line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), CONNECT_DEFERRED); line_edit->connect("gui_input", callable_mp(this, &SpinBox::_line_edit_input)); range_click_timer = memnew(Timer); diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 1b1abbcf8e..0aae9efe78 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -52,6 +52,7 @@ class SpinBox : public Range { String prefix; String suffix; + double custom_arrow_step = 0.0; void _line_edit_input(const Ref<InputEvent> &p_event); @@ -95,6 +96,8 @@ public: bool get_update_on_text_changed() const; void apply(); + void set_custom_arrow_step(const double p_custom_arrow_step); + double get_custom_arrow_step() const; SpinBox(); }; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 06553cd0f6..c023b06895 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -443,8 +443,10 @@ void TextEdit::_notification(int p_what) { case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_THEME_CHANGED: { - _update_caches(); - _update_wrap_at_column(true); + if (is_inside_tree()) { + _update_caches(); + _update_wrap_at_column(true); + } } break; case NOTIFICATION_WM_WINDOW_FOCUS_IN: { @@ -1055,7 +1057,7 @@ void TextEdit::_notification(int p_what) { const Variant *argp[] = { &args[0], &args[1], &args[2] }; Callable::CallError ce; Variant ret; - gutter.custom_draw_callback.call(argp, 3, ret, ce); + gutter.custom_draw_callback.callp(argp, 3, ret, ce); } } break; } @@ -1464,7 +1466,7 @@ void TextEdit::_notification(int p_what) { caret_end = caret_start + post_text.length(); } - DisplayServer::get_singleton()->virtual_keyboard_show(get_text(), get_global_rect(), true, -1, caret_start, caret_end); + DisplayServer::get_singleton()->virtual_keyboard_show(get_text(), get_global_rect(), DisplayServer::KEYBOARD_TYPE_MULTILINE, -1, caret_start, caret_end); } } break; @@ -2789,7 +2791,7 @@ String TextEdit::get_tooltip(const Point2 &p_pos) const { const Variant *argp[] = { &args[0] }; Callable::CallError ce; Variant ret; - tooltip_callback.call(argp, 1, ret, ce); + tooltip_callback.callp(argp, 1, ret, ce); ERR_FAIL_COND_V_MSG(ce.error != Callable::CallError::CALL_OK, "", "Failed to call custom tooltip."); return ret; } diff --git a/scene/gui/view_panner.cpp b/scene/gui/view_panner.cpp index 892d0aba29..3b7f499a07 100644 --- a/scene/gui/view_panner.cpp +++ b/scene/gui/view_panner.cpp @@ -135,7 +135,7 @@ void ViewPanner::callback_helper(Callable p_callback, Vector<Variant> p_args) { Variant result; Callable::CallError ce; - p_callback.call(argptr, p_args.size(), result, ce); + p_callback.callp(argptr, p_args.size(), result, ce); } void ViewPanner::set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback) { diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index e298805aca..ce204c6aeb 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -64,9 +64,6 @@ void CanvasItem::_propagate_visibility_changed(bool p_parent_visible_in_tree) { if (!visible) { return; } - if (p_parent_visible_in_tree && first_draw) { // Avoid propagating it twice. - first_draw = false; - } _handle_visibility_change(p_parent_visible_in_tree); } @@ -133,10 +130,6 @@ void CanvasItem::_update_callback() { RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item()); //todo updating = true - only allow drawing here if (is_visible_in_tree()) { - if (first_draw) { - notification(NOTIFICATION_VISIBILITY_CHANGED); - first_draw = false; - } drawing = true; current_item_drawn = this; notification(NOTIFICATION_DRAW); @@ -268,7 +261,6 @@ void CanvasItem::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { ERR_FAIL_COND(!is_inside_tree()); - first_draw = true; Node *parent = get_parent(); if (parent) { @@ -307,6 +299,10 @@ void CanvasItem::_notification(int p_what) { } } + RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, is_visible_in_tree()); // The visibility of the parent may change. + if (is_visible_in_tree()) { + notification(NOTIFICATION_VISIBILITY_CHANGED); // Considered invisible until entered. + } _enter_canvas(); _update_texture_filter_changed(false); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index f5df6512ee..38e0be1683 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -83,7 +83,6 @@ private: int light_mask = 1; Window *window = nullptr; - bool first_draw = false; bool visible = true; bool parent_visible_in_tree = false; bool clip_children = false; diff --git a/scene/main/multiplayer_api.cpp b/scene/main/multiplayer_api.cpp new file mode 100644 index 0000000000..95574042a8 --- /dev/null +++ b/scene/main/multiplayer_api.cpp @@ -0,0 +1,416 @@ +/*************************************************************************/ +/* multiplayer_api.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "multiplayer_api.h" + +#include "core/debugger/engine_debugger.h" +#include "core/io/marshalls.h" + +#include <stdint.h> + +#ifdef DEBUG_ENABLED +#include "core/os/os.h" +#endif + +StringName MultiplayerAPI::default_interface = StringName(); + +void MultiplayerAPI::set_default_interface(const StringName &p_interface) { + ERR_FAIL_COND_MSG(!ClassDB::is_parent_class(p_interface, MultiplayerAPI::get_class_static()), vformat("Can't make %s the default multiplayer interface since it does not extend MultiplayerAPI.", p_interface)); + default_interface = p_interface; +} + +StringName MultiplayerAPI::get_default_interface() { + return default_interface; +} + +Ref<MultiplayerAPI> MultiplayerAPI::create_default_interface() { + if (default_interface != StringName()) { + return Ref<MultiplayerAPI>(Object::cast_to<MultiplayerAPI>(ClassDB::instantiate(default_interface))); + } + return Ref<MultiplayerAPI>(memnew(MultiplayerAPIExtension)); +} + +// The variant is compressed and encoded; The first byte contains all the meta +// information and the format is: +// - The first LSB 5 bits are used for the variant type. +// - The next two bits are used to store the encoding mode. +// - The most significant is used to store the boolean value. +#define VARIANT_META_TYPE_MASK 0x1F +#define VARIANT_META_EMODE_MASK 0x60 +#define VARIANT_META_BOOL_MASK 0x80 +#define ENCODE_8 0 << 5 +#define ENCODE_16 1 << 5 +#define ENCODE_32 2 << 5 +#define ENCODE_64 3 << 5 +Error MultiplayerAPI::encode_and_compress_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_allow_object_decoding) { + // Unreachable because `VARIANT_MAX` == 27 and `ENCODE_VARIANT_MASK` == 31 + CRASH_COND(p_variant.get_type() > VARIANT_META_TYPE_MASK); + + uint8_t *buf = r_buffer; + r_len = 0; + uint8_t encode_mode = 0; + + switch (p_variant.get_type()) { + case Variant::BOOL: { + if (buf) { + // We still have 1 free bit in the meta, so let's use it. + buf[0] = (p_variant.operator bool()) ? (1 << 7) : 0; + buf[0] |= encode_mode | p_variant.get_type(); + } + r_len += 1; + } break; + case Variant::INT: { + if (buf) { + // Reserve the first byte for the meta. + buf += 1; + } + r_len += 1; + int64_t val = p_variant; + if (val <= (int64_t)INT8_MAX && val >= (int64_t)INT8_MIN) { + // Use 8 bit + encode_mode = ENCODE_8; + if (buf) { + buf[0] = val; + } + r_len += 1; + } else if (val <= (int64_t)INT16_MAX && val >= (int64_t)INT16_MIN) { + // Use 16 bit + encode_mode = ENCODE_16; + if (buf) { + encode_uint16(val, buf); + } + r_len += 2; + } else if (val <= (int64_t)INT32_MAX && val >= (int64_t)INT32_MIN) { + // Use 32 bit + encode_mode = ENCODE_32; + if (buf) { + encode_uint32(val, buf); + } + r_len += 4; + } else { + // Use 64 bit + encode_mode = ENCODE_64; + if (buf) { + encode_uint64(val, buf); + } + r_len += 8; + } + // Store the meta + if (buf) { + buf -= 1; + buf[0] = encode_mode | p_variant.get_type(); + } + } break; + default: + // Any other case is not yet compressed. + Error err = encode_variant(p_variant, r_buffer, r_len, p_allow_object_decoding); + if (err != OK) { + return err; + } + if (r_buffer) { + // The first byte is not used by the marshalling, so store the type + // so we know how to decompress and decode this variant. + r_buffer[0] = p_variant.get_type(); + } + } + + return OK; +} + +Error MultiplayerAPI::decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_object_decoding) { + const uint8_t *buf = p_buffer; + int len = p_len; + + ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA); + uint8_t type = buf[0] & VARIANT_META_TYPE_MASK; + uint8_t encode_mode = buf[0] & VARIANT_META_EMODE_MASK; + + ERR_FAIL_COND_V(type >= Variant::VARIANT_MAX, ERR_INVALID_DATA); + + switch (type) { + case Variant::BOOL: { + bool val = (buf[0] & VARIANT_META_BOOL_MASK) > 0; + r_variant = val; + if (r_len) { + *r_len = 1; + } + } break; + case Variant::INT: { + buf += 1; + len -= 1; + if (r_len) { + *r_len = 1; + } + if (encode_mode == ENCODE_8) { + // 8 bits. + ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA); + int8_t val = buf[0]; + r_variant = val; + if (r_len) { + (*r_len) += 1; + } + } else if (encode_mode == ENCODE_16) { + // 16 bits. + ERR_FAIL_COND_V(len < 2, ERR_INVALID_DATA); + int16_t val = decode_uint16(buf); + r_variant = val; + if (r_len) { + (*r_len) += 2; + } + } else if (encode_mode == ENCODE_32) { + // 32 bits. + ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); + int32_t val = decode_uint32(buf); + r_variant = val; + if (r_len) { + (*r_len) += 4; + } + } else { + // 64 bits. + ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); + int64_t val = decode_uint64(buf); + r_variant = val; + if (r_len) { + (*r_len) += 8; + } + } + } break; + default: + Error err = decode_variant(r_variant, p_buffer, p_len, r_len, p_allow_object_decoding); + if (err != OK) { + return err; + } + } + + return OK; +} + +Error MultiplayerAPI::encode_and_compress_variants(const Variant **p_variants, int p_count, uint8_t *p_buffer, int &r_len, bool *r_raw, bool p_allow_object_decoding) { + r_len = 0; + int size = 0; + + if (p_count == 0) { + if (r_raw) { + *r_raw = true; + } + return OK; + } + + // Try raw encoding optimization. + if (r_raw && p_count == 1) { + *r_raw = false; + const Variant &v = *(p_variants[0]); + if (v.get_type() == Variant::PACKED_BYTE_ARRAY) { + *r_raw = true; + const PackedByteArray pba = v; + if (p_buffer) { + memcpy(p_buffer, pba.ptr(), pba.size()); + } + r_len += pba.size(); + } else { + encode_and_compress_variant(v, p_buffer, size, p_allow_object_decoding); + r_len += size; + } + return OK; + } + + // Regular encoding. + for (int i = 0; i < p_count; i++) { + const Variant &v = *(p_variants[i]); + encode_and_compress_variant(v, p_buffer ? p_buffer + r_len : nullptr, size, p_allow_object_decoding); + r_len += size; + } + return OK; +} + +Error MultiplayerAPI::decode_and_decompress_variants(Vector<Variant> &r_variants, const uint8_t *p_buffer, int p_len, int &r_len, bool p_raw, bool p_allow_object_decoding) { + r_len = 0; + int argc = r_variants.size(); + if (argc == 0 && p_raw) { + return OK; + } + ERR_FAIL_COND_V(p_raw && argc != 1, ERR_INVALID_DATA); + if (p_raw) { + r_len = p_len; + PackedByteArray pba; + pba.resize(p_len); + memcpy(pba.ptrw(), p_buffer, p_len); + r_variants.write[0] = pba; + return OK; + } + + Vector<Variant> args; + Vector<const Variant *> argp; + args.resize(argc); + + for (int i = 0; i < argc; i++) { + ERR_FAIL_COND_V_MSG(r_len >= p_len, ERR_INVALID_DATA, "Invalid packet received. Size too small."); + + int vlen; + Error err = MultiplayerAPI::decode_and_decompress_variant(r_variants.write[i], &p_buffer[r_len], p_len - r_len, &vlen, p_allow_object_decoding); + ERR_FAIL_COND_V_MSG(err != OK, err, "Invalid packet received. Unable to decode state variable."); + r_len += vlen; + } + return OK; +} + +Error MultiplayerAPI::_rpc_bind(int p_peer, Object *p_object, const StringName &p_method, Array p_args) { + Vector<Variant> args; + Vector<const Variant *> argsp; + args.resize(p_args.size()); + argsp.resize(p_args.size()); + Variant *ptr = args.ptrw(); + const Variant **pptr = argsp.ptrw(); + for (int i = 0; i < p_args.size(); i++) { + ptr[i] = p_args[i]; + pptr[i] = &ptr[i]; + } + return rpcp(p_object, p_peer, p_method, argsp.size() ? argsp.ptrw() : nullptr, argsp.size()); +} + +void MultiplayerAPI::_bind_methods() { + ClassDB::bind_method(D_METHOD("has_multiplayer_peer"), &MultiplayerAPI::has_multiplayer_peer); + ClassDB::bind_method(D_METHOD("get_multiplayer_peer"), &MultiplayerAPI::get_multiplayer_peer); + ClassDB::bind_method(D_METHOD("set_multiplayer_peer", "peer"), &MultiplayerAPI::set_multiplayer_peer); + ClassDB::bind_method(D_METHOD("get_unique_id"), &MultiplayerAPI::get_unique_id); + ClassDB::bind_method(D_METHOD("is_server"), &MultiplayerAPI::is_server); + ClassDB::bind_method(D_METHOD("get_remote_sender_id"), &MultiplayerAPI::get_remote_sender_id); + ClassDB::bind_method(D_METHOD("poll"), &MultiplayerAPI::poll); + ClassDB::bind_method(D_METHOD("rpc", "peer", "object", "method", "arguments"), &MultiplayerAPI::_rpc_bind, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("object_configuration_add", "object", "configuration"), &MultiplayerAPI::object_configuration_add); + ClassDB::bind_method(D_METHOD("object_configuration_remove", "object", "configuration"), &MultiplayerAPI::object_configuration_remove); + + ClassDB::bind_method(D_METHOD("get_peers"), &MultiplayerAPI::get_peer_ids); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer_peer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerPeer", PROPERTY_USAGE_NONE), "set_multiplayer_peer", "get_multiplayer_peer"); + + ClassDB::bind_static_method("MultiplayerAPI", D_METHOD("set_default_interface", "interface_name"), &MultiplayerAPI::set_default_interface); + ClassDB::bind_static_method("MultiplayerAPI", D_METHOD("get_default_interface"), &MultiplayerAPI::get_default_interface); + ClassDB::bind_static_method("MultiplayerAPI", D_METHOD("create_default_interface"), &MultiplayerAPI::create_default_interface); + + ADD_SIGNAL(MethodInfo("peer_connected", PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("peer_disconnected", PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("connected_to_server")); + ADD_SIGNAL(MethodInfo("connection_failed")); + ADD_SIGNAL(MethodInfo("server_disconnected")); + + BIND_ENUM_CONSTANT(RPC_MODE_DISABLED); + BIND_ENUM_CONSTANT(RPC_MODE_ANY_PEER); + BIND_ENUM_CONSTANT(RPC_MODE_AUTHORITY); +} + +/// MultiplayerAPIExtension + +Error MultiplayerAPIExtension::poll() { + int err; + if (GDVIRTUAL_CALL(_poll, err)) { + return (Error)err; + } + return OK; +} + +void MultiplayerAPIExtension::set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) { + GDVIRTUAL_CALL(_set_multiplayer_peer, p_peer); +} + +Ref<MultiplayerPeer> MultiplayerAPIExtension::get_multiplayer_peer() { + Ref<MultiplayerPeer> peer; + if (GDVIRTUAL_CALL(_get_multiplayer_peer, peer)) { + return peer; + } + return nullptr; +} + +int MultiplayerAPIExtension::get_unique_id() { + int id; + if (GDVIRTUAL_CALL(_get_unique_id, id)) { + return id; + } + return 1; +} + +Vector<int> MultiplayerAPIExtension::get_peer_ids() { + Vector<int> ids; + if (GDVIRTUAL_CALL(_get_peer_ids, ids)) { + return ids; + } + return Vector<int>(); +} + +Error MultiplayerAPIExtension::rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { + if (!GDVIRTUAL_IS_OVERRIDDEN(_rpc)) { + return ERR_UNAVAILABLE; + } + Array args; + for (int i = 0; i < p_argcount; i++) { + args.push_back(*p_arg[i]); + } + int ret; + if (GDVIRTUAL_CALL(_rpc, p_peer_id, p_obj, p_method, args, ret)) { + return (Error)ret; + } + return FAILED; +} + +int MultiplayerAPIExtension::get_remote_sender_id() { + int id; + if (GDVIRTUAL_CALL(_get_remote_sender_id, id)) { + return id; + } + return 0; +} + +Error MultiplayerAPIExtension::object_configuration_add(Object *p_object, Variant p_config) { + int err; + if (GDVIRTUAL_CALL(_object_configuration_add, p_object, p_config, err)) { + return (Error)err; + } + return ERR_UNAVAILABLE; +} + +Error MultiplayerAPIExtension::object_configuration_remove(Object *p_object, Variant p_config) { + int err; + if (GDVIRTUAL_CALL(_object_configuration_remove, p_object, p_config, err)) { + return (Error)err; + } + return ERR_UNAVAILABLE; +} + +void MultiplayerAPIExtension::_bind_methods() { + GDVIRTUAL_BIND(_poll); + GDVIRTUAL_BIND(_set_multiplayer_peer, "multiplayer_peer"); + GDVIRTUAL_BIND(_get_multiplayer_peer); + GDVIRTUAL_BIND(_get_unique_id); + GDVIRTUAL_BIND(_get_peer_ids); + GDVIRTUAL_BIND(_rpc, "peer", "object", "method", "args"); + GDVIRTUAL_BIND(_get_remote_sender_id); + GDVIRTUAL_BIND(_object_configuration_add, "object", "configuration"); + GDVIRTUAL_BIND(_object_configuration_remove, "object", "configuration"); +} diff --git a/scene/main/multiplayer_api.h b/scene/main/multiplayer_api.h new file mode 100644 index 0000000000..c1d90d651e --- /dev/null +++ b/scene/main/multiplayer_api.h @@ -0,0 +1,115 @@ +/*************************************************************************/ +/* multiplayer_api.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef MULTIPLAYER_API_H +#define MULTIPLAYER_API_H + +#include "core/object/ref_counted.h" +#include "scene/main/multiplayer_peer.h" + +class MultiplayerAPI : public RefCounted { + GDCLASS(MultiplayerAPI, RefCounted); + +private: + static StringName default_interface; + +protected: + static void _bind_methods(); + Error _rpc_bind(int p_peer, Object *p_obj, const StringName &p_method, Array args = Array()); + +public: + enum RPCMode { + RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default) + RPC_MODE_ANY_PEER, // Any peer can call this RPC + RPC_MODE_AUTHORITY, // Only the node's multiplayer authority (server by default) can call this RPC + }; + + static Ref<MultiplayerAPI> create_default_interface(); + static void set_default_interface(const StringName &p_interface); + static StringName get_default_interface(); + + static Error encode_and_compress_variant(const Variant &p_variant, uint8_t *p_buffer, int &r_len, bool p_allow_object_decoding); + static Error decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_object_decoding); + static Error encode_and_compress_variants(const Variant **p_variants, int p_count, uint8_t *p_buffer, int &r_len, bool *r_raw = nullptr, bool p_allow_object_decoding = false); + static Error decode_and_decompress_variants(Vector<Variant> &r_variants, const uint8_t *p_buffer, int p_len, int &r_len, bool p_raw = false, bool p_allow_object_decoding = false); + + virtual Error poll() = 0; + virtual void set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) = 0; + virtual Ref<MultiplayerPeer> get_multiplayer_peer() = 0; + virtual int get_unique_id() = 0; + virtual Vector<int> get_peer_ids() = 0; + + virtual Error rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) = 0; + virtual int get_remote_sender_id() = 0; + + virtual Error object_configuration_add(Object *p_object, Variant p_config) = 0; + virtual Error object_configuration_remove(Object *p_object, Variant p_config) = 0; + + bool has_multiplayer_peer() { return get_multiplayer_peer().is_valid(); } + bool is_server() { return get_unique_id() == MultiplayerPeer::TARGET_PEER_SERVER; } + + MultiplayerAPI() {} + virtual ~MultiplayerAPI() {} +}; + +VARIANT_ENUM_CAST(MultiplayerAPI::RPCMode); + +class MultiplayerAPIExtension : public MultiplayerAPI { + GDCLASS(MultiplayerAPIExtension, MultiplayerAPI); + +protected: + static void _bind_methods(); + +public: + virtual Error poll() override; + virtual void set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) override; + virtual Ref<MultiplayerPeer> get_multiplayer_peer() override; + virtual int get_unique_id() override; + virtual Vector<int> get_peer_ids() override; + + virtual Error rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) override; + virtual int get_remote_sender_id() override; + + virtual Error object_configuration_add(Object *p_object, Variant p_config) override; + virtual Error object_configuration_remove(Object *p_object, Variant p_config) override; + + // Extensions + GDVIRTUAL0R(int, _poll); + GDVIRTUAL1(_set_multiplayer_peer, Ref<MultiplayerPeer>); + GDVIRTUAL0R(Ref<MultiplayerPeer>, _get_multiplayer_peer); + GDVIRTUAL0RC(int, _get_unique_id); + GDVIRTUAL0RC(PackedInt32Array, _get_peer_ids); + GDVIRTUAL4R(int, _rpc, int, Object *, StringName, Array); + GDVIRTUAL0RC(int, _get_remote_sender_id); + GDVIRTUAL2R(int, _object_configuration_add, Object *, Variant); + GDVIRTUAL2R(int, _object_configuration_remove, Object *, Variant); +}; + +#endif // MULTIPLAYER_API_H diff --git a/core/multiplayer/multiplayer_peer.cpp b/scene/main/multiplayer_peer.cpp index c7de7a1313..aad5baccab 100644 --- a/core/multiplayer/multiplayer_peer.cpp +++ b/scene/main/multiplayer_peer.cpp @@ -62,11 +62,11 @@ int MultiplayerPeer::get_transfer_channel() const { return transfer_channel; } -void MultiplayerPeer::set_transfer_mode(Multiplayer::TransferMode p_mode) { +void MultiplayerPeer::set_transfer_mode(TransferMode p_mode) { transfer_mode = p_mode; } -Multiplayer::TransferMode MultiplayerPeer::get_transfer_mode() const { +MultiplayerPeer::TransferMode MultiplayerPeer::get_transfer_mode() const { return transfer_mode; } @@ -107,6 +107,10 @@ void MultiplayerPeer::_bind_methods() { BIND_CONSTANT(TARGET_PEER_BROADCAST); BIND_CONSTANT(TARGET_PEER_SERVER); + BIND_ENUM_CONSTANT(TRANSFER_MODE_UNRELIABLE); + BIND_ENUM_CONSTANT(TRANSFER_MODE_UNRELIABLE_ORDERED); + BIND_ENUM_CONSTANT(TRANSFER_MODE_RELIABLE); + ADD_SIGNAL(MethodInfo("peer_connected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("peer_disconnected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("server_disconnected")); @@ -191,17 +195,17 @@ int MultiplayerPeerExtension::get_transfer_channel() const { return MultiplayerPeer::get_transfer_channel(); } -void MultiplayerPeerExtension::set_transfer_mode(Multiplayer::TransferMode p_mode) { +void MultiplayerPeerExtension::set_transfer_mode(TransferMode p_mode) { if (GDVIRTUAL_CALL(_set_transfer_mode, p_mode)) { return; } MultiplayerPeer::set_transfer_mode(p_mode); } -Multiplayer::TransferMode MultiplayerPeerExtension::get_transfer_mode() const { +MultiplayerPeer::TransferMode MultiplayerPeerExtension::get_transfer_mode() const { int mode; if (GDVIRTUAL_CALL(_get_transfer_mode, mode)) { - return (Multiplayer::TransferMode)mode; + return (MultiplayerPeer::TransferMode)mode; } return MultiplayerPeer::get_transfer_mode(); } diff --git a/core/multiplayer/multiplayer_peer.h b/scene/main/multiplayer_peer.h index 91546832ce..8a012d7520 100644 --- a/core/multiplayer/multiplayer_peer.h +++ b/scene/main/multiplayer_peer.h @@ -32,7 +32,6 @@ #define MULTIPLAYER_PEER_H #include "core/io/packet_peer.h" -#include "core/multiplayer/multiplayer.h" #include "core/object/gdvirtual.gen.inc" #include "core/object/script_language.h" @@ -41,12 +40,19 @@ class MultiplayerPeer : public PacketPeer { GDCLASS(MultiplayerPeer, PacketPeer); +public: + enum TransferMode { + TRANSFER_MODE_UNRELIABLE, + TRANSFER_MODE_UNRELIABLE_ORDERED, + TRANSFER_MODE_RELIABLE + }; + protected: static void _bind_methods(); private: int transfer_channel = 0; - Multiplayer::TransferMode transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; + TransferMode transfer_mode = TRANSFER_MODE_RELIABLE; bool refuse_connections = false; public: @@ -63,8 +69,8 @@ public: virtual void set_transfer_channel(int p_channel); virtual int get_transfer_channel() const; - virtual void set_transfer_mode(Multiplayer::TransferMode p_mode); - virtual Multiplayer::TransferMode get_transfer_mode() const; + virtual void set_transfer_mode(TransferMode p_mode); + virtual TransferMode get_transfer_mode() const; virtual void set_refuse_new_connections(bool p_enable); virtual bool is_refusing_new_connections() const; @@ -86,6 +92,7 @@ public: }; VARIANT_ENUM_CAST(MultiplayerPeer::ConnectionStatus); +VARIANT_ENUM_CAST(MultiplayerPeer::TransferMode); class MultiplayerPeerExtension : public MultiplayerPeer { GDCLASS(MultiplayerPeerExtension, MultiplayerPeer); @@ -105,8 +112,8 @@ public: /* MultiplayerPeer */ virtual void set_transfer_channel(int p_channel) override; virtual int get_transfer_channel() const override; - virtual void set_transfer_mode(Multiplayer::TransferMode p_mode) override; - virtual Multiplayer::TransferMode get_transfer_mode() const override; + virtual void set_transfer_mode(TransferMode p_mode) override; + virtual TransferMode get_transfer_mode() const override; virtual void set_target_peer(int p_peer_id) override; virtual int get_packet_peer() const override; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index b4701637a4..ea9788de27 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -33,12 +33,12 @@ #include "core/config/project_settings.h" #include "core/core_string_names.h" #include "core/io/resource_loader.h" -#include "core/multiplayer/multiplayer_api.h" #include "core/object/message_queue.h" #include "core/string/print_string.h" #include "instance_placeholder.h" #include "scene/animation/tween.h" #include "scene/debugger/scene_debugger.h" +#include "scene/main/multiplayer_api.h" #include "scene/resources/packed_scene.h" #include "scene/scene_string_names.h" #include "viewport.h" @@ -582,35 +582,30 @@ bool Node::is_multiplayer_authority() const { /***** RPC CONFIG ********/ -uint16_t Node::rpc_config(const StringName &p_method, Multiplayer::RPCMode p_rpc_mode, bool p_call_local, Multiplayer::TransferMode p_transfer_mode, int p_channel) { - for (int i = 0; i < data.rpc_methods.size(); i++) { - if (data.rpc_methods[i].name == p_method) { - Multiplayer::RPCConfig &nd = data.rpc_methods.write[i]; - nd.rpc_mode = p_rpc_mode; - nd.transfer_mode = p_transfer_mode; - nd.call_local = p_call_local; - nd.channel = p_channel; - return i | (1 << 15); - } +void Node::rpc_config(const StringName &p_method, const Variant &p_config) { + if (data.rpc_config.get_type() != Variant::DICTIONARY) { + data.rpc_config = Dictionary(); + } + Dictionary node_config = data.rpc_config; + if (p_config.get_type() == Variant::NIL) { + node_config.erase(p_method); + } else { + ERR_FAIL_COND(p_config.get_type() != Variant::DICTIONARY); + node_config[p_method] = p_config; } - // New method - Multiplayer::RPCConfig nd; - nd.name = p_method; - nd.rpc_mode = p_rpc_mode; - nd.transfer_mode = p_transfer_mode; - nd.channel = p_channel; - nd.call_local = p_call_local; - data.rpc_methods.push_back(nd); - return ((uint16_t)data.rpc_methods.size() - 1) | (1 << 15); +} + +const Variant Node::get_node_rpc_config() const { + return data.rpc_config; } /***** RPC FUNCTIONS ********/ -void Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Error Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 1) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; - return; + return ERR_INVALID_PARAMETER; } Variant::Type type = p_args[0]->get_type(); @@ -618,28 +613,28 @@ void Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING_NAME; - return; + return ERR_INVALID_PARAMETER; } StringName method = (*p_args[0]).operator StringName(); - rpcp(0, method, &p_args[1], p_argcount - 1); - + Error err = rpcp(0, method, &p_args[1], p_argcount - 1); r_error.error = Callable::CallError::CALL_OK; + return err; } -void Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Error Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 2) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 2; - return; + return ERR_INVALID_PARAMETER; } if (p_args[0]->get_type() != Variant::INT) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::INT; - return; + return ERR_INVALID_PARAMETER; } Variant::Type type = p_args[1]->get_type(); @@ -647,20 +642,20 @@ void Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallEr r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING_NAME; - return; + return ERR_INVALID_PARAMETER; } int peer_id = *p_args[0]; StringName method = (*p_args[1]).operator StringName(); - rpcp(peer_id, method, &p_args[2], p_argcount - 2); - + Error err = rpcp(peer_id, method, &p_args[2], p_argcount - 2); r_error.error = Callable::CallError::CALL_OK; + return err; } -void Node::rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { - ERR_FAIL_COND(!is_inside_tree()); - get_multiplayer()->rpcp(this, p_peer_id, p_method, p_arg, p_argcount); +Error Node::rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { + ERR_FAIL_COND_V(!is_inside_tree(), ERR_UNCONFIGURED); + return get_multiplayer()->rpcp(this, p_peer_id, p_method, p_arg, p_argcount); } Ref<MultiplayerAPI> Node::get_multiplayer() const { @@ -670,10 +665,6 @@ Ref<MultiplayerAPI> Node::get_multiplayer() const { return get_tree()->get_multiplayer(get_path()); } -Vector<Multiplayer::RPCConfig> Node::get_node_rpc_methods() const { - return data.rpc_methods; -} - //////////// end of rpc bool Node::can_process_notification(int p_what) const { @@ -2404,7 +2395,7 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { if (copy && copytarget) { const Callable copy_callable = Callable(copytarget, E.callable.get_method()); if (!copy->is_connected(E.signal.get_name(), copy_callable)) { - copy->connect(E.signal.get_name(), copy_callable, E.binds, E.flags); + copy->connect(E.signal.get_name(), copy_callable, E.flags); } } } @@ -2490,7 +2481,7 @@ void Node::_replace_connections_target(Node *p_new_target) { c.signal.get_object()->disconnect(c.signal.get_name(), Callable(this, c.callable.get_method())); bool valid = p_new_target->has_method(c.callable.get_method()) || Ref<Script>(p_new_target->get_script()).is_null() || Ref<Script>(p_new_target->get_script())->has_method(c.callable.get_method()); ERR_CONTINUE_MSG(!valid, vformat("Attempt to connect signal '%s.%s' to nonexistent method '%s.%s'.", c.signal.get_object()->get_class(), c.signal.get_name(), c.callable.get_object()->get_class(), c.callable.get_method())); - c.signal.get_object()->connect(c.signal.get_name(), Callable(p_new_target, c.callable.get_method()), c.binds, c.flags); + c.signal.get_object()->connect(c.signal.get_name(), Callable(p_new_target, c.callable.get_method()), c.flags); } } } @@ -2888,7 +2879,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("is_multiplayer_authority"), &Node::is_multiplayer_authority); ClassDB::bind_method(D_METHOD("get_multiplayer"), &Node::get_multiplayer); - ClassDB::bind_method(D_METHOD("rpc_config", "method", "rpc_mode", "call_local", "transfer_mode", "channel"), &Node::rpc_config, DEFVAL(false), DEFVAL(Multiplayer::TRANSFER_MODE_RELIABLE), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("rpc_config", "method", "config"), &Node::rpc_config); ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description); ClassDB::bind_method(D_METHOD("get_editor_description"), &Node::get_editor_description); diff --git a/scene/main/node.h b/scene/main/node.h index d978c03442..ccd1d561d2 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -127,7 +127,7 @@ private: Node *process_owner = nullptr; int multiplayer_authority = 1; // Server by default. - Vector<Multiplayer::RPCConfig> rpc_methods; + Variant rpc_config; // Variables used to properly sort the node when processing, ignored otherwise. // TODO: Should move all the stuff below to bits. @@ -183,8 +183,8 @@ private: TypedArray<Node> _get_children(bool p_include_internal = true) const; Array _get_groups() const; - void _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); - void _rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + Error _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + Error _rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); _FORCE_INLINE_ bool _is_internal_front() const { return data.parent && data.pos < data.parent->data.internal_children_front; } _FORCE_INLINE_ bool _is_internal_back() const { return data.parent && data.pos >= data.parent->data.children.size() - data.parent->data.internal_children_back; } @@ -491,30 +491,16 @@ public: int get_multiplayer_authority() const; bool is_multiplayer_authority() const; - uint16_t rpc_config(const StringName &p_method, Multiplayer::RPCMode p_rpc_mode, bool p_call_local = false, Multiplayer::TransferMode p_transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE, int p_channel = 0); // config a local method for RPC - Vector<Multiplayer::RPCConfig> get_node_rpc_methods() const; + void rpc_config(const StringName &p_method, const Variant &p_config); // config a local method for RPC + const Variant get_node_rpc_config() const; template <typename... VarArgs> - void rpc(const StringName &p_method, VarArgs... p_args) { - Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. - const Variant *argptrs[sizeof...(p_args) + 1]; - for (uint32_t i = 0; i < sizeof...(p_args); i++) { - argptrs[i] = &args[i]; - } - rpcp(0, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); - } + Error rpc(const StringName &p_method, VarArgs... p_args); template <typename... VarArgs> - void rpc_id(int p_peer_id, const StringName &p_method, VarArgs... p_args) { - Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. - const Variant *argptrs[sizeof...(p_args) + 1]; - for (uint32_t i = 0; i < sizeof...(p_args); i++) { - argptrs[i] = &args[i]; - } - rpcp(p_peer_id, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); - } + Error rpc_id(int p_peer_id, const StringName &p_method, VarArgs... p_args); - void rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount); + Error rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount); Ref<MultiplayerAPI> get_multiplayer() const; @@ -526,4 +512,22 @@ VARIANT_ENUM_CAST(Node::DuplicateFlags); typedef HashSet<Node *, Node::Comparator> NodeSet; +// Template definitions must be in the header so they are always fully initialized before their usage. +// See this StackOverflow question for more information: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file + +template <typename... VarArgs> +Error Node::rpc(const StringName &p_method, VarArgs... p_args) { + return rpc_id(0, p_method, p_args...); +} + +template <typename... VarArgs> +Error Node::rpc_id(int p_peer_id, const StringName &p_method, VarArgs... p_args) { + Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. + const Variant *argptrs[sizeof...(p_args) + 1]; + for (uint32_t i = 0; i < sizeof...(p_args); i++) { + argptrs[i] = &args[i]; + } + return rpcp(p_peer_id, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); +} + #endif // NODE_H diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 66482f65dc..644fb3e9cc 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -37,7 +37,6 @@ #include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/resource_loader.h" -#include "core/multiplayer/multiplayer_api.h" #include "core/object/message_queue.h" #include "core/os/keyboard.h" #include "core/os/os.h" @@ -45,6 +44,7 @@ #include "node.h" #include "scene/animation/tween.h" #include "scene/debugger/scene_debugger.h" +#include "scene/main/multiplayer_api.h" #include "scene/main/viewport.h" #include "scene/resources/font.h" #include "scene/resources/material.h" @@ -1213,19 +1213,17 @@ void SceneTree::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer, const NodePat if (p_root_path.is_empty()) { ERR_FAIL_COND(!p_multiplayer.is_valid()); if (multiplayer.is_valid()) { - multiplayer->set_root_path(NodePath()); + multiplayer->object_configuration_remove(nullptr, NodePath("/" + root->get_name())); } multiplayer = p_multiplayer; - multiplayer->set_root_path("/" + root->get_name()); + multiplayer->object_configuration_add(nullptr, NodePath("/" + root->get_name())); } else { + if (custom_multiplayers.has(p_root_path)) { + custom_multiplayers[p_root_path]->object_configuration_remove(nullptr, p_root_path); + } if (p_multiplayer.is_valid()) { custom_multiplayers[p_root_path] = p_multiplayer; - p_multiplayer->set_root_path(p_root_path); - } else { - if (custom_multiplayers.has(p_root_path)) { - custom_multiplayers[p_root_path]->set_root_path(NodePath()); - custom_multiplayers.erase(p_root_path); - } + p_multiplayer->object_configuration_add(nullptr, p_root_path); } } } @@ -1415,7 +1413,7 @@ SceneTree::SceneTree() { #endif // _3D_DISABLED // Initialize network state. - set_multiplayer(Ref<MultiplayerAPI>(memnew(MultiplayerAPI))); + set_multiplayer(MultiplayerAPI::create_default_interface()); root->set_as_audio_listener_2d(true); current_scene = nullptr; diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 3b6055fcf7..a621aea9c8 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -64,9 +64,9 @@ bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_valu if (active) { if (o->override.get_type() == Variant::OBJECT) { RID tex_rid = p_value; - RS::get_singleton()->global_variable_set_override(*r, tex_rid); + RS::get_singleton()->global_shader_uniform_set_override(*r, tex_rid); } else { - RS::get_singleton()->global_variable_set_override(*r, p_value); + RS::get_singleton()->global_shader_uniform_set_override(*r, p_value); } } o->in_use = p_value.get_type() != Variant::NIL; @@ -93,13 +93,13 @@ bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const { Vector<StringName> variables; - variables = RS::get_singleton()->global_variable_get_list(); + variables = RS::get_singleton()->global_shader_uniform_get_list(); for (int i = 0; i < variables.size(); i++) { PropertyInfo pinfo; pinfo.name = "params/" + variables[i]; pinfo.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - switch (RS::get_singleton()->global_variable_get_type(variables[i])) { + switch (RS::get_singleton()->global_shader_uniform_get_type(variables[i])) { case RS::GLOBAL_VAR_TYPE_BOOL: { pinfo.type = Variant::BOOL; } break; @@ -234,9 +234,9 @@ void ShaderGlobalsOverride::_activate() { if (o->in_use && o->override.get_type() != Variant::NIL) { if (o->override.get_type() == Variant::OBJECT) { RID tex_rid = o->override; - RS::get_singleton()->global_variable_set_override(E.key, tex_rid); + RS::get_singleton()->global_shader_uniform_set_override(E.key, tex_rid); } else { - RS::get_singleton()->global_variable_set_override(E.key, o->override); + RS::get_singleton()->global_shader_uniform_set_override(E.key, o->override); } } @@ -258,7 +258,7 @@ void ShaderGlobalsOverride::_notification(int p_what) { for (const KeyValue<StringName, Override> &E : overrides) { const Override *o = &E.value; if (o->in_use) { - RS::get_singleton()->global_variable_set_override(E.key, Variant()); + RS::get_singleton()->global_shader_uniform_set_override(E.key, Variant()); } } } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index c2fa1ace8d..584fad9648 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1234,13 +1234,23 @@ void Viewport::_gui_show_tooltip() { Rect2i vr = window->get_usable_parent_rect(); if (r.size.x + r.position.x > vr.size.x + vr.position.x) { - r.position.x = vr.position.x + vr.size.x - r.size.x; + // Place it in the opposite direction. If it fails, just hug the border. + r.position.x = gui.tooltip_pos.x - r.size.x - tooltip_offset.x; + + if (r.position.x < vr.position.x) { + r.position.x = vr.position.x + vr.size.x - r.size.x; + } } else if (r.position.x < vr.position.x) { r.position.x = vr.position.x; } if (r.size.y + r.position.y > vr.size.y + vr.position.y) { - r.position.y = vr.position.y + vr.size.y - r.size.y; + // Same as above. + r.position.y = gui.tooltip_pos.y - r.size.y - tooltip_offset.y; + + if (r.position.y < vr.position.y) { + r.position.y = vr.position.y + vr.size.y - r.size.y; + } } else if (r.position.y < vr.position.y) { r.position.y = vr.position.y; } @@ -2488,17 +2498,20 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) { if (gui.subwindow_drag == SUB_WINDOW_DRAG_RESIZE) { Vector2i diff = mm->get_position() - gui.subwindow_drag_from; Size2i min_size = gui.subwindow_focused->get_min_size(); + + Size2i min_size_adjusted = min_size; if (gui.subwindow_focused->is_wrapping_controls()) { Size2i cms = gui.subwindow_focused->get_contents_minimum_size(); - min_size.x = MAX(cms.x, min_size.x); - min_size.y = MAX(cms.y, min_size.y); + min_size_adjusted.x = MAX(cms.x, min_size.x); + min_size_adjusted.y = MAX(cms.y, min_size.y); } - min_size.x = MAX(min_size.x, 1); - min_size.y = MAX(min_size.y, 1); + + min_size_adjusted.x = MAX(min_size_adjusted.x, 1); + min_size_adjusted.y = MAX(min_size_adjusted.y, 1); Rect2i r = gui.subwindow_resize_from_rect; - Size2i limit = r.size - min_size; + Size2i limit = r.size - min_size_adjusted; switch (gui.subwindow_resize_mode) { case SUB_WINDOW_RESIZE_TOP_LEFT: { @@ -2553,6 +2566,19 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) { } } + Size2i max_size = gui.subwindow_focused->get_max_size(); + if ((max_size.x > 0 || max_size.y > 0) && (max_size.x >= min_size.x && max_size.y >= min_size.y)) { + max_size.x = MAX(max_size.x, 1); + max_size.y = MAX(max_size.y, 1); + + if (r.size.x > max_size.x) { + r.size.x = max_size.x; + } + if (r.size.y > max_size.y) { + r.size.y = max_size.y; + } + } + gui.subwindow_focused->_rect_changed_callback(r); } @@ -2590,7 +2616,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) { Ref<Texture2D> close_icon = sw.window->get_theme_icon(SNAME("close")); Rect2 close_rect; - close_rect.position = Vector2(r.position.x + r.size.x - close_v_ofs, r.position.y - close_h_ofs); + close_rect.position = Vector2(r.position.x + r.size.x - close_h_ofs, r.position.y - close_v_ofs); close_rect.size = close_icon->get_size(); if (gui.subwindow_focused != sw.window) { @@ -3621,17 +3647,17 @@ float Viewport::get_fsr_sharpness() const { return fsr_sharpness; } -void Viewport::set_fsr_mipmap_bias(float p_fsr_mipmap_bias) { - if (fsr_mipmap_bias == p_fsr_mipmap_bias) { +void Viewport::set_texture_mipmap_bias(float p_texture_mipmap_bias) { + if (texture_mipmap_bias == p_texture_mipmap_bias) { return; } - fsr_mipmap_bias = p_fsr_mipmap_bias; - RS::get_singleton()->viewport_set_fsr_mipmap_bias(viewport, p_fsr_mipmap_bias); + texture_mipmap_bias = p_texture_mipmap_bias; + RS::get_singleton()->viewport_set_texture_mipmap_bias(viewport, p_texture_mipmap_bias); } -float Viewport::get_fsr_mipmap_bias() const { - return fsr_mipmap_bias; +float Viewport::get_texture_mipmap_bias() const { + return texture_mipmap_bias; } #endif // _3D_DISABLED @@ -3773,8 +3799,8 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_fsr_sharpness", "fsr_sharpness"), &Viewport::set_fsr_sharpness); ClassDB::bind_method(D_METHOD("get_fsr_sharpness"), &Viewport::get_fsr_sharpness); - ClassDB::bind_method(D_METHOD("set_fsr_mipmap_bias", "fsr_mipmap_bias"), &Viewport::set_fsr_mipmap_bias); - ClassDB::bind_method(D_METHOD("get_fsr_mipmap_bias"), &Viewport::get_fsr_mipmap_bias); + ClassDB::bind_method(D_METHOD("set_texture_mipmap_bias", "texture_mipmap_bias"), &Viewport::set_texture_mipmap_bias); + ClassDB::bind_method(D_METHOD("get_texture_mipmap_bias"), &Viewport::get_texture_mipmap_bias); ClassDB::bind_method(D_METHOD("set_vrs_mode", "mode"), &Viewport::set_vrs_mode); ClassDB::bind_method(D_METHOD("get_vrs_mode"), &Viewport::get_vrs_mode); @@ -3804,7 +3830,7 @@ void Viewport::_bind_methods() { ADD_GROUP("Scaling 3D", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "scaling_3d_mode", PROPERTY_HINT_ENUM, "Bilinear (Fastest),FSR 1.0 (Fast)"), "set_scaling_3d_mode", "get_scaling_3d_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scaling_3d_scale", PROPERTY_HINT_RANGE, "0.25,2.0,0.01"), "set_scaling_3d_scale", "get_scaling_3d_scale"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_mipmap_bias", PROPERTY_HINT_RANGE, "-2,2,0.1"), "set_fsr_mipmap_bias", "get_fsr_mipmap_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_mipmap_bias", PROPERTY_HINT_RANGE, "-2,2,0.001"), "set_texture_mipmap_bias", "get_texture_mipmap_bias"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_sharpness", PROPERTY_HINT_RANGE, "0,2,0.1"), "set_fsr_sharpness", "get_fsr_sharpness"); #endif ADD_GROUP("Variable Rate Shading", "vrs_"); @@ -3978,8 +4004,8 @@ Viewport::Viewport() { float fsr_sharpness = GLOBAL_GET("rendering/scaling_3d/fsr_sharpness"); set_fsr_sharpness(fsr_sharpness); - float fsr_mipmap_bias = GLOBAL_GET("rendering/scaling_3d/fsr_mipmap_bias"); - set_fsr_mipmap_bias(fsr_mipmap_bias); + float texture_mipmap_bias = GLOBAL_GET("rendering/textures/default_filters/texture_mipmap_bias"); + set_texture_mipmap_bias(texture_mipmap_bias); #endif // _3D_DISABLED set_sdf_oversize(sdf_oversize); // Set to server. diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 58b05d23e0..4221baff06 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -304,7 +304,7 @@ private: Scaling3DMode scaling_3d_mode = SCALING_3D_MODE_BILINEAR; float scaling_3d_scale = 1.0; float fsr_sharpness = 0.2f; - float fsr_mipmap_bias = 0.0f; + float texture_mipmap_bias = 0.0f; bool use_debanding = false; float mesh_lod_threshold = 1.0; bool use_occlusion_culling = false; @@ -540,8 +540,8 @@ public: void set_fsr_sharpness(float p_fsr_sharpness); float get_fsr_sharpness() const; - void set_fsr_mipmap_bias(float p_fsr_mipmap_bias); - float get_fsr_mipmap_bias() const; + void set_texture_mipmap_bias(float p_texture_mipmap_bias); + float get_texture_mipmap_bias() const; void set_use_debanding(bool p_use_debanding); bool is_using_debanding() const; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 73e8f537d9..d40b82f5eb 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -242,8 +242,8 @@ void Window::_make_window() { window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, Rect2i(position, size)); ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID); DisplayServer::get_singleton()->window_set_current_screen(current_screen, window_id); - DisplayServer::get_singleton()->window_set_max_size(max_size, window_id); - DisplayServer::get_singleton()->window_set_min_size(min_size, window_id); + DisplayServer::get_singleton()->window_set_max_size(Size2i(), window_id); + DisplayServer::get_singleton()->window_set_min_size(Size2i(), window_id); String tr_title = atr(title); #ifdef DEBUG_ENABLED if (window_id == DisplayServer::MAIN_WINDOW_ID) { @@ -596,20 +596,43 @@ void Window::_update_window_size() { size.x = MAX(size_limit.x, size.x); size.y = MAX(size_limit.y, size.y); - if (max_size.x > 0 && max_size.x > min_size.x && size.x > max_size.x) { - size.x = max_size.x; - } + bool reset_min_first = false; + + bool max_size_valid = false; + if ((max_size.x > 0 || max_size.y > 0) && (max_size.x >= min_size.x && max_size.y >= min_size.y)) { + max_size_valid = true; + + if (size.x > max_size.x) { + size.x = max_size.x; + } + if (size_limit.x > max_size.x) { + size_limit.x = max_size.x; + reset_min_first = true; + } - if (max_size.y > 0 && max_size.y > min_size.y && size.y > max_size.y) { - size.y = max_size.y; + if (size.y > max_size.y) { + size.y = max_size.y; + } + if (size_limit.y > max_size.y) { + size_limit.y = max_size.y; + reset_min_first = true; + } } if (embedder) { + size.x = MAX(size.x, 1); + size.y = MAX(size.y, 1); + embedder->_sub_window_update(this); } else if (window_id != DisplayServer::INVALID_WINDOW_ID) { + if (reset_min_first && wrap_controls) { + // Avoid an error if setting max_size to a value between min_size and the previous size_limit. + DisplayServer::get_singleton()->window_set_min_size(Size2i(), window_id); + } + DisplayServer::get_singleton()->window_set_size(size, window_id); + DisplayServer::get_singleton()->window_set_max_size(max_size_valid ? max_size : Size2i(), window_id); DisplayServer::get_singleton()->window_set_min_size(size_limit, window_id); - DisplayServer::get_singleton()->window_set_max_size(max_size, window_id); } //update the viewport @@ -953,6 +976,8 @@ void Window::set_wrap_controls(bool p_enable) { wrap_controls = p_enable; if (wrap_controls) { child_controls_changed(); + } else { + _update_window_size(); } } @@ -1516,7 +1541,7 @@ void Window::_validate_property(PropertyInfo &property) const { Transform2D Window::get_screen_transform() const { Transform2D embedder_transform = Transform2D(); if (_get_embedder()) { - embedder_transform.translate(get_position()); + embedder_transform.translate_local(get_position()); embedder_transform = _get_embedder()->get_screen_transform() * embedder_transform; } return embedder_transform * Viewport::get_screen_transform(); diff --git a/scene/multiplayer/SCsub b/scene/multiplayer/SCsub deleted file mode 100644 index fc61250247..0000000000 --- a/scene/multiplayer/SCsub +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 09a283ea53..a5842106fb 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -130,18 +130,14 @@ #include "scene/main/http_request.h" #include "scene/main/instance_placeholder.h" #include "scene/main/missing_node.h" +#include "scene/main/multiplayer_api.h" #include "scene/main/resource_preloader.h" #include "scene/main/scene_tree.h" #include "scene/main/timer.h" #include "scene/main/viewport.h" #include "scene/main/window.h" -#include "scene/multiplayer/multiplayer_spawner.h" -#include "scene/multiplayer/multiplayer_synchronizer.h" -#include "scene/multiplayer/scene_cache_interface.h" -#include "scene/multiplayer/scene_replication_interface.h" -#include "scene/multiplayer/scene_rpc_interface.h" #include "scene/resources/animation_library.h" -#include "scene/resources/audio_stream_sample.h" +#include "scene/resources/audio_stream_wav.h" #include "scene/resources/bit_map.h" #include "scene/resources/bone_map.h" #include "scene/resources/box_shape_3d.h" @@ -248,6 +244,7 @@ #include "scene/3d/ray_cast_3d.h" #include "scene/3d/reflection_probe.h" #include "scene/3d/remote_transform_3d.h" +#include "scene/3d/shape_cast_3d.h" #include "scene/3d/skeleton_3d.h" #include "scene/3d/skeleton_ik_3d.h" #include "scene/3d/soft_dynamic_body_3d.h" @@ -322,9 +319,13 @@ void register_scene_types() { GDREGISTER_ABSTRACT_CLASS(Viewport); GDREGISTER_CLASS(SubViewport); GDREGISTER_CLASS(ViewportTexture); + + GDREGISTER_ABSTRACT_CLASS(MultiplayerPeer); + GDREGISTER_CLASS(MultiplayerPeerExtension); + GDREGISTER_ABSTRACT_CLASS(MultiplayerAPI); + GDREGISTER_CLASS(MultiplayerAPIExtension); + GDREGISTER_CLASS(HTTPRequest); - GDREGISTER_CLASS(MultiplayerSpawner); - GDREGISTER_CLASS(MultiplayerSynchronizer); GDREGISTER_CLASS(Timer); GDREGISTER_CLASS(CanvasLayer); GDREGISTER_CLASS(CanvasModulate); @@ -522,9 +523,7 @@ void register_scene_types() { GDREGISTER_CLASS(GPUParticlesAttractorVectorField3D); GDREGISTER_CLASS(CPUParticles3D); GDREGISTER_CLASS(Position3D); - GDREGISTER_CLASS(RootMotionView); - ClassDB::set_class_enabled("RootMotionView", false); // disabled by default, enabled by editor OS::get_singleton()->yield(); // may take time to init @@ -549,6 +548,7 @@ void register_scene_types() { GDREGISTER_CLASS(CollisionShape3D); GDREGISTER_CLASS(CollisionPolygon3D); GDREGISTER_CLASS(RayCast3D); + GDREGISTER_CLASS(ShapeCast3D); GDREGISTER_CLASS(MultiMeshInstance3D); GDREGISTER_CLASS(Curve3D); @@ -785,6 +785,7 @@ void register_scene_types() { GDREGISTER_CLASS(QuadMesh); GDREGISTER_CLASS(SphereMesh); GDREGISTER_CLASS(TextMesh); + GDREGISTER_CLASS(TorusMesh); GDREGISTER_CLASS(TubeTrailMesh); GDREGISTER_CLASS(RibbonTrailMesh); GDREGISTER_CLASS(PointMesh); @@ -870,13 +871,12 @@ void register_scene_types() { GDREGISTER_ABSTRACT_CLASS(Font); GDREGISTER_CLASS(FontFile); GDREGISTER_CLASS(FontVariation); + GDREGISTER_CLASS(SystemFont); GDREGISTER_CLASS(Curve); GDREGISTER_CLASS(LabelSettings); - GDREGISTER_CLASS(SceneReplicationConfig); - GDREGISTER_CLASS(TextLine); GDREGISTER_CLASS(TextParagraph); @@ -903,7 +903,7 @@ void register_scene_types() { GDREGISTER_CLASS(AudioStreamPlayer3D); #endif GDREGISTER_ABSTRACT_CLASS(VideoStream); - GDREGISTER_CLASS(AudioStreamSample); + GDREGISTER_CLASS(AudioStreamWAV); OS::get_singleton()->yield(); // may take time to init @@ -1090,6 +1090,9 @@ void register_scene_types() { ClassDB::add_compatibility_class("World", "World3D"); // Renamed during 4.0 alpha, added to ease transition between alphas. + ClassDB::add_compatibility_class("AudioStreamOGGVorbis", "AudioStreamOggVorbis"); + ClassDB::add_compatibility_class("AudioStreamSample", "AudioStreamWAV"); + ClassDB::add_compatibility_class("OGGPacketSequence", "OggPacketSequence"); ClassDB::add_compatibility_class("StreamCubemap", "CompressedCubemap"); ClassDB::add_compatibility_class("StreamCubemapArray", "CompressedCubemapArray"); ClassDB::add_compatibility_class("StreamTexture2D", "CompressedTexture2D"); @@ -1117,9 +1120,6 @@ void register_scene_types() { } SceneDebugger::initialize(); - SceneReplicationInterface::make_default(); - SceneRPCInterface::make_default(); - SceneCacheInterface::make_default(); } void initialize_theme() { diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 7183accc66..69b30b72b0 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -1563,33 +1563,35 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const { return -1; } -void Animation::track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition) { - ERR_FAIL_INDEX(p_track, tracks.size()); +int Animation::track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition) { + ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; + int ret = -1; + switch (t->type) { case TYPE_POSITION_3D: { - ERR_FAIL_COND((p_key.get_type() != Variant::VECTOR3) && (p_key.get_type() != Variant::VECTOR3I)); - int idx = position_track_insert_key(p_track, p_time, p_key); - track_set_key_transition(p_track, idx, p_transition); + ERR_FAIL_COND_V((p_key.get_type() != Variant::VECTOR3) && (p_key.get_type() != Variant::VECTOR3I), -1); + ret = position_track_insert_key(p_track, p_time, p_key); + track_set_key_transition(p_track, ret, p_transition); } break; case TYPE_ROTATION_3D: { - ERR_FAIL_COND((p_key.get_type() != Variant::QUATERNION) && (p_key.get_type() != Variant::BASIS)); - int idx = rotation_track_insert_key(p_track, p_time, p_key); - track_set_key_transition(p_track, idx, p_transition); + ERR_FAIL_COND_V((p_key.get_type() != Variant::QUATERNION) && (p_key.get_type() != Variant::BASIS), -1); + ret = rotation_track_insert_key(p_track, p_time, p_key); + track_set_key_transition(p_track, ret, p_transition); } break; case TYPE_SCALE_3D: { - ERR_FAIL_COND((p_key.get_type() != Variant::VECTOR3) && (p_key.get_type() != Variant::VECTOR3I)); - int idx = scale_track_insert_key(p_track, p_time, p_key); - track_set_key_transition(p_track, idx, p_transition); + ERR_FAIL_COND_V((p_key.get_type() != Variant::VECTOR3) && (p_key.get_type() != Variant::VECTOR3I), -1); + ret = scale_track_insert_key(p_track, p_time, p_key); + track_set_key_transition(p_track, ret, p_transition); } break; case TYPE_BLEND_SHAPE: { - ERR_FAIL_COND((p_key.get_type() != Variant::FLOAT) && (p_key.get_type() != Variant::INT)); - int idx = blend_shape_track_insert_key(p_track, p_time, p_key); - track_set_key_transition(p_track, idx, p_transition); + ERR_FAIL_COND_V((p_key.get_type() != Variant::FLOAT) && (p_key.get_type() != Variant::INT), -1); + ret = blend_shape_track_insert_key(p_track, p_time, p_key); + track_set_key_transition(p_track, ret, p_transition); } break; case TYPE_VALUE: { @@ -1599,17 +1601,17 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke k.time = p_time; k.transition = p_transition; k.value = p_key; - _insert(p_time, vt->values, k); + ret = _insert(p_time, vt->values, k); } break; case TYPE_METHOD: { MethodTrack *mt = static_cast<MethodTrack *>(t); - ERR_FAIL_COND(p_key.get_type() != Variant::DICTIONARY); + ERR_FAIL_COND_V(p_key.get_type() != Variant::DICTIONARY, -1); Dictionary d = p_key; - ERR_FAIL_COND(!d.has("method") || (d["method"].get_type() != Variant::STRING_NAME && d["method"].get_type() != Variant::STRING)); - ERR_FAIL_COND(!d.has("args") || !d["args"].is_array()); + ERR_FAIL_COND_V(!d.has("method") || (d["method"].get_type() != Variant::STRING_NAME && d["method"].get_type() != Variant::STRING), -1); + ERR_FAIL_COND_V(!d.has("args") || !d["args"].is_array(), -1); MethodKey k; @@ -1618,14 +1620,14 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke k.method = d["method"]; k.params = d["args"]; - _insert(p_time, mt->methods, k); + ret = _insert(p_time, mt->methods, k); } break; case TYPE_BEZIER: { BezierTrack *bt = static_cast<BezierTrack *>(t); Array arr = p_key; - ERR_FAIL_COND(arr.size() != 6); + ERR_FAIL_COND_V(arr.size() != 6, -1); TKey<BezierKey> k; k.time = p_time; @@ -1635,23 +1637,23 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke k.value.out_handle.x = arr[3]; k.value.out_handle.y = arr[4]; k.value.handle_mode = static_cast<HandleMode>((int)arr[5]); - _insert(p_time, bt->values, k); + ret = _insert(p_time, bt->values, k); } break; case TYPE_AUDIO: { AudioTrack *at = static_cast<AudioTrack *>(t); Dictionary k = p_key; - ERR_FAIL_COND(!k.has("start_offset")); - ERR_FAIL_COND(!k.has("end_offset")); - ERR_FAIL_COND(!k.has("stream")); + ERR_FAIL_COND_V(!k.has("start_offset"), -1); + ERR_FAIL_COND_V(!k.has("end_offset"), -1); + ERR_FAIL_COND_V(!k.has("stream"), -1); TKey<AudioKey> ak; ak.time = p_time; ak.value.start_offset = k["start_offset"]; ak.value.end_offset = k["end_offset"]; ak.value.stream = k["stream"]; - _insert(p_time, at->values, ak); + ret = _insert(p_time, at->values, ak); } break; case TYPE_ANIMATION: { @@ -1661,12 +1663,14 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke ak.time = p_time; ak.value = p_key; - _insert(p_time, at->values, ak); + ret = _insert(p_time, at->values, ak); } break; } emit_changed(); + + return ret; } int Animation::track_get_key_count(int p_track) const { @@ -2302,7 +2306,7 @@ Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a } Quaternion Animation::_cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c) const { - return p_a.cubic_slerp(p_b, p_pre_a, p_post_b, p_c); + return p_a.spherical_cubic_interpolate(p_b, p_pre_a, p_post_b, p_c); } Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c) const { @@ -2363,7 +2367,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a Quaternion pa = p_pre_a; Quaternion pb = p_post_b; - return a.cubic_slerp(b, pa, pb, p_c); + return a.spherical_cubic_interpolate(b, pa, pb, p_c); } case Variant::AABB: { AABB a = p_a; diff --git a/scene/resources/animation.h b/scene/resources/animation.h index abbcaa92bc..bf9f786a0d 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -392,7 +392,7 @@ public: void track_set_enabled(int p_track, bool p_enabled); bool track_is_enabled(int p_track) const; - void track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition = 1); + int track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition = 1); void track_set_key_transition(int p_track, int p_key_idx, real_t p_transition); void track_set_key_value(int p_track, int p_key_idx, const Variant &p_value); void track_set_key_time(int p_track, int p_key_idx, double p_time); diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_wav.cpp index dcd36284d4..a87c8272ea 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_wav.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_stream_sample.cpp */ +/* audio_stream_wav.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "audio_stream_sample.h" +#include "audio_stream_wav.h" #include "core/io/file_access.h" #include "core/io/marshalls.h" -void AudioStreamPlaybackSample::start(float p_from_pos) { - if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) { +void AudioStreamPlaybackWAV::start(float p_from_pos) { + if (base->format == AudioStreamWAV::FORMAT_IMA_ADPCM) { //no seeking in IMA_ADPCM for (int i = 0; i < 2; i++) { ima_adpcm[i].step_index = 0; @@ -55,24 +55,24 @@ void AudioStreamPlaybackSample::start(float p_from_pos) { active = true; } -void AudioStreamPlaybackSample::stop() { +void AudioStreamPlaybackWAV::stop() { active = false; } -bool AudioStreamPlaybackSample::is_playing() const { +bool AudioStreamPlaybackWAV::is_playing() const { return active; } -int AudioStreamPlaybackSample::get_loop_count() const { +int AudioStreamPlaybackWAV::get_loop_count() const { return 0; } -float AudioStreamPlaybackSample::get_playback_position() const { +float AudioStreamPlaybackWAV::get_playback_position() const { return float(offset >> MIX_FRAC_BITS) / base->mix_rate; } -void AudioStreamPlaybackSample::seek(float p_time) { - if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) { +void AudioStreamPlaybackWAV::seek(float p_time) { + if (base->format == AudioStreamWAV::FORMAT_IMA_ADPCM) { return; //no seeking in ima-adpcm } @@ -87,7 +87,7 @@ void AudioStreamPlaybackSample::seek(float p_time) { } template <class Depth, bool is_stereo, bool is_ima_adpcm> -void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm) { +void AudioStreamPlaybackWAV::do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm) { // this function will be compiled branchless by any decent compiler int32_t final, final_r, next, next_r; @@ -124,7 +124,7 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds ima_adpcm[i].last_nibble++; const uint8_t *src_ptr = (const uint8_t *)base->data; - src_ptr += AudioStreamSample::DATA_PAD; + src_ptr += AudioStreamWAV::DATA_PAD; uint8_t nbb = src_ptr[(ima_adpcm[i].last_nibble >> 1) * (is_stereo ? 2 : 1) + i]; nibble = (ima_adpcm[i].last_nibble & 1) ? (nbb >> 4) : (nbb & 0xF); @@ -221,7 +221,7 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds } } -int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { +int AudioStreamPlaybackWAV::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { if (!base->data || !active) { for (int i = 0; i < p_frames; i++) { p_buffer[i] = AudioFrame(0, 0); @@ -231,13 +231,13 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int int len = base->data_bytes; switch (base->format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: len /= 1; break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: len /= 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: len *= 2; break; } @@ -251,13 +251,13 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int int64_t loop_begin_fp = ((int64_t)base->loop_begin << MIX_FRAC_BITS); int64_t loop_end_fp = ((int64_t)base->loop_end << MIX_FRAC_BITS); int64_t length_fp = ((int64_t)len << MIX_FRAC_BITS); - int64_t begin_limit = (base->loop_mode != AudioStreamSample::LOOP_DISABLED) ? loop_begin_fp : 0; - int64_t end_limit = (base->loop_mode != AudioStreamSample::LOOP_DISABLED) ? loop_end_fp : length_fp; + int64_t begin_limit = (base->loop_mode != AudioStreamWAV::LOOP_DISABLED) ? loop_begin_fp : 0; + int64_t end_limit = (base->loop_mode != AudioStreamWAV::LOOP_DISABLED) ? loop_end_fp : length_fp; bool is_stereo = base->stereo; int32_t todo = p_frames; - if (base->loop_mode == AudioStreamSample::LOOP_BACKWARD) { + if (base->loop_mode == AudioStreamWAV::LOOP_BACKWARD) { sign = -1; } @@ -271,20 +271,20 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int //looping - AudioStreamSample::LoopMode loop_format = base->loop_mode; - AudioStreamSample::Format format = base->format; + AudioStreamWAV::LoopMode loop_format = base->loop_mode; + AudioStreamWAV::Format format = base->format; /* audio data */ uint8_t *dataptr = (uint8_t *)base->data; - const void *data = dataptr + AudioStreamSample::DATA_PAD; + const void *data = dataptr + AudioStreamWAV::DATA_PAD; AudioFrame *dst_buff = p_buffer; - if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { - if (loop_format != AudioStreamSample::LOOP_DISABLED) { + if (format == AudioStreamWAV::FORMAT_IMA_ADPCM) { + if (loop_format != AudioStreamWAV::LOOP_DISABLED) { ima_adpcm[0].loop_pos = loop_begin_fp >> MIX_FRAC_BITS; ima_adpcm[1].loop_pos = loop_begin_fp >> MIX_FRAC_BITS; - loop_format = AudioStreamSample::LOOP_FORWARD; + loop_format = AudioStreamWAV::LOOP_FORWARD; } } @@ -297,9 +297,9 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int if (increment < 0) { /* going backwards */ - if (loop_format != AudioStreamSample::LOOP_DISABLED && offset < loop_begin_fp) { + if (loop_format != AudioStreamWAV::LOOP_DISABLED && offset < loop_begin_fp) { /* loopstart reached */ - if (loop_format == AudioStreamSample::LOOP_PINGPONG) { + if (loop_format == AudioStreamWAV::LOOP_PINGPONG) { /* bounce ping pong */ offset = loop_begin_fp + (loop_begin_fp - offset); increment = -increment; @@ -317,10 +317,10 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int } } else { /* going forward */ - if (loop_format != AudioStreamSample::LOOP_DISABLED && offset >= loop_end_fp) { + if (loop_format != AudioStreamWAV::LOOP_DISABLED && offset >= loop_end_fp) { /* loopend reached */ - if (loop_format == AudioStreamSample::LOOP_PINGPONG) { + if (loop_format == AudioStreamWAV::LOOP_PINGPONG) { /* bounce ping pong */ offset = loop_end_fp - (offset - loop_end_fp); increment = -increment; @@ -328,7 +328,7 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int } else { /* go to loop-begin */ - if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { + if (format == AudioStreamWAV::FORMAT_IMA_ADPCM) { for (int i = 0; i < 2; i++) { ima_adpcm[i].step_index = ima_adpcm[i].loop_step_index; ima_adpcm[i].predictor = ima_adpcm[i].loop_predictor; @@ -366,14 +366,14 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int todo -= target; switch (base->format) { - case AudioStreamSample::FORMAT_8_BITS: { + case AudioStreamWAV::FORMAT_8_BITS: { if (is_stereo) { do_resample<int8_t, true, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); } else { do_resample<int8_t, false, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); } } break; - case AudioStreamSample::FORMAT_16_BITS: { + case AudioStreamWAV::FORMAT_16_BITS: { if (is_stereo) { do_resample<int16_t, true, false>((int16_t *)data, dst_buff, offset, increment, target, ima_adpcm); } else { @@ -381,7 +381,7 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int } } break; - case AudioStreamSample::FORMAT_IMA_ADPCM: { + case AudioStreamWAV::FORMAT_IMA_ADPCM: { if (is_stereo) { do_resample<int8_t, true, true>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); } else { @@ -406,73 +406,73 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int return p_frames; } -void AudioStreamPlaybackSample::tag_used_streams() { +void AudioStreamPlaybackWAV::tag_used_streams() { base->tag_used(get_playback_position()); } -AudioStreamPlaybackSample::AudioStreamPlaybackSample() {} +AudioStreamPlaybackWAV::AudioStreamPlaybackWAV() {} ///////////////////// -void AudioStreamSample::set_format(Format p_format) { +void AudioStreamWAV::set_format(Format p_format) { format = p_format; } -AudioStreamSample::Format AudioStreamSample::get_format() const { +AudioStreamWAV::Format AudioStreamWAV::get_format() const { return format; } -void AudioStreamSample::set_loop_mode(LoopMode p_loop_mode) { +void AudioStreamWAV::set_loop_mode(LoopMode p_loop_mode) { loop_mode = p_loop_mode; } -AudioStreamSample::LoopMode AudioStreamSample::get_loop_mode() const { +AudioStreamWAV::LoopMode AudioStreamWAV::get_loop_mode() const { return loop_mode; } -void AudioStreamSample::set_loop_begin(int p_frame) { +void AudioStreamWAV::set_loop_begin(int p_frame) { loop_begin = p_frame; } -int AudioStreamSample::get_loop_begin() const { +int AudioStreamWAV::get_loop_begin() const { return loop_begin; } -void AudioStreamSample::set_loop_end(int p_frame) { +void AudioStreamWAV::set_loop_end(int p_frame) { loop_end = p_frame; } -int AudioStreamSample::get_loop_end() const { +int AudioStreamWAV::get_loop_end() const { return loop_end; } -void AudioStreamSample::set_mix_rate(int p_hz) { +void AudioStreamWAV::set_mix_rate(int p_hz) { ERR_FAIL_COND(p_hz == 0); mix_rate = p_hz; } -int AudioStreamSample::get_mix_rate() const { +int AudioStreamWAV::get_mix_rate() const { return mix_rate; } -void AudioStreamSample::set_stereo(bool p_enable) { +void AudioStreamWAV::set_stereo(bool p_enable) { stereo = p_enable; } -bool AudioStreamSample::is_stereo() const { +bool AudioStreamWAV::is_stereo() const { return stereo; } -float AudioStreamSample::get_length() const { +float AudioStreamWAV::get_length() const { int len = data_bytes; switch (format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: len /= 1; break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: len /= 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: len *= 2; break; } @@ -484,11 +484,11 @@ float AudioStreamSample::get_length() const { return float(len) / mix_rate; } -bool AudioStreamSample::is_monophonic() const { +bool AudioStreamWAV::is_monophonic() const { return false; } -void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) { +void AudioStreamWAV::set_data(const Vector<uint8_t> &p_data) { AudioServer::get_singleton()->lock(); if (data) { memfree(data); @@ -510,7 +510,7 @@ void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) { AudioServer::get_singleton()->unlock(); } -Vector<uint8_t> AudioStreamSample::get_data() const { +Vector<uint8_t> AudioStreamWAV::get_data() const { Vector<uint8_t> pv; if (data) { @@ -525,8 +525,8 @@ Vector<uint8_t> AudioStreamSample::get_data() const { return pv; } -Error AudioStreamSample::save_to_wav(const String &p_path) { - if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { +Error AudioStreamWAV::save_to_wav(const String &p_path) { + if (format == AudioStreamWAV::FORMAT_IMA_ADPCM) { WARN_PRINT("Saving IMA_ADPC samples are not supported yet"); return ERR_UNAVAILABLE; } @@ -544,13 +544,13 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { int byte_pr_sample = 0; switch (format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: byte_pr_sample = 1; break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: byte_pr_sample = 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: byte_pr_sample = 4; break; } @@ -583,19 +583,19 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { Vector<uint8_t> data = get_data(); const uint8_t *read_data = data.ptr(); switch (format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: for (unsigned int i = 0; i < data_bytes; i++) { uint8_t data_point = (read_data[i] + 128); file->store_8(data_point); } break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: for (unsigned int i = 0; i < data_bytes / 2; i++) { uint16_t data_point = decode_uint16(&read_data[i * 2]); file->store_16(data_point); } break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: //Unimplemented break; } @@ -603,40 +603,40 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { return OK; } -Ref<AudioStreamPlayback> AudioStreamSample::instantiate_playback() { - Ref<AudioStreamPlaybackSample> sample; +Ref<AudioStreamPlayback> AudioStreamWAV::instantiate_playback() { + Ref<AudioStreamPlaybackWAV> sample; sample.instantiate(); - sample->base = Ref<AudioStreamSample>(this); + sample->base = Ref<AudioStreamWAV>(this); return sample; } -String AudioStreamSample::get_stream_name() const { +String AudioStreamWAV::get_stream_name() const { return ""; } -void AudioStreamSample::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamSample::set_data); - ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamSample::get_data); +void AudioStreamWAV::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamWAV::set_data); + ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamWAV::get_data); - ClassDB::bind_method(D_METHOD("set_format", "format"), &AudioStreamSample::set_format); - ClassDB::bind_method(D_METHOD("get_format"), &AudioStreamSample::get_format); + ClassDB::bind_method(D_METHOD("set_format", "format"), &AudioStreamWAV::set_format); + ClassDB::bind_method(D_METHOD("get_format"), &AudioStreamWAV::get_format); - ClassDB::bind_method(D_METHOD("set_loop_mode", "loop_mode"), &AudioStreamSample::set_loop_mode); - ClassDB::bind_method(D_METHOD("get_loop_mode"), &AudioStreamSample::get_loop_mode); + ClassDB::bind_method(D_METHOD("set_loop_mode", "loop_mode"), &AudioStreamWAV::set_loop_mode); + ClassDB::bind_method(D_METHOD("get_loop_mode"), &AudioStreamWAV::get_loop_mode); - ClassDB::bind_method(D_METHOD("set_loop_begin", "loop_begin"), &AudioStreamSample::set_loop_begin); - ClassDB::bind_method(D_METHOD("get_loop_begin"), &AudioStreamSample::get_loop_begin); + ClassDB::bind_method(D_METHOD("set_loop_begin", "loop_begin"), &AudioStreamWAV::set_loop_begin); + ClassDB::bind_method(D_METHOD("get_loop_begin"), &AudioStreamWAV::get_loop_begin); - ClassDB::bind_method(D_METHOD("set_loop_end", "loop_end"), &AudioStreamSample::set_loop_end); - ClassDB::bind_method(D_METHOD("get_loop_end"), &AudioStreamSample::get_loop_end); + ClassDB::bind_method(D_METHOD("set_loop_end", "loop_end"), &AudioStreamWAV::set_loop_end); + ClassDB::bind_method(D_METHOD("get_loop_end"), &AudioStreamWAV::get_loop_end); - ClassDB::bind_method(D_METHOD("set_mix_rate", "mix_rate"), &AudioStreamSample::set_mix_rate); - ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioStreamSample::get_mix_rate); + ClassDB::bind_method(D_METHOD("set_mix_rate", "mix_rate"), &AudioStreamWAV::set_mix_rate); + ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioStreamWAV::get_mix_rate); - ClassDB::bind_method(D_METHOD("set_stereo", "stereo"), &AudioStreamSample::set_stereo); - ClassDB::bind_method(D_METHOD("is_stereo"), &AudioStreamSample::is_stereo); + ClassDB::bind_method(D_METHOD("set_stereo", "stereo"), &AudioStreamWAV::set_stereo); + ClassDB::bind_method(D_METHOD("is_stereo"), &AudioStreamWAV::is_stereo); - ClassDB::bind_method(D_METHOD("save_to_wav", "path"), &AudioStreamSample::save_to_wav); + ClassDB::bind_method(D_METHOD("save_to_wav", "path"), &AudioStreamWAV::save_to_wav); ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_data", "get_data"); ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA-ADPCM"), "set_format", "get_format"); @@ -656,9 +656,9 @@ void AudioStreamSample::_bind_methods() { BIND_ENUM_CONSTANT(LOOP_BACKWARD); } -AudioStreamSample::AudioStreamSample() {} +AudioStreamWAV::AudioStreamWAV() {} -AudioStreamSample::~AudioStreamSample() { +AudioStreamWAV::~AudioStreamWAV() { if (data) { memfree(data); data = nullptr; diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_wav.h index 2e694cffe2..d800388d96 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_wav.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_stream_sample.h */ +/* audio_stream_wav.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIO_STREAM_SAMPLE_H -#define AUDIO_STREAM_SAMPLE_H +#ifndef AUDIO_STREAM_WAV_H +#define AUDIO_STREAM_WAV_H #include "servers/audio/audio_stream.h" -class AudioStreamSample; +class AudioStreamWAV; -class AudioStreamPlaybackSample : public AudioStreamPlayback { - GDCLASS(AudioStreamPlaybackSample, AudioStreamPlayback); +class AudioStreamPlaybackWAV : public AudioStreamPlayback { + GDCLASS(AudioStreamPlaybackWAV, AudioStreamPlayback); enum { MIX_FRAC_BITS = 13, MIX_FRAC_LEN = (1 << MIX_FRAC_BITS), @@ -57,8 +57,8 @@ class AudioStreamPlaybackSample : public AudioStreamPlayback { int64_t offset = 0; int sign = 1; bool active = false; - friend class AudioStreamSample; - Ref<AudioStreamSample> base; + friend class AudioStreamWAV; + Ref<AudioStreamWAV> base; template <class Depth, bool is_stereo, bool is_ima_adpcm> void do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm); @@ -77,11 +77,11 @@ public: virtual void tag_used_streams() override; - AudioStreamPlaybackSample(); + AudioStreamPlaybackWAV(); }; -class AudioStreamSample : public AudioStream { - GDCLASS(AudioStreamSample, AudioStream); +class AudioStreamWAV : public AudioStream { + GDCLASS(AudioStreamWAV, AudioStream); RES_BASE_EXTENSION("sample") public: @@ -100,7 +100,7 @@ public: }; private: - friend class AudioStreamPlaybackSample; + friend class AudioStreamPlaybackWAV; enum { DATA_PAD = 16 //padding for interpolation @@ -149,11 +149,11 @@ public: virtual Ref<AudioStreamPlayback> instantiate_playback() override; virtual String get_stream_name() const override; - AudioStreamSample(); - ~AudioStreamSample(); + AudioStreamWAV(); + ~AudioStreamWAV(); }; -VARIANT_ENUM_CAST(AudioStreamSample::Format) -VARIANT_ENUM_CAST(AudioStreamSample::LoopMode) +VARIANT_ENUM_CAST(AudioStreamWAV::Format) +VARIANT_ENUM_CAST(AudioStreamWAV::LoopMode) -#endif // AUDIO_STREAM_SAMPLE_H +#endif // AUDIO_STREAM_WAV_H diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 520a0a04ed..fa375795c1 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -741,7 +741,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_selected_color", "Tree", control_font_pressed_color); theme->set_color("font_outline_color", "Tree", Color(1, 1, 1)); theme->set_color("guide_color", "Tree", Color(0.7, 0.7, 0.7, 0.25)); - theme->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2)); + theme->set_color("drop_position_color", "Tree", Color(1, 1, 1)); theme->set_color("relationship_line_color", "Tree", Color(0.27, 0.27, 0.27)); theme->set_color("parent_hl_line_color", "Tree", Color(0.27, 0.27, 0.27)); theme->set_color("children_hl_line_color", "Tree", Color(0.27, 0.27, 0.27)); @@ -776,7 +776,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_color", "ItemList", control_font_lower_color); theme->set_color("font_selected_color", "ItemList", control_font_pressed_color); theme->set_color("font_outline_color", "ItemList", Color(1, 1, 1)); - theme->set_color("guide_color", "ItemList", Color(0, 0, 0, 0.1)); + theme->set_color("guide_color", "ItemList", Color(0.7, 0.7, 0.7, 0.25)); theme->set_stylebox("selected", "ItemList", make_flat_stylebox(style_selected_color)); theme->set_stylebox("selected_focus", "ItemList", make_flat_stylebox(style_selected_color)); theme->set_stylebox("cursor", "ItemList", focus); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index a8d4903dad..d361b34da8 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1249,8 +1249,8 @@ void Environment::_bind_methods() { ADD_GROUP("SSR", "ssr_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssr_enabled"), "set_ssr_enabled", "is_ssr_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "ssr_max_steps", PROPERTY_HINT_RANGE, "1,512,1"), "set_ssr_max_steps", "get_ssr_max_steps"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_in", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_ssr_fade_in", "get_ssr_fade_in"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_out", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_ssr_fade_out", "get_ssr_fade_out"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_depth_tolerance", PROPERTY_HINT_RANGE, "0.01,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance"); // SSAO @@ -1277,7 +1277,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.01,16,0.01,or_greater"), "set_ssao_radius", "get_ssao_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_ssao_intensity", "get_ssao_intensity"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_power", PROPERTY_HINT_EXP_EASING), "set_ssao_power", "get_ssao_power"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_power", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_ssao_power", "get_ssao_power"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_detail", PROPERTY_HINT_RANGE, "0,5,0.01"), "set_ssao_detail", "get_ssao_detail"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_horizon", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ssao_horizon", "get_ssao_horizon"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_sharpness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ssao_sharpness", "get_ssao_sharpness"); @@ -1337,8 +1337,10 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_bounce_feedback", PROPERTY_HINT_RANGE, "0,1.99,0.01"), "set_sdfgi_bounce_feedback", "get_sdfgi_bounce_feedback"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_cascades", PROPERTY_HINT_RANGE, "1,8,1"), "set_sdfgi_cascades", "get_sdfgi_cascades"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_min_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_sdfgi_min_cell_size", "get_sdfgi_min_cell_size"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_cascade0_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_cascade0_distance", "get_sdfgi_cascade0_distance"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_max_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_max_distance", "get_sdfgi_max_distance"); + // Don't store the values of `sdfgi_cascade0_distance` and `sdfgi_max_distance` + // as they're derived from `sdfgi_min_cell_size`. + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_cascade0_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater", PROPERTY_USAGE_EDITOR), "set_sdfgi_cascade0_distance", "get_sdfgi_cascade0_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_max_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater", PROPERTY_USAGE_EDITOR), "set_sdfgi_max_distance", "get_sdfgi_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_y_scale", PROPERTY_HINT_ENUM, "50% (Compact),75% (Balanced),100% (Sparse)"), "set_sdfgi_y_scale", "get_sdfgi_y_scale"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_energy"), "set_sdfgi_energy", "get_sdfgi_energy"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_normal_bias"), "set_sdfgi_normal_bias", "get_sdfgi_normal_bias"); @@ -1462,7 +1464,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_gi_inject", PROPERTY_HINT_RANGE, "0.0,16,0.01,exp"), "set_volumetric_fog_gi_inject", "get_volumetric_fog_gi_inject"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_anisotropy", PROPERTY_HINT_RANGE, "-0.9,0.9,0.01"), "set_volumetric_fog_anisotropy", "get_volumetric_fog_anisotropy"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_ambient_inject", PROPERTY_HINT_RANGE, "0.0,16,0.01,exp"), "set_volumetric_fog_ambient_inject", "get_volumetric_fog_ambient_inject"); ADD_SUBGROUP("Temporal Reprojection", "volumetric_fog_temporal_reprojection_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_temporal_reprojection_enabled"), "set_volumetric_fog_temporal_reprojection_enabled", "is_volumetric_fog_temporal_reprojection_enabled"); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index b71fe8904a..385d815230 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -175,10 +175,10 @@ private: // Fog bool fog_enabled = false; - Color fog_light_color = Color(0.5, 0.6, 0.7); + Color fog_light_color = Color(0.518, 0.553, 0.608); float fog_light_energy = 1.0; float fog_sun_scatter = 0.0; - float fog_density = 0.001; + float fog_density = 0.01; float fog_height = 0.0; float fog_height_density = 0.0; //can be negative to invert effect float fog_aerial_perspective = 0.0; @@ -194,8 +194,8 @@ private: float volumetric_fog_anisotropy = 0.2; float volumetric_fog_length = 64.0; float volumetric_fog_detail_spread = 2.0; - float volumetric_fog_gi_inject = 0.0; - float volumetric_fog_ambient_inject = false; + float volumetric_fog_gi_inject = 1.0; + float volumetric_fog_ambient_inject = 0.0; bool volumetric_fog_temporal_reproject = true; float volumetric_fog_temporal_reproject_amount = 0.9; void _update_volumetric_fog(); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index dd728b3af1..619036d296 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -157,7 +157,7 @@ void Font::set_fallbacks(const TypedArray<Font> &p_fallbacks) { for (int i = 0; i < fallbacks.size(); i++) { Ref<Font> f = fallbacks[i]; if (f.is_valid()) { - f->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + f->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); } } _invalidate_rids(); @@ -2534,7 +2534,7 @@ void FontVariation::set_base_font(const Ref<Font> &p_font) { } base_font = p_font; if (base_font.is_valid()) { - base_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + base_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); } _invalidate_rids(); notify_property_list_changed(); @@ -2565,7 +2565,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const { Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); if (f.is_valid()) { theme_font = f; - theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); } return f; } @@ -2582,7 +2582,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const { Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); if (f.is_valid()) { theme_font = f; - theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); } return f; } @@ -2592,7 +2592,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const { Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); if (f.is_valid()) { theme_font = f; - theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); } return f; } @@ -2693,3 +2693,374 @@ FontVariation::FontVariation() { FontVariation::~FontVariation() { reset_state(); } + +/*************************************************************************/ +/* SystemFont */ +/*************************************************************************/ + +void SystemFont::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &SystemFont::set_antialiased); + ClassDB::bind_method(D_METHOD("is_antialiased"), &SystemFont::is_antialiased); + + ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "generate_mipmaps"), &SystemFont::set_generate_mipmaps); + ClassDB::bind_method(D_METHOD("get_generate_mipmaps"), &SystemFont::get_generate_mipmaps); + + ClassDB::bind_method(D_METHOD("set_force_autohinter", "force_autohinter"), &SystemFont::set_force_autohinter); + ClassDB::bind_method(D_METHOD("is_force_autohinter"), &SystemFont::is_force_autohinter); + + ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &SystemFont::set_hinting); + ClassDB::bind_method(D_METHOD("get_hinting"), &SystemFont::get_hinting); + + ClassDB::bind_method(D_METHOD("set_subpixel_positioning", "subpixel_positioning"), &SystemFont::set_subpixel_positioning); + ClassDB::bind_method(D_METHOD("get_subpixel_positioning"), &SystemFont::get_subpixel_positioning); + + ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &SystemFont::set_oversampling); + ClassDB::bind_method(D_METHOD("get_oversampling"), &SystemFont::get_oversampling); + + ClassDB::bind_method(D_METHOD("get_font_names"), &SystemFont::get_font_names); + ClassDB::bind_method(D_METHOD("set_font_names", "names"), &SystemFont::set_font_names); + + ClassDB::bind_method(D_METHOD("set_font_style", "style"), &SystemFont::set_font_style); + + ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "font_names"), "set_font_names", "get_font_names"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_FLAGS, "Bold,Italic"), "set_font_style", "get_font_style"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "is_antialiased"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps"), "set_generate_mipmaps", "get_generate_mipmaps"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter"), "set_force_autohinter", "is_force_autohinter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel"), "set_subpixel_positioning", "get_subpixel_positioning"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), "set_oversampling", "get_oversampling"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), "set_fallbacks", "get_fallbacks"); +} + +void SystemFont::_update_rids() const { + Ref<Font> f = _get_base_font_or_default(); + + rids.clear(); + if (fallbacks.is_empty() && f.is_valid()) { + RID rid = _get_rid(); + if (rid.is_valid()) { + rids.push_back(rid); + } + + const TypedArray<Font> &base_fallbacks = f->get_fallbacks(); + for (int i = 0; i < base_fallbacks.size(); i++) { + _update_rids_fb(base_fallbacks[i], 0); + } + } else { + _update_rids_fb(const_cast<SystemFont *>(this), 0); + } + dirty_rids = false; +} + +void SystemFont::_update_base_font() { + if (base_font.is_valid()) { + base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids)); + base_font.unref(); + } + + face_indeces.clear(); + ftr_weight = 0; + ftr_italic = 0; + for (const String &E : names) { + if (E.is_empty()) { + continue; + } + + String path = OS::get_singleton()->get_system_font_path(E, style & TextServer::FONT_BOLD, style & TextServer::FONT_ITALIC); + if (path.is_empty()) { + continue; + } + Ref<FontFile> file; + file.instantiate(); + Error err = file->load_dynamic_font(path); + if (err != OK) { + continue; + } + + // If it's a font collection check all faces to match requested style. + for (int i = 0; i < file->get_face_count(); i++) { + file->set_face_index(0, i); + if (((file->get_font_style() & TextServer::FONT_BOLD) == (style & TextServer::FONT_BOLD)) && ((file->get_font_style() & TextServer::FONT_ITALIC) == (style & TextServer::FONT_ITALIC))) { + face_indeces.push_back(i); + } + } + if (face_indeces.is_empty()) { + face_indeces.push_back(0); + } + file->set_face_index(0, face_indeces[0]); + + // If it's a variable font, apply weight and italic coordinates to match requested style. + Dictionary ftr = file->get_supported_variation_list(); + if ((style & TextServer::FONT_BOLD) && ftr.has(TS->name_to_tag("weight"))) { + ftr_weight = 700; + } + if ((style & TextServer::FONT_ITALIC) && ftr.has(TS->name_to_tag("italic"))) { + ftr_italic = 1; + } + + // Apply font rendering settings. + file->set_antialiased(antialiased); + file->set_generate_mipmaps(mipmaps); + file->set_force_autohinter(force_autohinter); + file->set_hinting(hinting); + file->set_subpixel_positioning(subpixel_positioning); + file->set_oversampling(oversampling); + + base_font = file; + } + + if (base_font.is_valid()) { + base_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); + } + + _invalidate_rids(); + notify_property_list_changed(); +} + +void SystemFont::reset_state() { + if (base_font.is_valid()) { + base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids)); + base_font.unref(); + } + + if (theme_font.is_valid()) { + theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids)); + theme_font.unref(); + } + + names.clear(); + face_indeces.clear(); + ftr_weight = 0; + ftr_italic = 0; + style = 0; + antialiased = true; + mipmaps = false; + force_autohinter = false; + hinting = TextServer::HINTING_LIGHT; + subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED; + oversampling = 0.f; + + Font::reset_state(); +} + +Ref<Font> SystemFont::_get_base_font_or_default() const { + if (theme_font.is_valid()) { + theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids)); + theme_font.unref(); + } + + if (base_font.is_valid()) { + return base_font; + } + + // Check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + List<StringName> theme_types; + Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + + for (const StringName &E : theme_types) { + if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (f.is_valid()) { + theme_font = f; + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); + } + return f; + } + } + } + + // Lastly, fall back on the items defined in the default Theme, if they exist. + if (Theme::get_default().is_valid()) { + List<StringName> theme_types; + Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + + for (const StringName &E : theme_types) { + if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (f.is_valid()) { + theme_font = f; + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); + } + return f; + } + } + + // If they don't exist, use any type to return the default/empty value. + Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); + if (f.is_valid()) { + theme_font = f; + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); + } + return f; + } + + return Ref<Font>(); +} + +void SystemFont::set_antialiased(bool p_antialiased) { + if (antialiased != p_antialiased) { + antialiased = p_antialiased; + if (base_font.is_valid()) { + base_font->set_antialiased(antialiased); + } + emit_changed(); + } +} + +bool SystemFont::is_antialiased() const { + return antialiased; +} + +void SystemFont::set_generate_mipmaps(bool p_generate_mipmaps) { + if (mipmaps != p_generate_mipmaps) { + mipmaps = p_generate_mipmaps; + if (base_font.is_valid()) { + base_font->set_generate_mipmaps(mipmaps); + } + emit_changed(); + } +} + +bool SystemFont::get_generate_mipmaps() const { + return mipmaps; +} + +void SystemFont::set_force_autohinter(bool p_force_autohinter) { + if (force_autohinter != p_force_autohinter) { + force_autohinter = p_force_autohinter; + if (base_font.is_valid()) { + base_font->set_force_autohinter(force_autohinter); + } + emit_changed(); + } +} + +bool SystemFont::is_force_autohinter() const { + return force_autohinter; +} + +void SystemFont::set_hinting(TextServer::Hinting p_hinting) { + if (hinting != p_hinting) { + hinting = p_hinting; + if (base_font.is_valid()) { + base_font->set_hinting(hinting); + } + emit_changed(); + } +} + +TextServer::Hinting SystemFont::get_hinting() const { + return hinting; +} + +void SystemFont::set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel) { + if (subpixel_positioning != p_subpixel) { + subpixel_positioning = p_subpixel; + if (base_font.is_valid()) { + base_font->set_subpixel_positioning(subpixel_positioning); + } + emit_changed(); + } +} + +TextServer::SubpixelPositioning SystemFont::get_subpixel_positioning() const { + return subpixel_positioning; +} + +void SystemFont::set_oversampling(real_t p_oversampling) { + if (oversampling != p_oversampling) { + oversampling = p_oversampling; + if (base_font.is_valid()) { + base_font->set_oversampling(oversampling); + } + emit_changed(); + } +} + +real_t SystemFont::get_oversampling() const { + return oversampling; +} + +void SystemFont::set_font_names(const PackedStringArray &p_names) { + if (names != p_names) { + names = p_names; + _update_base_font(); + } +} + +PackedStringArray SystemFont::get_font_names() const { + return names; +} + +void SystemFont::set_font_style(BitField<TextServer::FontStyle> p_style) { + if (style != p_style) { + style = p_style; + _update_base_font(); + } +} + +BitField<TextServer::FontStyle> SystemFont::get_font_style() const { + return style; +} + +int SystemFont::get_spacing(TextServer::SpacingType p_spacing) const { + if (base_font.is_valid()) { + return base_font->get_spacing(p_spacing); + } else { + return 0; + } +} + +RID SystemFont::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const { + Ref<Font> f = _get_base_font_or_default(); + if (f.is_valid()) { + Dictionary var = p_variation_coordinates; + if (ftr_weight > 0 && !var.has(TS->name_to_tag("weight"))) { + var[TS->name_to_tag("weight")] = ftr_weight; + } + if (ftr_italic > 0 && !var.has(TS->name_to_tag("italic"))) { + var[TS->name_to_tag("italic")] = ftr_italic; + } + + if (!face_indeces.is_empty()) { + int face_index = CLAMP(p_face_index, 0, face_indeces.size() - 1); + return f->find_variation(var, face_indeces[face_index], p_strength, p_transform); + } else { + return f->find_variation(var, 0, p_strength, p_transform); + } + } + return RID(); +} + +RID SystemFont::_get_rid() const { + Ref<Font> f = _get_base_font_or_default(); + if (f.is_valid()) { + if (!face_indeces.is_empty()) { + Dictionary var; + if (ftr_weight > 0) { + var[TS->name_to_tag("weight")] = ftr_weight; + } + if (ftr_italic > 0) { + var[TS->name_to_tag("italic")] = ftr_italic; + } + return f->find_variation(var, face_indeces[0]); + } else { + return f->_get_rid(); + } + } + return RID(); +} + +int64_t SystemFont::get_face_count() const { + return face_indeces.size(); +} + +SystemFont::SystemFont() { + /* NOP */ +} + +SystemFont::~SystemFont() { + reset_state(); +} diff --git a/scene/resources/font.h b/scene/resources/font.h index 8a2f83c414..260b4e521f 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -41,7 +41,7 @@ class TextLine; class TextParagraph; /*************************************************************************/ -/* Font */ +/* Font */ /*************************************************************************/ class Font : public Resource { @@ -381,4 +381,74 @@ public: ~FontVariation(); }; +/*************************************************************************/ +/* SystemFont */ +/*************************************************************************/ + +class SystemFont : public Font { + GDCLASS(SystemFont, Font); + + PackedStringArray names; + BitField<TextServer::FontStyle> style = 0; + + mutable Ref<Font> theme_font; + + Ref<FontFile> base_font; + Vector<int> face_indeces; + int ftr_weight = 0; + int ftr_italic = 0; + + bool antialiased = true; + bool mipmaps = false; + bool force_autohinter = false; + TextServer::Hinting hinting = TextServer::HINTING_LIGHT; + TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; + real_t oversampling = 0.f; + +protected: + static void _bind_methods(); + + virtual void _update_base_font(); + virtual void _update_rids() const override; + + virtual void reset_state() override; + +public: + virtual Ref<Font> _get_base_font_or_default() const; + + virtual void set_antialiased(bool p_antialiased); + virtual bool is_antialiased() const; + + virtual void set_generate_mipmaps(bool p_generate_mipmaps); + virtual bool get_generate_mipmaps() const; + + virtual void set_force_autohinter(bool p_force_autohinter); + virtual bool is_force_autohinter() const; + + virtual void set_hinting(TextServer::Hinting p_hinting); + virtual TextServer::Hinting get_hinting() const; + + virtual void set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel); + virtual TextServer::SubpixelPositioning get_subpixel_positioning() const; + + virtual void set_oversampling(real_t p_oversampling); + virtual real_t get_oversampling() const; + + virtual void set_font_names(const PackedStringArray &p_names); + virtual PackedStringArray get_font_names() const; + + virtual void set_font_style(BitField<TextServer::FontStyle> p_style); + virtual BitField<TextServer::FontStyle> get_font_style() const override; + + virtual int get_spacing(TextServer::SpacingType p_spacing) const override; + + virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const override; + virtual RID _get_rid() const override; + + int64_t get_face_count() const override; + + SystemFont(); + ~SystemFont(); +}; + #endif // FONT_H diff --git a/scene/resources/label_settings.cpp b/scene/resources/label_settings.cpp index e8b986b431..ef380a68f9 100644 --- a/scene/resources/label_settings.cpp +++ b/scene/resources/label_settings.cpp @@ -99,7 +99,7 @@ void LabelSettings::set_font(const Ref<Font> &p_font) { } font = p_font; if (font.is_valid()) { - font->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LabelSettings::_font_changed), varray(), CONNECT_REFERENCE_COUNTED); + font->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LabelSettings::_font_changed), CONNECT_REFERENCE_COUNTED); } emit_changed(); } diff --git a/scene/resources/label_settings.h b/scene/resources/label_settings.h index d2644a7484..062d499d50 100644 --- a/scene/resources/label_settings.h +++ b/scene/resources/label_settings.h @@ -39,17 +39,17 @@ class LabelSettings : public Resource { GDCLASS(LabelSettings, Resource); - real_t line_spacing = 0; + real_t line_spacing = 3; Ref<Font> font; int font_size = Font::DEFAULT_FONT_SIZE; - Color font_color = Color(0.875, 0.875, 0.875); + Color font_color = Color(1, 1, 1); int outline_size = 0; Color outline_color = Color(1, 1, 1); - int shadow_size = 0; - Color shadow_color = Color(1, 1, 1); + int shadow_size = 1; + Color shadow_color = Color(0, 0, 0, 0); Vector2 shadow_offset = Vector2(1, 1); void _font_changed(); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index f07232a3ad..88bc01fb25 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -154,18 +154,18 @@ Material::~Material() { bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); + StringName pr = shader->remap_uniform(p_name); if (!pr) { String n = p_name; if (n.find("param/") == 0) { //backwards compatibility pr = n.substr(6, n.length()); } - if (n.find("shader_param/") == 0) { //backwards compatibility - pr = n.replace_first("shader_param/", ""); + if (n.find("shader_uniform/") == 0) { //backwards compatibility + pr = n.replace_first("shader_uniform/", ""); } } if (pr) { - set_shader_param(pr, p_value); + set_shader_uniform(pr, p_value); return true; } } @@ -175,14 +175,14 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); + StringName pr = shader->remap_uniform(p_name); if (!pr) { String n = p_name; if (n.find("param/") == 0) { //backwards compatibility pr = n.substr(6, n.length()); } - if (n.find("shader_param/") == 0) { //backwards compatibility - pr = n.replace_first("shader_param/", ""); + if (n.find("shader_uniform/") == 0) { //backwards compatibility + pr = n.replace_first("shader_uniform/", ""); } } @@ -203,7 +203,7 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { if (!shader.is_null()) { List<PropertyInfo> list; - shader->get_param_list(&list, true); + shader->get_shader_uniform_list(&list, true); HashMap<String, HashMap<String, List<PropertyInfo>>> groups; { @@ -233,7 +233,7 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { if (!groups.has(last_group)) { PropertyInfo info; info.usage = PROPERTY_USAGE_GROUP; - info.name = last_group; + info.name = last_group.capitalize(); List<PropertyInfo> none_subgroup; none_subgroup.push_back(info); @@ -247,7 +247,7 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { if (!groups[last_group].has(last_subgroup)) { PropertyInfo info; info.usage = PROPERTY_USAGE_SUBGROUP; - info.name = last_subgroup; + info.name = last_subgroup.capitalize(); List<PropertyInfo> subgroup; subgroup.push_back(info); @@ -299,7 +299,7 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { bool ShaderMaterial::property_can_revert(const String &p_name) { if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); + StringName pr = shader->remap_uniform(p_name); if (pr) { Variant default_value = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); Variant current_value; @@ -313,7 +313,7 @@ bool ShaderMaterial::property_can_revert(const String &p_name) { Variant ShaderMaterial::property_get_revert(const String &p_name) { Variant r_ret; if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); + StringName pr = shader->remap_uniform(p_name); if (pr) { r_ret = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); } @@ -349,7 +349,7 @@ Ref<Shader> ShaderMaterial::get_shader() const { return shader; } -void ShaderMaterial::set_shader_param(const StringName &p_param, const Variant &p_value) { +void ShaderMaterial::set_shader_uniform(const StringName &p_param, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { param_cache.erase(p_param); RS::get_singleton()->material_set_param(_get_material(), p_param, Variant()); @@ -369,7 +369,7 @@ void ShaderMaterial::set_shader_param(const StringName &p_param, const Variant & } } -Variant ShaderMaterial::get_shader_param(const StringName &p_param) const { +Variant ShaderMaterial::get_shader_uniform(const StringName &p_param) const { if (param_cache.has(p_param)) { return param_cache[p_param]; } else { @@ -384,8 +384,8 @@ void ShaderMaterial::_shader_changed() { void ShaderMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shader", "shader"), &ShaderMaterial::set_shader); ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader); - ClassDB::bind_method(D_METHOD("set_shader_param", "param", "value"), &ShaderMaterial::set_shader_param); - ClassDB::bind_method(D_METHOD("get_shader_param", "param"), &ShaderMaterial::get_shader_param); + ClassDB::bind_method(D_METHOD("set_shader_uniform", "param", "value"), &ShaderMaterial::set_shader_uniform); + ClassDB::bind_method(D_METHOD("get_shader_uniform", "param"), &ShaderMaterial::get_shader_uniform); ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ShaderMaterial::property_can_revert); ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ShaderMaterial::property_get_revert); @@ -394,12 +394,12 @@ void ShaderMaterial::_bind_methods() { void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { String f = p_function.operator String(); - if ((f == "get_shader_param" || f == "set_shader_param") && p_idx == 0) { + if ((f == "get_shader_uniform" || f == "set_shader_uniform") && p_idx == 0) { if (shader.is_valid()) { List<PropertyInfo> pl; - shader->get_param_list(&pl); + shader->get_shader_uniform_list(&pl); for (const PropertyInfo &E : pl) { - r_options->push_back(E.name.replace_first("shader_param/", "").quote()); + r_options->push_back(E.name.replace_first("shader_uniform/", "").quote()); } } } @@ -1067,7 +1067,8 @@ void BaseMaterial3D::_update_shader() { code += " float num_layers = mix(float(heightmap_max_layers),float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n"; code += " float layer_depth = 1.0 / num_layers;\n"; code += " float current_layer_depth = 0.0;\n"; - code += " vec2 P = view_dir.xy * heightmap_scale;\n"; + // Multiply the heightmap scale by 0.01 to improve heightmap scale usability. + code += " vec2 P = view_dir.xy * heightmap_scale * 0.01;\n"; code += " vec2 delta = P / num_layers;\n"; code += " vec2 ofs = base_uv;\n"; if (flags[FLAG_INVERT_HEIGHTMAP]) { @@ -1103,7 +1104,8 @@ void BaseMaterial3D::_update_shader() { } // Use offset limiting to improve the appearance of non-deep parallax. // This reduces the impression of depth, but avoids visible warping in the distance. - code += " vec2 ofs = base_uv - view_dir.xy * depth * heightmap_scale;\n"; + // Multiply the heightmap scale by 0.01 to improve heightmap scale usability. + code += " vec2 ofs = base_uv - view_dir.xy * depth * heightmap_scale * 0.01;\n"; } code += " base_uv=ofs;\n"; @@ -1276,38 +1278,21 @@ void BaseMaterial3D::_update_shader() { if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) { if (!RenderingServer::get_singleton()->is_low_end()) { code += " {\n"; + if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) { code += " float fade_distance = abs((VIEW_MATRIX * MODEL_MATRIX[3]).z);\n"; } else { - code += " float fade_distance=-VERTEX.z;\n"; + code += " float fade_distance = -VERTEX.z;\n"; } + // Use interleaved gradient noise, which is fast but still looks good. + code += " const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f);"; + code += " float fade = clamp(smoothstep(distance_fade_min, distance_fade_max, fade_distance), 0.0, 1.0);\n"; + // Use a hard cap to prevent a few stray pixels from remaining when past the fade-out distance. + code += " if (fade < 0.001 || fade < fract(magic.z * fract(dot(FRAGCOORD.xy, magic.xy)))) {\n"; + code += " discard;\n"; + code += " }\n"; - code += " float fade=clamp(smoothstep(distance_fade_min,distance_fade_max,fade_distance),0.0,1.0);\n"; - code += " int x = int(FRAGCOORD.x) % 4;\n"; - code += " int y = int(FRAGCOORD.y) % 4;\n"; - code += " int index = x + y * 4;\n"; - code += " float limit = 0.0;\n\n"; - code += " if (x < 8) {\n"; - code += " if (index == 0) limit = 0.0625;\n"; - code += " if (index == 1) limit = 0.5625;\n"; - code += " if (index == 2) limit = 0.1875;\n"; - code += " if (index == 3) limit = 0.6875;\n"; - code += " if (index == 4) limit = 0.8125;\n"; - code += " if (index == 5) limit = 0.3125;\n"; - code += " if (index == 6) limit = 0.9375;\n"; - code += " if (index == 7) limit = 0.4375;\n"; - code += " if (index == 8) limit = 0.25;\n"; - code += " if (index == 9) limit = 0.75;\n"; - code += " if (index == 10) limit = 0.125;\n"; - code += " if (index == 11) limit = 0.625;\n"; - code += " if (index == 12) limit = 1.0;\n"; - code += " if (index == 13) limit = 0.5;\n"; - code += " if (index == 14) limit = 0.875;\n"; - code += " if (index == 15) limit = 0.375;\n"; - code += " }\n\n"; - code += " if (fade < limit)\n"; - code += " discard;\n"; code += " }\n\n"; } @@ -1793,12 +1778,21 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) { } flags[p_flag] = p_enabled; - if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN || p_flag == FLAG_USE_POINT_SIZE) { + + if ( + p_flag == FLAG_USE_SHADOW_TO_OPACITY || + p_flag == FLAG_USE_TEXTURE_REPEAT || + p_flag == FLAG_SUBSURFACE_MODE_SKIN || + p_flag == FLAG_USE_POINT_SIZE || + p_flag == FLAG_UV1_USE_TRIPLANAR || + p_flag == FLAG_UV2_USE_TRIPLANAR) { notify_property_list_changed(); } + if (p_flag == FLAG_PARTICLE_TRAILS_MODE) { update_configuration_warning(); } + _queue_shader_change(); } @@ -1924,6 +1918,14 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const { property.usage = PROPERTY_USAGE_NO_EDITOR; } + if ((property.name == "uv1_triplanar_sharpness" || property.name == "uv1_world_triplanar") && !flags[FLAG_UV1_USE_TRIPLANAR]) { + property.usage = PROPERTY_USAGE_NO_EDITOR; + } + + if ((property.name == "uv2_triplanar_sharpness" || property.name == "uv2_world_triplanar") && !flags[FLAG_UV2_USE_TRIPLANAR]) { + property.usage = PROPERTY_USAGE_NO_EDITOR; + } + // you can only enable anti-aliasing (in materials) on alpha scissor and alpha hash const bool can_select_aa = (transparency == TRANSPARENCY_ALPHA_SCISSOR || transparency == TRANSPARENCY_ALPHA_HASH); // alpha anti aliasiasing is only enabled when you can select aa @@ -2637,7 +2639,7 @@ void BaseMaterial3D::_bind_methods() { ADD_GROUP("Transparency", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth Pre-Pass"), "set_transparency", "get_transparency"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode", PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip"), "set_alpha_antialiasing", "get_alpha_antialiasing"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_antialiasing_edge", "get_alpha_antialiasing_edge"); @@ -2684,7 +2686,7 @@ void BaseMaterial3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_on_uv2"), "set_flag", "get_flag", FLAG_EMISSION_ON_UV2); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_EMISSION); - ADD_GROUP("NormalMap", "normal_"); + ADD_GROUP("Normal Map", "normal_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "normal_enabled"), "set_feature", "get_feature", FEATURE_NORMAL_MAPPING); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_normal_scale", "get_normal_scale"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_NORMAL); @@ -2724,7 +2726,7 @@ void BaseMaterial3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "heightmap_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_HEIGHTMAP); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_flip_texture"), "set_flag", "get_flag", FLAG_INVERT_HEIGHTMAP); - ADD_GROUP("Subsurf Scatter", "subsurf_scatter_"); + ADD_GROUP("Subsurface Scattering", "subsurf_scatter_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURFACE_SCATTERING); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_subsurface_scattering_strength", "get_subsurface_scattering_strength"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_skin_mode"), "set_flag", "get_flag", FLAG_SUBSURFACE_MODE_SKIN); @@ -2948,7 +2950,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_clearcoat(1); set_clearcoat_roughness(0.5); set_anisotropy(0); - set_heightmap_scale(0.05); + set_heightmap_scale(5.0); set_subsurface_scattering_strength(0); set_backlight(Color(0, 0, 0)); set_transmittance_color(Color(1, 1, 1, 1)); @@ -2969,7 +2971,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_transparency(TRANSPARENCY_DISABLED); set_alpha_antialiasing(ALPHA_ANTIALIASING_OFF); - set_alpha_scissor_threshold(0.05); + set_alpha_scissor_threshold(0.5); set_alpha_hash_scale(1.0); set_alpha_antialiasing_edge(0.3); diff --git a/scene/resources/material.h b/scene/resources/material.h index 8c04817c6b..ca5b17dd07 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -115,8 +115,8 @@ public: void set_shader(const Ref<Shader> &p_shader); Ref<Shader> get_shader() const; - void set_shader_param(const StringName &p_param, const Variant &p_value); - Variant get_shader_param(const StringName &p_param) const; + void set_shader_uniform(const StringName &p_param, const Variant &p_value); + Variant get_shader_uniform(const StringName &p_param) const; virtual Shader::Mode get_shader_mode() const override; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 3e7b0a2808..ec9db89794 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -260,6 +260,64 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { return triangle_mesh; } +Ref<TriangleMesh> Mesh::generate_surface_triangle_mesh(int p_surface) const { + ERR_FAIL_INDEX_V(p_surface, get_surface_count(), Ref<TriangleMesh>()); + + if (surface_triangle_meshes.size() != get_surface_count()) { + surface_triangle_meshes.resize(get_surface_count()); + } + + if (surface_triangle_meshes[p_surface].is_valid()) { + return surface_triangle_meshes[p_surface]; + } + + int facecount = 0; + + if (surface_get_primitive_type(p_surface) != PRIMITIVE_TRIANGLES) { + return Ref<TriangleMesh>(); + } + + if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) { + facecount += surface_get_array_index_len(p_surface); + } else { + facecount += surface_get_array_len(p_surface); + } + + Vector<Vector3> faces; + faces.resize(facecount); + Vector3 *facesw = faces.ptrw(); + + Array a = surface_get_arrays(p_surface); + ERR_FAIL_COND_V(a.is_empty(), Ref<TriangleMesh>()); + + int vc = surface_get_array_len(p_surface); + Vector<Vector3> vertices = a[ARRAY_VERTEX]; + const Vector3 *vr = vertices.ptr(); + int widx = 0; + + if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) { + int ic = surface_get_array_index_len(p_surface); + Vector<int> indices = a[ARRAY_INDEX]; + const int *ir = indices.ptr(); + + for (int j = 0; j < ic; j++) { + int index = ir[j]; + facesw[widx++] = vr[index]; + } + + } else { + for (int j = 0; j < vc; j++) { + facesw[widx++] = vr[j]; + } + } + + Ref<TriangleMesh> triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); + triangle_mesh->create(faces); + surface_triangle_meshes.set(p_surface, triangle_mesh); + + return triangle_mesh; +} + void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) { if (debug_lines.size() > 0) { r_lines = debug_lines; @@ -320,6 +378,14 @@ Vector<Face3> Mesh::get_faces() const { return Vector<Face3>(); } +Vector<Face3> Mesh::get_surface_faces(int p_surface) const { + Ref<TriangleMesh> tm = generate_surface_triangle_mesh(p_surface); + if (tm.is_valid()) { + return tm->get_faces(); + } + return Vector<Face3>(); +} + Ref<Shape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const { if (p_simplify) { ConvexDecompositionSettings settings; diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 0f3fae4179..142373ce7f 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -42,6 +42,7 @@ class Mesh : public Resource { GDCLASS(Mesh, Resource); mutable Ref<TriangleMesh> triangle_mesh; //cached + mutable Vector<Ref<TriangleMesh>> surface_triangle_meshes; //cached mutable Vector<Vector3> debug_lines; Size2i lightmap_size_hint; @@ -161,7 +162,9 @@ public: virtual AABB get_aabb() const; Vector<Face3> get_faces() const; + Vector<Face3> get_surface_faces(int p_surface) const; Ref<TriangleMesh> generate_triangle_mesh() const; + Ref<TriangleMesh> generate_surface_triangle_mesh(int p_surface) const; void generate_debug_mesh_lines(Vector<Vector3> &r_lines); void generate_debug_mesh_indices(Vector<Vector3> &r_points); diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index a808ead66b..ac5493efdc 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -30,6 +30,10 @@ #include "navigation_mesh.h" +#ifdef DEBUG_ENABLED +#include "servers/navigation_server_3d.h" +#endif + void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) { ERR_FAIL_COND(p_mesh.is_null()); @@ -337,6 +341,7 @@ void NavigationMesh::clear_polygons() { polygons.clear(); } +#ifndef DISABLE_DEPRECATED Ref<Mesh> NavigationMesh::get_debug_mesh() { if (debug_mesh.is_valid()) { return debug_mesh; @@ -420,6 +425,102 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { return debug_mesh; } +#endif // DISABLE_DEPRECATED + +#ifdef DEBUG_ENABLED +Ref<ArrayMesh> NavigationMesh::_get_debug_mesh() { + if (debug_mesh.is_valid()) { + // Blocks further updates for now, code below is intended for dynamic updates e.g. when settings change. + return debug_mesh; + } + + if (!debug_mesh.is_valid()) { + debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + } else { + debug_mesh->clear_surfaces(); + } + + if (vertices.size() == 0) { + return debug_mesh; + } + + int polygon_count = get_polygon_count(); + + if (polygon_count < 1) { + // no face, no play + return debug_mesh; + } + + // build geometry face surface + Vector<Vector3> face_vertex_array; + face_vertex_array.resize(polygon_count * 3); + + for (int i = 0; i < polygon_count; i++) { + Vector<int> polygon = get_polygon(i); + + face_vertex_array.push_back(vertices[polygon[0]]); + face_vertex_array.push_back(vertices[polygon[1]]); + face_vertex_array.push_back(vertices[polygon[2]]); + } + + Array face_mesh_array; + face_mesh_array.resize(Mesh::ARRAY_MAX); + face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array; + + // if enabled add vertex colors to colorize each face individually + bool enabled_geometry_face_random_color = NavigationServer3D::get_singleton()->get_debug_navigation_enable_geometry_face_random_color(); + if (enabled_geometry_face_random_color) { + Color debug_navigation_geometry_face_color = NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_color(); + Color polygon_color = debug_navigation_geometry_face_color; + + Vector<Color> face_color_array; + face_color_array.resize(polygon_count * 3); + + for (int i = 0; i < polygon_count; i++) { + polygon_color = debug_navigation_geometry_face_color * (Color(Math::randf(), Math::randf(), Math::randf())); + + Vector<int> polygon = get_polygon(i); + + face_color_array.push_back(polygon_color); + face_color_array.push_back(polygon_color); + face_color_array.push_back(polygon_color); + } + face_mesh_array[Mesh::ARRAY_COLOR] = face_color_array; + } + + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, face_mesh_array); + Ref<StandardMaterial3D> debug_geometry_face_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_face_material(); + debug_mesh->surface_set_material(debug_mesh->get_surface_count(), debug_geometry_face_material); + + // if enabled build geometry edge line surface + bool enabled_edge_lines = NavigationServer3D::get_singleton()->get_debug_navigation_enable_edge_lines(); + + if (enabled_edge_lines) { + Vector<Vector3> line_vertex_array; + line_vertex_array.resize(polygon_count * 6); + + for (int i = 0; i < polygon_count; i++) { + Vector<int> polygon = get_polygon(i); + + line_vertex_array.push_back(vertices[polygon[0]]); + line_vertex_array.push_back(vertices[polygon[1]]); + line_vertex_array.push_back(vertices[polygon[1]]); + line_vertex_array.push_back(vertices[polygon[2]]); + line_vertex_array.push_back(vertices[polygon[2]]); + line_vertex_array.push_back(vertices[polygon[0]]); + } + + Array line_mesh_array; + line_mesh_array.resize(Mesh::ARRAY_MAX); + line_mesh_array[Mesh::ARRAY_VERTEX] = line_vertex_array; + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, line_mesh_array); + Ref<StandardMaterial3D> debug_geometry_edge_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_edge_material(); + debug_mesh->surface_set_material(debug_mesh->get_surface_count(), debug_geometry_edge_material); + } + + return debug_mesh; +} +#endif void NavigationMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_sample_partition_type", "sample_partition_type"), &NavigationMesh::set_sample_partition_type); diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h index 40b275c792..79d8962d24 100644 --- a/scene/resources/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -204,7 +204,11 @@ public: Vector<int> get_polygon(int p_idx); void clear_polygons(); +#ifndef DISABLE_DEPRECATED Ref<Mesh> get_debug_mesh(); +#endif // DISABLE_DEPRECATED + + Ref<ArrayMesh> _get_debug_mesh(); NavigationMesh(); }; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 2c58aa83a9..ac67e6e5e9 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -434,10 +434,10 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { for (int j = 0; j < binds.size(); j++) { argptrs[j] = &binds[j]; } - callable = callable.bind(argptrs, binds.size()); + callable = callable.bindp(argptrs, binds.size()); } - cfrom->connect(snames[c.signal], callable, varray(), CONNECT_PERSIST | c.flags); + cfrom->connect(snames[c.signal], callable, CONNECT_PERSIST | c.flags); } //Node *s = ret_nodes[0]; @@ -892,9 +892,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, HashMap<String cd.signal = _nm_get_string(c.signal.get_name(), name_map); cd.flags = c.flags; cd.unbinds = unbinds; - for (int i = 0; i < c.binds.size(); i++) { // TODO: This could be removed now. - cd.binds.push_back(_vm_get_variant(c.binds[i], variant_map)); - } + for (int i = 0; i < binds.size(); i++) { cd.binds.push_back(_vm_get_variant(binds[i], variant_map)); } diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 7a49b9b515..4b2e029f47 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -98,6 +98,17 @@ void ParticlesMaterial::init_shaders() { shader_names->emission_ring_radius = "emission_ring_radius"; shader_names->emission_ring_inner_radius = "emission_ring_inner_radius"; + shader_names->turbulence_enabled = "turbulence_enabled"; + shader_names->turbulence_noise_strength = "turbulence_noise_strength"; + shader_names->turbulence_noise_scale = "turbulence_noise_scale"; + shader_names->turbulence_noise_speed = "turbulence_noise_speed"; + shader_names->turbulence_noise_speed_random = "turbulence_noise_speed_random"; + shader_names->turbulence_influence_over_life = "turbulence_influence_over_life"; + shader_names->turbulence_influence_min = "turbulence_influence_min"; + shader_names->turbulence_influence_max = "turbulence_influence_max"; + shader_names->turbulence_initial_displacement_min = "turbulence_initial_displacement_min"; + shader_names->turbulence_initial_displacement_max = "turbulence_initial_displacement_max"; + shader_names->gravity = "gravity"; shader_names->lifetime_randomness = "lifetime_randomness"; @@ -141,7 +152,6 @@ void ParticlesMaterial::_update_shader() { shader_map[mk].users++; return; } - //must create a shader! // Add a comment to describe the shader origin (useful when converting to ShaderMaterial). @@ -282,6 +292,77 @@ void ParticlesMaterial::_update_shader() { code += "uniform float collision_bounce;\n"; } + if (turbulence_enabled) { + code += "uniform float turbulence_noise_strength;\n"; + code += "uniform float turbulence_noise_scale;\n"; + code += "uniform float turbulence_influence_min;\n"; + code += "uniform float turbulence_influence_max;\n"; + code += "uniform float turbulence_initial_displacement_min;\n"; + code += "uniform float turbulence_initial_displacement_max;\n"; + code += "uniform float turbulence_noise_speed_random;\n"; + code += "uniform vec3 turbulence_noise_speed = vec3(1.0, 1.0, 1.0);\n"; + if (tex_parameters[PARAM_TURB_INFLUENCE_OVER_LIFE].is_valid()) { + code += "uniform sampler2D turbulence_influence_over_life;\n"; + } + if (turbulence_color_ramp.is_valid()) { + code += "uniform sampler2D turbulence_color_ramp;\n"; + } + code += "\n"; + + //functions for 3D noise / turbulence + code += "\n\n"; + code += "// 3D Noise with friendly permission by Inigo Quilez\n"; + code += "vec3 hash_noise( vec3 p ) {\n"; + code += " p *= mat3(vec3(127.1, 311.7, -53.7), vec3(269.5, 183.3, 77.1), vec3(-301.7, 27.3, 215.3));\n"; + code += " return 2.0 * fract(fract(p)*4375.55) -1.;\n"; + code += "}\n"; + code += "\n"; + code += "float noise( vec3 p) {\n"; + code += " vec3 i = floor(p);;\n"; + code += " vec3 f = fract(p);\n "; + code += " vec3 u = f * f * (3.0 - 2.0 * f);\n"; + code += "\n"; + code += " return 2.0*mix( mix( mix( dot( hash_noise( i + vec3(0.0,0.0,0.0) ), f - vec3(0.0,0.0,0.0) ), dot( hash_noise( i + vec3(1.0,0.0,0.0) ), f - vec3(1.0,0.0,0.0) ), u.x),\n"; + code += " mix( dot( hash_noise( i + vec3(0.0,1.0,0.0) ), f - vec3(0.0,1.0,0.0) ), dot( hash_noise( i + vec3(1.0,1.0,0.0) ), f - vec3(1.0,1.0,0.0) ), u.x), u.y),\n"; + code += " mix( mix( dot( hash_noise( i + vec3(0.0,0.0,1.0) ), f - vec3(0.0,0.0,1.0) ), dot( hash_noise( i + vec3(1.0,0.0,1.0) ), f - vec3(1.0,0.0,1.0) ), u.x),\n"; + code += " mix( dot( hash_noise( i + vec3(0.0,1.0,1.0) ), f - vec3(0.0,1.0,1.0) ), dot( hash_noise( i + vec3(1.0,1.0,1.0) ), f - vec3(1.0,1.0,1.0) ), u.x), u.y), u.z);\n"; + code += "}\n\n"; + code += "// Curl 3D and noise_3d function with friendly permission by Isaac Cohen\n"; + code += "vec3 noise_3d(vec3 p) {\n"; + code += " float s = noise(p);\n"; + code += " float s1 = noise(vec3(p.y - 19.1, p.z + 33.4, p.x + 47.2));\n"; + code += " float s2 = noise(vec3(p.z + 74.2, p.x - 124.5, p.y + 99.4));\n"; + code += " vec3 c = vec3(s, s1, s2);\n"; + code += " return c;\n"; + code += "}\n\n"; + code += "vec3 curl_3d(vec3 p, float c) {\n"; + code += " float epsilon = 0.001 + c;\n"; + code += " vec3 dx = vec3(epsilon, 0.0, 0.0);\n"; + code += " vec3 dy = vec3(0.0, epsilon, 0.0);\n"; + code += " vec3 dz = vec3(0.0, 0.0, epsilon);\n"; + code += " vec3 x0 = noise_3d(p - dx).xyz;\n"; + code += " vec3 x1 = noise_3d(p + dx).xyz;\n"; + code += " vec3 y0 = noise_3d(p - dy).xyz;\n"; + code += " vec3 y1 = noise_3d(p + dy).xyz;\n"; + code += " vec3 z0 = noise_3d(p - dz).xyz;\n"; + code += " vec3 z1 = noise_3d(p + dz).xyz;\n"; + code += " float x = y1.z - y0.z - z1.y + z0.y;\n"; + code += " float y = z1.x - z0.x - x1.z + x0.z;\n"; + code += " float z = x1.y - x0.y - y1.x + y0.x;\n"; + code += " float divisor = 1.0 / (2.0 * epsilon);\n"; + code += " return vec3(normalize(vec3(x, y, z) * divisor));\n"; + code += "}\n"; + code += "vec3 get_noise_direction(vec3 pos, vec3 emission_pos, vec3 time_noise) {\n"; + code += " float adj_contrast = max((turbulence_noise_strength - 1.0), 0.0) * 70.0;\n"; + code += " vec3 noise_time = (vec3(TIME) * turbulence_noise_speed) + time_noise;\n"; + code += " vec3 noise_pos = (pos * turbulence_noise_scale) - emission_pos;\n"; + code += " vec3 diff = pos - emission_pos;\n"; + code += " vec3 noise_direction = curl_3d(noise_pos + noise_time - diff, adj_contrast);\n"; + code += " noise_direction = mix(0.9 * noise_direction, noise_direction, turbulence_noise_strength - 9.0);\n"; + code += " return noise_direction;\n"; + code += "}\n"; + } + //need a random function code += "\n\n"; code += "float rand_from_seed(inout uint seed) {\n"; @@ -463,8 +544,18 @@ void ParticlesMaterial::_update_shader() { break; } } - code += " if (RESTART_VELOCITY) VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; + // Apply noise/turbulence: initial displacement. + if (turbulence_enabled) { + if (get_turbulence_noise_speed_random() >= 0.0) { + code += " vec3 time_noise = noise_3d( vec3(TIME) * turbulence_noise_speed_random ) * -turbulence_noise_speed;\n"; + } else { + code += " const vec3 time_noise = vec3(0.0);\n"; + } + code += " vec3 noise_direction = get_noise_direction(TRANSFORM[3].xyz, EMISSION_TRANSFORM[3].xyz, time_noise);\n"; + code += " float turb_init_displacement = mix(turbulence_initial_displacement_min, turbulence_initial_displacement_max, rand_from_seed(alt_seed));"; + code += " TRANSFORM[3].xyz += noise_direction * turb_init_displacement;\n"; + } code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " VELOCITY.z = 0.0;\n"; @@ -483,7 +574,6 @@ void ParticlesMaterial::_update_shader() { if (color_initial_ramp.is_valid()) { code += " float color_initial_rand = rand_from_seed(alt_seed);\n"; } - code += " float pi = 3.14159;\n"; code += " float degree_to_rad = pi / 180.0;\n"; code += "\n"; @@ -570,7 +660,7 @@ void ParticlesMaterial::_update_shader() { code += " vec3 diff = pos - org;\n"; code += " force += length(diff) > 0.0 ? normalize(diff) * tex_radial_accel * mix(radial_accel_min, radial_accel_max, rand_from_seed(alt_seed)) : vec3(0.0);\n"; code += " // apply tangential acceleration;\n"; - code += " float tangent_accel_val = tex_tangent_accel * mix(tangent_accel_min, tangent_accel_max, rand_from_seed(alt_seed))\n;"; + code += " float tangent_accel_val = tex_tangent_accel * mix(tangent_accel_min, tangent_accel_max, rand_from_seed(alt_seed));\n"; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0, 1.0)), 0.0) * tangent_accel_val : vec3(0.0);\n"; @@ -584,6 +674,41 @@ void ParticlesMaterial::_update_shader() { code += " // apply attractor forces\n"; code += " VELOCITY += force * DELTA;\n"; + + if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { + code += " VELOCITY = normalize(VELOCITY) * tex_linear_velocity;\n"; + } + + // Apply noise/turbulence. + if (turbulence_enabled) { + code += " // apply turbulence\n"; + if (tex_parameters[PARAM_TURB_INFLUENCE_OVER_LIFE].is_valid()) { + code += " float turbulence_influence = textureLod(turbulence_influence_over_life, vec2(tv, 0.0), 0.0).r;\n"; + } else { + code += " const float turbulence_influence = 1.0;\n"; + } + code += " \n"; + if (get_turbulence_noise_speed_random() >= 0.0) { + code += " vec3 time_noise = noise_3d( vec3(TIME) * turbulence_noise_speed_random ) * -turbulence_noise_speed;\n"; + } else { + code += " const vec3 time_noise = vec3(0.0);\n"; + } + code += " vec3 noise_direction = get_noise_direction(TRANSFORM[3].xyz, EMISSION_TRANSFORM[3].xyz, time_noise);\n"; + // If collision happened, turbulence is no longer applied. + String extra_tab = ""; + if (collision_enabled) { + code += " if (!COLLIDED) {\n"; + extra_tab = " "; + } + code += extra_tab + " \n"; + code += extra_tab + " float vel_mag = length(VELOCITY);\n"; + code += extra_tab + " float vel_infl = clamp(mix(turbulence_influence_min, turbulence_influence_max, rand_from_seed(alt_seed)) * turbulence_influence, 0.0, 1.0);\n"; + code += extra_tab + " VELOCITY = mix(VELOCITY, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; + if (collision_enabled) { + code += " }"; + } + } + code += " \n"; code += " // orbit velocity\n"; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " float orbit_amount = tex_orbit_velocity * mix(orbit_velocity_min, orbit_velocity_max, rand_from_seed(alt_seed));\n"; @@ -595,9 +720,6 @@ void ParticlesMaterial::_update_shader() { code += " }\n"; } - if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { - code += " VELOCITY = normalize(VELOCITY) * tex_linear_velocity;\n"; - } code += " float dmp = mix(damping_min, damping_max, rand_from_seed(alt_seed));\n"; code += " if (dmp * tex_damping > 0.0) {\n"; code += " float v = length(VELOCITY);\n"; @@ -701,24 +823,34 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[3] = origin;\n"; } } - //scale by scale - code += " float base_scale = mix(scale_min, scale_max, scale_rand);\n"; - code += " base_scale = sign(base_scale) * max(abs(base_scale), 0.001);\n"; - code += " TRANSFORM[0].xyz *= base_scale * sign(tex_scale.r) * max(abs(tex_scale.r), 0.001);\n"; - code += " TRANSFORM[1].xyz *= base_scale * sign(tex_scale.g) * max(abs(tex_scale.g), 0.001);\n"; - code += " TRANSFORM[2].xyz *= base_scale * sign(tex_scale.b) * max(abs(tex_scale.b), 0.001);\n"; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { - code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } + if (collision_enabled) { code += " if (COLLIDED) {\n"; - code += " TRANSFORM[3].xyz+=COLLISION_NORMAL * COLLISION_DEPTH;\n"; - code += " VELOCITY -= COLLISION_NORMAL * dot(COLLISION_NORMAL, VELOCITY) * (1.0 + collision_bounce);\n"; - code += " VELOCITY = mix(VELOCITY,vec3(0.0),collision_friction * DELTA * 100.0);\n"; + code += " if (length(VELOCITY) > 3.0) {\n"; + code += " TRANSFORM[3].xyz += COLLISION_NORMAL * COLLISION_DEPTH;\n"; + code += " VELOCITY -= COLLISION_NORMAL * dot(COLLISION_NORMAL, VELOCITY) * (1.0 + collision_bounce);\n"; + code += " VELOCITY = mix(VELOCITY,vec3(0.0),clamp(collision_friction, 0.0, 1.0));\n"; + code += " } else {\n"; + code += " VELOCITY = vec3(0.0);\n"; + // If turbulence is enabled, set the noise direction to up so the turbulence color is "neutral" + if (turbulence_enabled) { + code += " noise_direction = vec3(1.0, 0.0, 0.0);\n"; + } + code += " }\n"; code += " }\n"; } + + // scale by scale + code += " float base_scale = mix(scale_min, scale_max, scale_rand);\n"; + code += " base_scale = sign(base_scale) * max(abs(base_scale), 0.001);\n"; + code += " TRANSFORM[0].xyz *= base_scale * sign(tex_scale.r) * max(abs(tex_scale.r), 0.001);\n"; + code += " TRANSFORM[1].xyz *= base_scale * sign(tex_scale.g) * max(abs(tex_scale.g), 0.001);\n"; + code += " TRANSFORM[2].xyz *= base_scale * sign(tex_scale.b) * max(abs(tex_scale.b), 0.001);\n"; + if (sub_emitter_mode != SUB_EMITTER_DISABLED) { code += " int emit_count = 0;\n"; switch (sub_emitter_mode) { @@ -856,6 +988,15 @@ void ParticlesMaterial::set_param_min(Parameter p_param, float p_value) { case PARAM_ANIM_OFFSET: { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_min, p_value); } break; + case PARAM_TURB_VEL_INFLUENCE: { + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_influence_min, p_value); + } break; + case PARAM_TURB_INIT_DISPLACEMENT: { + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_initial_displacement_min, p_value); + } break; + case PARAM_TURB_INFLUENCE_OVER_LIFE: { + // Can't happen, but silences warning + } break; case PARAM_MAX: break; // Can't happen, but silences warning } @@ -912,6 +1053,15 @@ void ParticlesMaterial::set_param_max(Parameter p_param, float p_value) { case PARAM_ANIM_OFFSET: { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_max, p_value); } break; + case PARAM_TURB_VEL_INFLUENCE: { + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_influence_max, p_value); + } break; + case PARAM_TURB_INIT_DISPLACEMENT: { + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_initial_displacement_max, p_value); + } break; + case PARAM_TURB_INFLUENCE_OVER_LIFE: { + // Can't happen, but silences warning + } break; case PARAM_MAX: break; // Can't happen, but silences warning } @@ -986,6 +1136,16 @@ void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D case PARAM_ANIM_OFFSET: { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, tex_rid); } break; + case PARAM_TURB_INFLUENCE_OVER_LIFE: { + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_influence_over_life, tex_rid); + _adjust_curve_range(p_texture, 0, 1); + } break; + case PARAM_TURB_VEL_INFLUENCE: { + // Can't happen, but silences warning + } break; + case PARAM_TURB_INIT_DISPLACEMENT: { + // Can't happen, but silences warning + } break; case PARAM_MAX: break; // Can't happen, but silences warning } @@ -1151,6 +1311,54 @@ real_t ParticlesMaterial::get_emission_ring_inner_radius() const { return emission_ring_inner_radius; } +void ParticlesMaterial::set_turbulence_enabled(const bool p_turbulence_enabled) { + turbulence_enabled = p_turbulence_enabled; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_enabled, turbulence_enabled); + _queue_shader_change(); + notify_property_list_changed(); +} + +bool ParticlesMaterial::get_turbulence_enabled() const { + return turbulence_enabled; +} + +void ParticlesMaterial::set_turbulence_noise_strength(float p_turbulence_noise_strength) { + turbulence_noise_strength = p_turbulence_noise_strength; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_strength, p_turbulence_noise_strength); +} + +float ParticlesMaterial::get_turbulence_noise_strength() const { + return turbulence_noise_strength; +} + +void ParticlesMaterial::set_turbulence_noise_scale(float p_turbulence_noise_scale) { + turbulence_noise_scale = p_turbulence_noise_scale; + float shader_turbulence_noise_scale = (pow(p_turbulence_noise_scale, 0.25) * 5.6234 / 10.0) * 4.0 - 3.0; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_scale, shader_turbulence_noise_scale); +} + +float ParticlesMaterial::get_turbulence_noise_scale() const { + return turbulence_noise_scale; +} + +void ParticlesMaterial::set_turbulence_noise_speed_random(float p_turbulence_noise_speed_random) { + turbulence_noise_speed_random = p_turbulence_noise_speed_random; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_speed_random, p_turbulence_noise_speed_random); +} + +float ParticlesMaterial::get_turbulence_noise_speed_random() const { + return turbulence_noise_speed_random; +} + +void ParticlesMaterial::set_turbulence_noise_speed(const Vector3 &p_turbulence_noise_speed) { + turbulence_noise_speed = p_turbulence_noise_speed; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_speed, turbulence_noise_speed); +} + +Vector3 ParticlesMaterial::get_turbulence_noise_speed() const { + return turbulence_noise_speed; +} + void ParticlesMaterial::set_gravity(const Vector3 &p_gravity) { gravity = p_gravity; Vector3 gset = gravity; @@ -1214,6 +1422,20 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const { if (property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) { property.usage = PROPERTY_USAGE_NONE; } + + if (!turbulence_enabled) { + if (property.name == "turbulence_noise_strength" || + property.name == "turbulence_noise_scale" || + property.name == "turbulence_noise_speed" || + property.name == "turbulence_noise_speed_random" || + property.name == "turbulence_influence_over_life" || + property.name == "turbulence_influence_min" || + property.name == "turbulence_influence_max" || + property.name == "turbulence_initial_displacement_min" || + property.name == "turbulence_initial_displacement_max") { + property.usage = PROPERTY_USAGE_NO_EDITOR; + } + } } void ParticlesMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) { @@ -1365,6 +1587,21 @@ void ParticlesMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emission_ring_inner_radius", "inner_radius"), &ParticlesMaterial::set_emission_ring_inner_radius); ClassDB::bind_method(D_METHOD("get_emission_ring_inner_radius"), &ParticlesMaterial::get_emission_ring_inner_radius); + ClassDB::bind_method(D_METHOD("get_turbulence_enabled"), &ParticlesMaterial::get_turbulence_enabled); + ClassDB::bind_method(D_METHOD("set_turbulence_enabled", "turbulence_enabled"), &ParticlesMaterial::set_turbulence_enabled); + + ClassDB::bind_method(D_METHOD("get_turbulence_noise_strength"), &ParticlesMaterial::get_turbulence_noise_strength); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_strength", "turbulence_noise_strength"), &ParticlesMaterial::set_turbulence_noise_strength); + + ClassDB::bind_method(D_METHOD("get_turbulence_noise_scale"), &ParticlesMaterial::get_turbulence_noise_scale); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_scale", "turbulence_noise_scale"), &ParticlesMaterial::set_turbulence_noise_scale); + + ClassDB::bind_method(D_METHOD("get_turbulence_noise_speed_random"), &ParticlesMaterial::get_turbulence_noise_speed_random); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_speed_random", "turbulence_noise_speed_random"), &ParticlesMaterial::set_turbulence_noise_speed_random); + + ClassDB::bind_method(D_METHOD("get_turbulence_noise_speed"), &ParticlesMaterial::get_turbulence_noise_speed); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_speed", "turbulence_noise_speed"), &ParticlesMaterial::set_turbulence_noise_speed); + ClassDB::bind_method(D_METHOD("get_gravity"), &ParticlesMaterial::get_gravity); ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &ParticlesMaterial::set_gravity); @@ -1413,7 +1650,7 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_height"), "set_emission_ring_height", "get_emission_ring_height"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_radius"), "set_emission_ring_radius", "get_emission_ring_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_inner_radius"), "set_emission_ring_inner_radius", "get_emission_ring_inner_radius"); - ADD_GROUP("ParticleFlags", "particle_flag_"); + ADD_GROUP("Particle Flags", "particle_flag_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_rotate_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ROTATE_Y); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_disable_z"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_DISABLE_Z); @@ -1467,6 +1704,19 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_max", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_max", "get_param_max", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_HUE_VARIATION); + + ADD_GROUP("Turbulence", "turbulence_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "turbulence_enabled"), "set_turbulence_enabled", "get_turbulence_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_strength", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_turbulence_noise_strength", "get_turbulence_noise_strength"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_scale", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_turbulence_noise_scale", "get_turbulence_noise_scale"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "turbulence_noise_speed"), "set_turbulence_noise_speed", "get_turbulence_noise_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_speed_random", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_turbulence_noise_speed_random", "get_turbulence_noise_speed_random"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_TURB_VEL_INFLUENCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_TURB_VEL_INFLUENCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_initial_displacement_min", PROPERTY_HINT_RANGE, "-100,100,0.1"), "set_param_min", "get_param_min", PARAM_TURB_INIT_DISPLACEMENT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_initial_displacement_max", PROPERTY_HINT_RANGE, "-100,100,0.1"), "set_param_max", "get_param_max", PARAM_TURB_INIT_DISPLACEMENT); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "turbulence_influence_over_life", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TURB_INFLUENCE_OVER_LIFE); + ADD_GROUP("Animation", "anim_"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); @@ -1517,6 +1767,10 @@ void ParticlesMaterial::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_RING); BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX); + BIND_ENUM_CONSTANT(PARAM_TURB_VEL_INFLUENCE); + BIND_ENUM_CONSTANT(PARAM_TURB_INIT_DISPLACEMENT); + BIND_ENUM_CONSTANT(PARAM_TURB_INFLUENCE_OVER_LIFE); + BIND_ENUM_CONSTANT(SUB_EMITTER_DISABLED); BIND_ENUM_CONSTANT(SUB_EMITTER_CONSTANT); BIND_ENUM_CONSTANT(SUB_EMITTER_AT_END); @@ -1560,6 +1814,17 @@ ParticlesMaterial::ParticlesMaterial() : set_emission_ring_height(1); set_emission_ring_radius(1); set_emission_ring_inner_radius(0); + + set_turbulence_enabled(false); + set_turbulence_noise_speed(Vector3(0.5, 0.5, 0.5)); + set_turbulence_noise_strength(1); + set_turbulence_noise_scale(9); + set_turbulence_noise_speed_random(0); + set_param_min(PARAM_TURB_VEL_INFLUENCE, 0.1); + set_param_max(PARAM_TURB_VEL_INFLUENCE, 0.1); + set_param_min(PARAM_TURB_INIT_DISPLACEMENT, 0.0); + set_param_max(PARAM_TURB_INIT_DISPLACEMENT, 0.0); + set_gravity(Vector3(0, -9.8, 0)); set_lifetime_randomness(0); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index af45593f38..7fb46d6ac5 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -58,6 +58,9 @@ public: PARAM_HUE_VARIATION, PARAM_ANIM_SPEED, PARAM_ANIM_OFFSET, + PARAM_TURB_INFLUENCE_OVER_LIFE, + PARAM_TURB_VEL_INFLUENCE, + PARAM_TURB_INIT_DISPLACEMENT, PARAM_MAX }; @@ -105,9 +108,10 @@ private: uint32_t attractor_enabled : 1; uint32_t collision_enabled : 1; uint32_t collision_scale : 1; + uint32_t turbulence_enabled : 1; }; - uint32_t key = 0; + uint64_t key = 0; static uint32_t hash(const MaterialKey &p_key) { return hash_murmur3_one_32(p_key.key); @@ -152,6 +156,7 @@ private: mk.collision_enabled = collision_enabled; mk.attractor_enabled = attractor_interaction_enabled; mk.collision_scale = collision_scale; + mk.turbulence_enabled = turbulence_enabled; return mk; } @@ -216,6 +221,17 @@ private: StringName emission_ring_radius; StringName emission_ring_inner_radius; + StringName turbulence_enabled; + StringName turbulence_noise_strength; + StringName turbulence_noise_scale; + StringName turbulence_noise_speed; + StringName turbulence_noise_speed_random; + StringName turbulence_influence_over_life; + StringName turbulence_influence_min; + StringName turbulence_influence_max; + StringName turbulence_initial_displacement_min; + StringName turbulence_initial_displacement_max; + StringName gravity; StringName lifetime_randomness; @@ -243,6 +259,7 @@ private: float params_min[PARAM_MAX]; float params_max[PARAM_MAX]; + float params[PARAM_MAX]; Ref<Texture2D> tex_parameters[PARAM_MAX]; Color color; @@ -265,6 +282,13 @@ private: bool anim_loop = false; + bool turbulence_enabled; + Vector3 turbulence_noise_speed; + Ref<Texture2D> turbulence_color_ramp; + float turbulence_noise_strength = 0.0f; + float turbulence_noise_scale = 0.0f; + float turbulence_noise_speed_random = 0.0f; + Vector3 gravity; double lifetime_randomness = 0.0; @@ -340,6 +364,18 @@ public: real_t get_emission_ring_inner_radius() const; int get_emission_point_count() const; + void set_turbulence_enabled(bool p_turbulence_enabled); + void set_turbulence_noise_strength(float p_turbulence_noise_strength); + void set_turbulence_noise_scale(float p_turbulence_noise_scale); + void set_turbulence_noise_speed_random(float p_turbulence_noise_speed_random); + void set_turbulence_noise_speed(const Vector3 &p_turbulence_noise_speed); + + bool get_turbulence_enabled() const; + float get_turbulence_noise_strength() const; + float get_turbulence_noise_scale() const; + float get_turbulence_noise_speed_random() const; + Vector3 get_turbulence_noise_speed() const; + void set_gravity(const Vector3 &p_gravity); Vector3 get_gravity() const; diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 68441afb1c..f038a79b8f 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -1622,6 +1622,134 @@ bool SphereMesh::get_is_hemisphere() const { SphereMesh::SphereMesh() {} /** + TorusMesh +*/ + +void TorusMesh::_create_mesh_array(Array &p_arr) const { + // set our bounding box + + Vector<Vector3> points; + Vector<Vector3> normals; + Vector<float> tangents; + Vector<Vector2> uvs; + Vector<int> indices; + +#define ADD_TANGENT(m_x, m_y, m_z, m_d) \ + tangents.push_back(m_x); \ + tangents.push_back(m_y); \ + tangents.push_back(m_z); \ + tangents.push_back(m_d); + + ERR_FAIL_COND_MSG(inner_radius == outer_radius, "Inner radius and outer radius cannot be the same."); + + float min_radius = inner_radius; + float max_radius = outer_radius; + + if (min_radius > max_radius) { + SWAP(min_radius, max_radius); + } + + float radius = (max_radius - min_radius) * 0.5; + + for (int i = 0; i <= rings; i++) { + int prevrow = (i - 1) * (ring_segments + 1); + int thisrow = i * (ring_segments + 1); + float inci = float(i) / rings; + float angi = inci * Math_TAU; + + Vector2 normali = Vector2(-Math::sin(angi), -Math::cos(angi)); + + for (int j = 0; j <= ring_segments; j++) { + float incj = float(j) / ring_segments; + float angj = incj * Math_TAU; + + Vector2 normalj = Vector2(-Math::cos(angj), Math::sin(angj)); + Vector2 normalk = normalj * radius + Vector2(min_radius + radius, 0); + + points.push_back(Vector3(normali.x * normalk.x, normalk.y, normali.y * normalk.x)); + normals.push_back(Vector3(normali.x * normalj.x, normalj.y, normali.y * normalj.x)); + ADD_TANGENT(-Math::cos(angi), 0.0, Math::sin(angi), 1.0); + uvs.push_back(Vector2(inci, incj)); + + if (i > 0 && j > 0) { + indices.push_back(thisrow + j - 1); + indices.push_back(prevrow + j); + indices.push_back(prevrow + j - 1); + + indices.push_back(thisrow + j - 1); + indices.push_back(thisrow + j); + indices.push_back(prevrow + j); + } + } + } + + p_arr[RS::ARRAY_VERTEX] = points; + p_arr[RS::ARRAY_NORMAL] = normals; + p_arr[RS::ARRAY_TANGENT] = tangents; + p_arr[RS::ARRAY_TEX_UV] = uvs; + p_arr[RS::ARRAY_INDEX] = indices; +} + +void TorusMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_inner_radius", "radius"), &TorusMesh::set_inner_radius); + ClassDB::bind_method(D_METHOD("get_inner_radius"), &TorusMesh::get_inner_radius); + + ClassDB::bind_method(D_METHOD("set_outer_radius", "radius"), &TorusMesh::set_outer_radius); + ClassDB::bind_method(D_METHOD("get_outer_radius"), &TorusMesh::get_outer_radius); + + ClassDB::bind_method(D_METHOD("set_rings", "rings"), &TorusMesh::set_rings); + ClassDB::bind_method(D_METHOD("get_rings"), &TorusMesh::get_rings); + + ClassDB::bind_method(D_METHOD("set_ring_segments", "rings"), &TorusMesh::set_ring_segments); + ClassDB::bind_method(D_METHOD("get_ring_segments"), &TorusMesh::get_ring_segments); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inner_radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_inner_radius", "get_inner_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "outer_radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_outer_radius", "get_outer_radius"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "3,128,1"), "set_rings", "get_rings"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "ring_segments", PROPERTY_HINT_RANGE, "3,64,1"), "set_ring_segments", "get_ring_segments"); +} + +void TorusMesh::set_inner_radius(const float p_inner_radius) { + inner_radius = p_inner_radius; + _request_update(); +} + +float TorusMesh::get_inner_radius() const { + return inner_radius; +} + +void TorusMesh::set_outer_radius(const float p_outer_radius) { + outer_radius = p_outer_radius; + _request_update(); +} + +float TorusMesh::get_outer_radius() const { + return outer_radius; +} + +void TorusMesh::set_rings(const int p_rings) { + ERR_FAIL_COND(p_rings < 3); + rings = p_rings; + _request_update(); +} + +int TorusMesh::get_rings() const { + return rings; +} + +void TorusMesh::set_ring_segments(const int p_ring_segments) { + ERR_FAIL_COND(p_ring_segments < 3); + ring_segments = p_ring_segments; + _request_update(); +} + +int TorusMesh::get_ring_segments() const { + return ring_segments; +} + +TorusMesh::TorusMesh() {} + +/** PointMesh */ diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index ec124e379f..64eefd2c07 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -351,6 +351,38 @@ public: }; /** + Big donut +*/ +class TorusMesh : public PrimitiveMesh { + GDCLASS(TorusMesh, PrimitiveMesh); + +private: + float inner_radius = 0.5; + float outer_radius = 1.0; + int rings = 64; + int ring_segments = 32; + +protected: + static void _bind_methods(); + virtual void _create_mesh_array(Array &p_arr) const override; + +public: + void set_inner_radius(const float p_inner_radius); + float get_inner_radius() const; + + void set_outer_radius(const float p_outer_radius); + float get_outer_radius() const; + + void set_rings(const int p_rings); + int get_rings() const; + + void set_ring_segments(const int p_ring_segments); + int get_ring_segments() const; + + TorusMesh(); +}; + +/** A single point for use in particle systems */ diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 100e8ea7c6..2b1d91e4ef 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -2211,7 +2211,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso return OK; } -Error ResourceFormatSaverText::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverText::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { if (p_path.ends_with(".tscn") && !Ref<PackedScene>(p_resource).is_valid()) { return ERR_FILE_UNRECOGNIZED; } diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index 69bb40502f..9154bcf795 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -194,7 +194,7 @@ public: class ResourceFormatSaverText : public ResourceFormatSaver { public: static ResourceFormatSaverText *singleton; - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual bool recognize(const Ref<Resource> &p_resource) const; virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; diff --git a/scene/resources/separation_ray_shape_2d.cpp b/scene/resources/separation_ray_shape_2d.cpp index 0d6aee47d8..fea41061fd 100644 --- a/scene/resources/separation_ray_shape_2d.cpp +++ b/scene/resources/separation_ray_shape_2d.cpp @@ -57,7 +57,7 @@ void SeparationRayShape2D::draw(const RID &p_to_rid, const Color &p_color) { Transform2D xf; xf.rotate(target_position.angle()); - xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); + xf.translate_local(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); Vector<Vector2> pts = { xf.xform(Vector2(arrow_size, 0)), diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 74031e02d7..db7b03f2be 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -103,11 +103,11 @@ String Shader::get_code() const { return code; } -void Shader::get_param_list(List<PropertyInfo> *p_params, bool p_get_groups) const { +void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups) const { _update_shader(); List<PropertyInfo> local; - RenderingServer::get_singleton()->shader_get_param_list(shader, &local); + RenderingServer::get_singleton()->shader_get_shader_uniform_list(shader, &local); params_cache.clear(); params_cache_dirty = false; @@ -176,8 +176,8 @@ bool Shader::is_text_shader() const { return true; } -bool Shader::has_param(const StringName &p_param) const { - return params_cache.has("shader_param/" + p_param); +bool Shader::has_uniform(const StringName &p_param) const { + return params_cache.has("shader_uniform/" + p_param); } void Shader::_update_shader() const { @@ -192,7 +192,7 @@ void Shader::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_texture_param", "param", "texture", "index"), &Shader::set_default_texture_param, DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_default_texture_param", "param", "index"), &Shader::get_default_texture_param, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("has_param", "name"), &Shader::has_param); + ClassDB::bind_method(D_METHOD("has_uniform", "name"), &Shader::has_uniform); ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_code", "get_code"); @@ -251,7 +251,7 @@ String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const return ""; } -Error ResourceFormatSaverShader::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverShader::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { Ref<Shader> shader = p_resource; ERR_FAIL_COND_V(shader.is_null(), ERR_INVALID_PARAMETER); diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 7aa14651a5..abc953de5f 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -78,21 +78,21 @@ public: void set_code(const String &p_code); String get_code() const; - void get_param_list(List<PropertyInfo> *p_params, bool p_get_groups = false) const; - bool has_param(const StringName &p_param) const; + void get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups = false) const; + bool has_uniform(const StringName &p_param) const; - void set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture, int p_index = 0); - Ref<Texture2D> get_default_texture_param(const StringName &p_param, int p_index = 0) const; + void set_default_texture_param(const StringName &p_uniform, const Ref<Texture2D> &p_texture, int p_index = 0); + Ref<Texture2D> get_default_texture_param(const StringName &p_uniform, int p_index = 0) const; void get_default_texture_param_list(List<StringName> *r_textures) const; virtual bool is_text_shader() const; - _FORCE_INLINE_ StringName remap_param(const StringName &p_param) const { + _FORCE_INLINE_ StringName remap_uniform(const StringName &p_uniform) const { if (params_cache_dirty) { - get_param_list(nullptr); + get_shader_uniform_list(nullptr); } - const HashMap<StringName, StringName>::Iterator E = params_cache.find(p_param); + const HashMap<StringName, StringName>::Iterator E = params_cache.find(p_uniform); if (E) { return E->value; } @@ -117,7 +117,7 @@ public: class ResourceFormatSaverShader : public ResourceFormatSaver { public: - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; virtual bool recognize(const Ref<Resource> &p_resource) const; }; diff --git a/scene/resources/shader_include.cpp b/scene/resources/shader_include.cpp index b819128af3..42435fe3c7 100644 --- a/scene/resources/shader_include.cpp +++ b/scene/resources/shader_include.cpp @@ -113,7 +113,7 @@ String ResourceFormatLoaderShaderInclude::get_resource_type(const String &p_path // ResourceFormatSaverShaderInclude -Error ResourceFormatSaverShaderInclude::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverShaderInclude::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { Ref<ShaderInclude> shader_inc = p_resource; ERR_FAIL_COND_V(shader_inc.is_null(), ERR_INVALID_PARAMETER); diff --git a/scene/resources/shader_include.h b/scene/resources/shader_include.h index 6f0deeef4e..b0865e3a61 100644 --- a/scene/resources/shader_include.h +++ b/scene/resources/shader_include.h @@ -63,7 +63,7 @@ public: class ResourceFormatSaverShaderInclude : public ResourceFormatSaver { public: - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; virtual bool recognize(const Ref<Resource> &p_resource) const; }; diff --git a/scene/resources/skeleton_profile.cpp b/scene/resources/skeleton_profile.cpp index 0714de470c..bfb4bb6e2b 100644 --- a/scene/resources/skeleton_profile.cpp +++ b/scene/resources/skeleton_profile.cpp @@ -123,12 +123,20 @@ bool SkeletonProfile::_get(const StringName &p_path, Variant &r_ret) const { void SkeletonProfile::_validate_property(PropertyInfo &property) const { if (is_read_only) { - if (property.name == ("group_size") || property.name == ("bone_size")) { + if (property.name == ("group_size") || property.name == ("bone_size") || property.name == ("root_bone") || property.name == ("scale_base_bone")) { property.usage = PROPERTY_USAGE_NO_EDITOR; return; } } + if (property.name == ("root_bone") || property.name == ("scale_base_bone")) { + String hint = ""; + for (int i = 0; i < bones.size(); i++) { + hint += i == 0 ? String(bones[i].bone_name) : "," + String(bones[i].bone_name); + } + property.hint_string = hint; + } + PackedStringArray split = property.name.split("/"); if (split.size() == 3 && split[0] == "bones") { if (split[2] == "bone_tail" && get_tail_direction(split[1].to_int()) != TAIL_DIRECTION_SPECIFIC_CHILD) { @@ -168,6 +176,28 @@ void SkeletonProfile::_get_property_list(List<PropertyInfo> *p_list) const { } } +StringName SkeletonProfile::get_root_bone() { + return root_bone; +} + +void SkeletonProfile::set_root_bone(StringName p_bone_name) { + if (is_read_only) { + return; + } + root_bone = p_bone_name; +} + +StringName SkeletonProfile::get_scale_base_bone() { + return scale_base_bone; +} + +void SkeletonProfile::set_scale_base_bone(StringName p_bone_name) { + if (is_read_only) { + return; + } + scale_base_bone = p_bone_name; +} + int SkeletonProfile::get_group_size() { return groups.size(); } @@ -361,6 +391,12 @@ bool SkeletonProfile::has_bone(StringName p_bone_name) { } void SkeletonProfile::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_root_bone", "bone_name"), &SkeletonProfile::set_root_bone); + ClassDB::bind_method(D_METHOD("get_root_bone"), &SkeletonProfile::get_root_bone); + + ClassDB::bind_method(D_METHOD("set_scale_base_bone", "bone_name"), &SkeletonProfile::set_scale_base_bone); + ClassDB::bind_method(D_METHOD("get_scale_base_bone"), &SkeletonProfile::get_scale_base_bone); + ClassDB::bind_method(D_METHOD("set_group_size", "size"), &SkeletonProfile::set_group_size); ClassDB::bind_method(D_METHOD("get_group_size"), &SkeletonProfile::get_group_size); @@ -396,6 +432,9 @@ void SkeletonProfile::_bind_methods() { ClassDB::bind_method(D_METHOD("get_group", "bone_idx"), &SkeletonProfile::get_group); ClassDB::bind_method(D_METHOD("set_group", "bone_idx", "group"), &SkeletonProfile::set_group); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "root_bone", PROPERTY_HINT_ENUM_SUGGESTION, ""), "set_root_bone", "get_root_bone"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "scale_base_bone", PROPERTY_HINT_ENUM_SUGGESTION, ""), "set_scale_base_bone", "get_scale_base_bone"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "group_size", PROPERTY_HINT_RANGE, "0,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Groups,groups/"), "set_group_size", "get_group_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "bone_size", PROPERTY_HINT_RANGE, "0,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Bones,bones/"), "set_bone_size", "get_bone_size"); @@ -415,6 +454,9 @@ SkeletonProfile::~SkeletonProfile() { SkeletonProfileHumanoid::SkeletonProfileHumanoid() { is_read_only = true; + root_bone = "Root"; + scale_base_bone = "Hips"; + groups.resize(4); groups.write[0].group_name = "Body"; diff --git a/scene/resources/skeleton_profile.h b/scene/resources/skeleton_profile.h index d305311538..84dfca458e 100644 --- a/scene/resources/skeleton_profile.h +++ b/scene/resources/skeleton_profile.h @@ -64,6 +64,9 @@ protected: bool require = false; }; + StringName root_bone; + StringName scale_base_bone; + Vector<SkeletonProfileGroup> groups; Vector<SkeletonProfileBone> bones; @@ -74,6 +77,12 @@ protected: static void _bind_methods(); public: + StringName get_root_bone(); + void set_root_bone(StringName p_bone_name); + + StringName get_scale_base_bone(); + void set_scale_base_bone(StringName p_bone_name); + int get_group_size(); void set_group_size(int p_size); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 0aefe34f7d..05ed9238b8 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -2009,7 +2009,7 @@ void CurveXYZTexture::set_curve_x(Ref<Curve> p_curve) { } _curve_x = p_curve; if (_curve_x.is_valid()) { - _curve_x->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED); + _curve_x->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), CONNECT_REFERENCE_COUNTED); } _update(); } @@ -2022,7 +2022,7 @@ void CurveXYZTexture::set_curve_y(Ref<Curve> p_curve) { } _curve_y = p_curve; if (_curve_y.is_valid()) { - _curve_y->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED); + _curve_y->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), CONNECT_REFERENCE_COUNTED); } _update(); } @@ -2035,7 +2035,7 @@ void CurveXYZTexture::set_curve_z(Ref<Curve> p_curve) { } _curve_z = p_curve; if (_curve_z.is_valid()) { - _curve_z->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED); + _curve_z->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), CONNECT_REFERENCE_COUNTED); } _update(); } diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 39b77568cf..3f6eec8497 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -295,7 +295,7 @@ void Theme::set_default_font(const Ref<Font> &p_default_font) { default_font = p_default_font; if (default_font.is_valid()) { - default_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); + default_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed).bind(false), CONNECT_REFERENCE_COUNTED); } _emit_theme_changed(); @@ -341,7 +341,7 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_theme_type, c icon_map[p_theme_type][p_name] = p_icon; if (p_icon.is_valid()) { - icon_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); + icon_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed).bind(false), CONNECT_REFERENCE_COUNTED); } _emit_theme_changed(!existing); @@ -451,7 +451,7 @@ void Theme::set_stylebox(const StringName &p_name, const StringName &p_theme_typ style_map[p_theme_type][p_name] = p_style; if (p_style.is_valid()) { - style_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); + style_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed).bind(false), CONNECT_REFERENCE_COUNTED); } _emit_theme_changed(!existing); @@ -561,7 +561,7 @@ void Theme::set_font(const StringName &p_name, const StringName &p_theme_type, c font_map[p_theme_type][p_name] = p_font; if (p_font.is_valid()) { - font_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); + font_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed).bind(false), CONNECT_REFERENCE_COUNTED); } _emit_theme_changed(!existing); diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index a59870f4a9..b0b9f1228f 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -1048,13 +1048,13 @@ int TileSet::get_custom_data_layer_by_name(String p_value) const { } } -void TileSet::set_custom_data_name(int p_layer_id, String p_value) { +void TileSet::set_custom_data_layer_name(int p_layer_id, String p_value) { ERR_FAIL_INDEX(p_layer_id, custom_data_layers.size()); // Exit if another property has the same name. if (!p_value.is_empty()) { for (int other_layer_id = 0; other_layer_id < get_custom_data_layers_count(); other_layer_id++) { - if (other_layer_id != p_layer_id && get_custom_data_name(other_layer_id) == p_value) { + if (other_layer_id != p_layer_id && get_custom_data_layer_name(other_layer_id) == p_value) { ERR_FAIL_MSG(vformat("There is already a custom property named %s", p_value)); } } @@ -1070,12 +1070,12 @@ void TileSet::set_custom_data_name(int p_layer_id, String p_value) { emit_changed(); } -String TileSet::get_custom_data_name(int p_layer_id) const { +String TileSet::get_custom_data_layer_name(int p_layer_id) const { ERR_FAIL_INDEX_V(p_layer_id, custom_data_layers.size(), ""); return custom_data_layers[p_layer_id].name; } -void TileSet::set_custom_data_type(int p_layer_id, Variant::Type p_value) { +void TileSet::set_custom_data_layer_type(int p_layer_id, Variant::Type p_value) { ERR_FAIL_INDEX(p_layer_id, custom_data_layers.size()); custom_data_layers.write[p_layer_id].type = p_value; @@ -1086,7 +1086,7 @@ void TileSet::set_custom_data_type(int p_layer_id, Variant::Type p_value) { emit_changed(); } -Variant::Type TileSet::get_custom_data_type(int p_layer_id) const { +Variant::Type TileSet::get_custom_data_layer_type(int p_layer_id) const { ERR_FAIL_INDEX_V(p_layer_id, custom_data_layers.size(), Variant::NIL); return custom_data_layers[p_layer_id].type; } @@ -3036,14 +3036,14 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { while (index >= custom_data_layers.size()) { add_custom_data_layer(); } - set_custom_data_name(index, p_value); + set_custom_data_layer_name(index, p_value); return true; } else if (components[1] == "type") { ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false); while (index >= custom_data_layers.size()) { add_custom_data_layer(); } - set_custom_data_type(index, Variant::Type(int(p_value))); + set_custom_data_layer_type(index, Variant::Type(int(p_value))); return true; } } else if (components.size() == 2 && components[0] == "sources" && components[1].is_valid_int()) { @@ -3165,10 +3165,10 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { return false; } if (components[1] == "name") { - r_ret = get_custom_data_name(index); + r_ret = get_custom_data_layer_name(index); return true; } else if (components[1] == "type") { - r_ret = get_custom_data_type(index); + r_ret = get_custom_data_layer_type(index); return true; } } else if (components.size() == 2 && components[0] == "sources" && components[1].is_valid_int()) { @@ -3391,6 +3391,11 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("add_custom_data_layer", "to_position"), &TileSet::add_custom_data_layer, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("move_custom_data_layer", "layer_index", "to_position"), &TileSet::move_custom_data_layer); ClassDB::bind_method(D_METHOD("remove_custom_data_layer", "layer_index"), &TileSet::remove_custom_data_layer); + ClassDB::bind_method(D_METHOD("get_custom_data_layer_by_name", "layer_name"), &TileSet::get_custom_data_layer_by_name); + ClassDB::bind_method(D_METHOD("set_custom_data_layer_name", "layer_index", "layer_name"), &TileSet::set_custom_data_layer_name); + ClassDB::bind_method(D_METHOD("get_custom_data_layer_name", "layer_index"), &TileSet::get_custom_data_layer_name); + ClassDB::bind_method(D_METHOD("set_custom_data_layer_type", "layer_index", "layer_type"), &TileSet::set_custom_data_layer_type); + ClassDB::bind_method(D_METHOD("get_custom_data_layer_type", "layer_index"), &TileSet::get_custom_data_layer_type); // Tile proxies ClassDB::bind_method(D_METHOD("set_source_level_tile_proxy", "source_from", "source_to"), &TileSet::set_source_level_tile_proxy); @@ -4847,14 +4852,14 @@ void TileData::notify_tile_data_properties_should_change() { // Convert custom data to the new type. custom_data.resize(tile_set->get_custom_data_layers_count()); for (int i = 0; i < custom_data.size(); i++) { - if (custom_data[i].get_type() != tile_set->get_custom_data_type(i)) { + if (custom_data[i].get_type() != tile_set->get_custom_data_layer_type(i)) { Variant new_val; Callable::CallError error; - if (Variant::can_convert(custom_data[i].get_type(), tile_set->get_custom_data_type(i))) { + if (Variant::can_convert(custom_data[i].get_type(), tile_set->get_custom_data_layer_type(i))) { const Variant *args[] = { &custom_data[i] }; - Variant::construct(tile_set->get_custom_data_type(i), new_val, args, 1, error); + Variant::construct(tile_set->get_custom_data_layer_type(i), new_val, args, 1, error); } else { - Variant::construct(tile_set->get_custom_data_type(i), new_val, nullptr, 0, error); + Variant::construct(tile_set->get_custom_data_layer_type(i), new_val, nullptr, 0, error); } custom_data.write[i] = new_val; } @@ -5661,7 +5666,7 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const { Variant default_val; Callable::CallError error; Variant::construct(custom_data[i].get_type(), default_val, nullptr, 0, error); - property_info = PropertyInfo(tile_set->get_custom_data_type(i), vformat("custom_data_%d", i), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); + property_info = PropertyInfo(tile_set->get_custom_data_layer_type(i), vformat("custom_data_%d", i), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); if (custom_data[i] == default_val) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index bfd21190d8..6ea3889fce 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -479,10 +479,10 @@ public: void move_custom_data_layer(int p_from_index, int p_to_pos); void remove_custom_data_layer(int p_index); int get_custom_data_layer_by_name(String p_value) const; - void set_custom_data_name(int p_layer_id, String p_value); - String get_custom_data_name(int p_layer_id) const; - void set_custom_data_type(int p_layer_id, Variant::Type p_value); - Variant::Type get_custom_data_type(int p_layer_id) const; + void set_custom_data_layer_name(int p_layer_id, String p_value); + String get_custom_data_layer_name(int p_layer_id) const; + void set_custom_data_layer_type(int p_layer_id, Variant::Type p_value); + Variant::Type get_custom_data_layer_type(int p_layer_id) const; // Tiles proxies. void set_source_level_tile_proxy(int p_source_from, int p_source_to); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index b68cce9dda..a67716d52b 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -967,6 +967,12 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from ERR_FAIL_COND(!g->nodes.has(p_to_node)); ERR_FAIL_INDEX(p_to_port, g->nodes[p_to_node].node->get_input_port_count()); + for (const Connection &E : g->connections) { + if (E.from_node == p_from_node && E.from_port == p_from_port && E.to_node == p_to_node && E.to_port == p_to_port) { + return; + } + } + Connection c; c.from_node = p_from_node; c.from_port = p_from_port; @@ -2641,6 +2647,10 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_world", "NODE_POSITION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_position_world", "CAMERA_POSITION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_direction_world", "CAMERA_DIRECTION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_view", "NODE_POSITION_VIEW" }, // Node3D, Fragment { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_4D, "fragcoord", "FRAGCOORD" }, @@ -2669,6 +2679,10 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_world", "NODE_POSITION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_position_world", "CAMERA_POSITION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_direction_world", "CAMERA_DIRECTION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_view", "NODE_POSITION_VIEW" }, // Node3D, Light { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_4D, "fragcoord", "FRAGCOORD" }, @@ -3745,7 +3759,7 @@ String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::T } return vformat(RTR("This uniform type does not support the '%s' qualifier."), qualifier_str); } else if (qualifier == Qualifier::QUAL_GLOBAL) { - RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(uniform_name); + RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(uniform_name); if (gvt == RS::GLOBAL_VAR_TYPE_MAX) { return vformat(RTR("Global uniform '%s' does not exist.\nCreate it in the Project Settings."), uniform_name); } diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index b8667f07fe..b422d298b2 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -1901,13 +1901,7 @@ String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; case OP_REFLECT: - if (op_type == OP_TYPE_VECTOR_2D) { // Not supported. - code += "vec2(0.0);\n"; - } else if (op_type == OP_TYPE_VECTOR_4D) { // Not supported. - code += "vec4(0.0);\n"; - } else { - code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; - } + code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; case OP_STEP: code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; @@ -1967,7 +1961,7 @@ String VisualShaderNodeVectorOp::get_warning(Shader::Mode p_mode, VisualShader:: bool invalid_type = false; if (op_type == OP_TYPE_VECTOR_2D || op_type == OP_TYPE_VECTOR_4D) { - if (op == OP_CROSS || op == OP_REFLECT) { + if (op == OP_CROSS) { invalid_type = true; } } @@ -4006,14 +4000,6 @@ int VisualShaderNodeVectorRefract::get_input_port_count() const { return 3; } -VisualShaderNodeVectorRefract::PortType VisualShaderNodeVectorRefract::get_input_port_type(int p_port) const { - if (p_port == 2) { - return PORT_TYPE_SCALAR; - } - - return PORT_TYPE_VECTOR_3D; -} - String VisualShaderNodeVectorRefract::get_input_port_name(int p_port) const { switch (p_port) { case 0: @@ -4030,10 +4016,6 @@ int VisualShaderNodeVectorRefract::get_output_port_count() const { return 1; } -VisualShaderNodeVectorRefract::PortType VisualShaderNodeVectorRefract::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR_3D; -} - String VisualShaderNodeVectorRefract::get_output_port_name(int p_port) const { return ""; } @@ -4042,6 +4024,31 @@ String VisualShaderNodeVectorRefract::generate_code(Shader::Mode p_mode, VisualS return " " + p_output_vars[0] + " = refract(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } +void VisualShaderNodeVectorRefract::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX)); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_4D: { + set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0)); + set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1)); + } break; + default: + break; + } + op_type = p_op_type; + emit_changed(); +} + VisualShaderNodeVectorRefract::VisualShaderNodeVectorRefract() { set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); @@ -5581,12 +5588,16 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty case VisualShaderNodeTextureUniform::TYPE_DATA: if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) { type_code = "hint_default_black"; + } else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) { + type_code = "hint_default_transparent"; } break; case VisualShaderNodeTextureUniform::TYPE_COLOR: type_code = "source_color"; if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) { type_code += ", hint_default_black"; + } else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) { + type_code += ", hint_default_transparent"; } break; case VisualShaderNodeTextureUniform::TYPE_NORMAL_MAP: @@ -5812,7 +5823,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureUniform::get_texture_repeat); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black"), "set_color_default", "get_color_default"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black,Transparent"), "set_color_default", "get_color_default"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Default,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Default,Enabled,Disabled"), "set_texture_repeat", "get_texture_repeat"); @@ -5824,6 +5835,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() { BIND_ENUM_CONSTANT(COLOR_DEFAULT_WHITE); BIND_ENUM_CONSTANT(COLOR_DEFAULT_BLACK); + BIND_ENUM_CONSTANT(COLOR_DEFAULT_TRANSPARENT); BIND_ENUM_CONSTANT(COLOR_DEFAULT_MAX); BIND_ENUM_CONSTANT(FILTER_DEFAULT); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 1eb7b7240f..ffcb41072d 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -1564,21 +1564,20 @@ public: /// REFRACT /////////////////////////////////////// -class VisualShaderNodeVectorRefract : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorRefract, VisualShaderNode); +class VisualShaderNodeVectorRefract : public VisualShaderNodeVectorBase { + GDCLASS(VisualShaderNodeVectorRefract, VisualShaderNodeVectorBase); public: virtual String get_caption() const override; virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; virtual String get_input_port_name(int p_port) const override; virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + virtual void set_op_type(OpType p_op_type) override; VisualShaderNodeVectorRefract(); }; @@ -2131,6 +2130,7 @@ public: enum ColorDefault { COLOR_DEFAULT_WHITE, COLOR_DEFAULT_BLACK, + COLOR_DEFAULT_TRANSPARENT, COLOR_DEFAULT_MAX, }; diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp index a6553e1431..fff6dbc32a 100644 --- a/servers/audio/effects/audio_effect_record.cpp +++ b/servers/audio/effects/audio_effect_record.cpp @@ -199,16 +199,16 @@ bool AudioEffectRecord::is_recording_active() const { return recording_active; } -void AudioEffectRecord::set_format(AudioStreamSample::Format p_format) { +void AudioEffectRecord::set_format(AudioStreamWAV::Format p_format) { format = p_format; } -AudioStreamSample::Format AudioEffectRecord::get_format() const { +AudioStreamWAV::Format AudioEffectRecord::get_format() const { return format; } -Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { - AudioStreamSample::Format dst_format = format; +Ref<AudioStreamWAV> AudioEffectRecord::get_recording() const { + AudioStreamWAV::Format dst_format = format; bool stereo = true; //forcing mono is not implemented Vector<uint8_t> dst_data; @@ -216,7 +216,7 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { ERR_FAIL_COND_V(current_instance.is_null(), nullptr); ERR_FAIL_COND_V(current_instance->recording_data.size() == 0, nullptr); - if (dst_format == AudioStreamSample::FORMAT_8_BITS) { + if (dst_format == AudioStreamWAV::FORMAT_8_BITS) { int data_size = current_instance->recording_data.size(); dst_data.resize(data_size); uint8_t *w = dst_data.ptrw(); @@ -225,7 +225,7 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { int8_t v = CLAMP(current_instance->recording_data[i] * 128, -128, 127); w[i] = v; } - } else if (dst_format == AudioStreamSample::FORMAT_16_BITS) { + } else if (dst_format == AudioStreamWAV::FORMAT_16_BITS) { int data_size = current_instance->recording_data.size(); dst_data.resize(data_size * 2); uint8_t *w = dst_data.ptrw(); @@ -234,7 +234,7 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { int16_t v = CLAMP(current_instance->recording_data[i] * 32768, -32768, 32767); encode_uint16(v, &w[i * 2]); } - } else if (dst_format == AudioStreamSample::FORMAT_IMA_ADPCM) { + } else if (dst_format == AudioStreamWAV::FORMAT_IMA_ADPCM) { //byte interleave Vector<float> left; Vector<float> right; @@ -273,12 +273,12 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { ERR_PRINT("Format not implemented."); } - Ref<AudioStreamSample> sample; + Ref<AudioStreamWAV> sample; sample.instantiate(); sample->set_data(dst_data); sample->set_format(dst_format); sample->set_mix_rate(AudioServer::get_singleton()->get_mix_rate()); - sample->set_loop_mode(AudioStreamSample::LOOP_DISABLED); + sample->set_loop_mode(AudioStreamWAV::LOOP_DISABLED); sample->set_loop_begin(0); sample->set_loop_end(0); sample->set_stereo(stereo); @@ -297,6 +297,6 @@ void AudioEffectRecord::_bind_methods() { } AudioEffectRecord::AudioEffectRecord() { - format = AudioStreamSample::FORMAT_16_BITS; + format = AudioStreamWAV::FORMAT_16_BITS; recording_active = false; } diff --git a/servers/audio/effects/audio_effect_record.h b/servers/audio/effects/audio_effect_record.h index b23b63dbd8..e89d8adbde 100644 --- a/servers/audio/effects/audio_effect_record.h +++ b/servers/audio/effects/audio_effect_record.h @@ -35,7 +35,7 @@ #include "core/io/marshalls.h" #include "core/os/os.h" #include "core/os/thread.h" -#include "scene/resources/audio_stream_sample.h" +#include "scene/resources/audio_stream_wav.h" #include "servers/audio/audio_effect.h" #include "servers/audio_server.h" @@ -85,7 +85,7 @@ class AudioEffectRecord : public AudioEffect { bool recording_active; Ref<AudioEffectRecordInstance> current_instance; - AudioStreamSample::Format format; + AudioStreamWAV::Format format; void ensure_thread_stopped(); @@ -96,9 +96,9 @@ public: Ref<AudioEffectInstance> instantiate() override; void set_recording_active(bool p_record); bool is_recording_active() const; - void set_format(AudioStreamSample::Format p_format); - AudioStreamSample::Format get_format() const; - Ref<AudioStreamSample> get_recording() const; + void set_format(AudioStreamWAV::Format p_format); + AudioStreamWAV::Format get_format() const; + Ref<AudioStreamWAV> get_recording() const; AudioEffectRecord(); }; diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 1054073377..9052f8e05e 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -39,7 +39,7 @@ #include "core/os/os.h" #include "core/string/string_name.h" #include "core/templates/pair.h" -#include "scene/resources/audio_stream_sample.h" +#include "scene/resources/audio_stream_wav.h" #include "servers/audio/audio_driver_dummy.h" #include "servers/audio/effects/audio_effect_compressor.h" diff --git a/servers/audio_server.h b/servers/audio_server.h index 287a18ecde..5613267909 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -43,7 +43,7 @@ class AudioDriverDummy; class AudioStream; -class AudioStreamSample; +class AudioStreamWAV; class AudioStreamPlayback; class AudioDriver { diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 59f88844e9..4e7db7d0a5 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -278,7 +278,7 @@ void DisplayServer::tts_post_utterance_event(TTSUtteranceEvent p_event, int p_id Variant args[1]; args[0] = p_id; const Variant *argp[] = { &args[0] }; - utterance_callback[p_event].call_deferred(argp, 1); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession. + utterance_callback[p_event].call_deferredp(argp, 1); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession. } } break; case DisplayServer::TTS_UTTERANCE_BOUNDARY: { @@ -287,7 +287,7 @@ void DisplayServer::tts_post_utterance_event(TTSUtteranceEvent p_event, int p_id args[0] = p_pos; args[1] = p_id; const Variant *argp[] = { &args[0], &args[1] }; - utterance_callback[p_event].call_deferred(argp, 2); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession. + utterance_callback[p_event].call_deferredp(argp, 2); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession. } } break; default: @@ -400,7 +400,7 @@ String DisplayServer::ime_get_text() const { ERR_FAIL_V_MSG(String(), "IME or NOTIFICATION_WM_IME_UPDATEnot supported by this display server."); } -void DisplayServer::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) { +void DisplayServer::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) { WARN_PRINT("Virtual keyboard not supported by this display server."); } @@ -494,11 +494,11 @@ int64_t DisplayServer::window_get_native_handle(HandleType p_handle_type, Window } void DisplayServer::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { - WARN_PRINT("Changing the VSync mode is not supported by this display server."); + WARN_PRINT("Changing the V-Sync mode is not supported by this display server."); } DisplayServer::VSyncMode DisplayServer::window_get_vsync_mode(WindowID p_window) const { - WARN_PRINT("Changing the VSync mode is not supported by this display server."); + WARN_PRINT("Changing the V-Sync mode is not supported by this display server."); return VSyncMode::VSYNC_ENABLED; } @@ -660,7 +660,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("ime_get_selection"), &DisplayServer::ime_get_selection); ClassDB::bind_method(D_METHOD("ime_get_text"), &DisplayServer::ime_get_text); - ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "multiline", "max_length", "cursor_start", "cursor_end"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2()), DEFVAL(false), DEFVAL(-1), DEFVAL(-1), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "type", "max_length", "cursor_start", "cursor_end"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2()), DEFVAL(KEYBOARD_TYPE_DEFAULT), DEFVAL(-1), DEFVAL(-1), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("virtual_keyboard_hide"), &DisplayServer::virtual_keyboard_hide); ClassDB::bind_method(D_METHOD("virtual_keyboard_get_height"), &DisplayServer::virtual_keyboard_get_height); @@ -732,6 +732,15 @@ void DisplayServer::_bind_methods() { BIND_ENUM_CONSTANT(SCREEN_SENSOR_PORTRAIT); BIND_ENUM_CONSTANT(SCREEN_SENSOR); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_DEFAULT); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_MULTILINE); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_NUMBER); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_NUMBER_DECIMAL); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_PHONE); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_EMAIL_ADDRESS); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_PASSWORD); + BIND_ENUM_CONSTANT(KEYBOARD_TYPE_URL); + BIND_ENUM_CONSTANT(CURSOR_ARROW); BIND_ENUM_CONSTANT(CURSOR_IBEAM); BIND_ENUM_CONSTANT(CURSOR_POINTING_HAND); diff --git a/servers/display_server.h b/servers/display_server.h index 7a15df2f92..8632b53f7b 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -382,7 +382,18 @@ public: virtual Point2i ime_get_selection() const; virtual String ime_get_text() const; - virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1); + enum VirtualKeyboardType { + KEYBOARD_TYPE_DEFAULT, + KEYBOARD_TYPE_MULTILINE, + KEYBOARD_TYPE_NUMBER, + KEYBOARD_TYPE_NUMBER_DECIMAL, + KEYBOARD_TYPE_PHONE, + KEYBOARD_TYPE_EMAIL_ADDRESS, + KEYBOARD_TYPE_PASSWORD, + KEYBOARD_TYPE_URL + }; + + virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), VirtualKeyboardType p_type = KEYBOARD_TYPE_DEFAULT, int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1); virtual void virtual_keyboard_hide(); // returns height of the currently shown virtual keyboard (0 if keyboard is hidden) @@ -467,6 +478,7 @@ VARIANT_ENUM_CAST(DisplayServer::ScreenOrientation) VARIANT_ENUM_CAST(DisplayServer::WindowMode) VARIANT_ENUM_CAST(DisplayServer::WindowFlags) VARIANT_ENUM_CAST(DisplayServer::HandleType) +VARIANT_ENUM_CAST(DisplayServer::VirtualKeyboardType); VARIANT_ENUM_CAST(DisplayServer::CursorShape) VARIANT_ENUM_CAST(DisplayServer::VSyncMode) VARIANT_ENUM_CAST(DisplayServer::TTSUtteranceEvent) diff --git a/servers/movie_writer/movie_writer.cpp b/servers/movie_writer/movie_writer.cpp index 93f9f8ea08..40b2b2539e 100644 --- a/servers/movie_writer/movie_writer.cpp +++ b/servers/movie_writer/movie_writer.cpp @@ -31,6 +31,7 @@ #include "movie_writer.h" #include "core/config/project_settings.h" #include "core/io/dir_access.h" +#include "core/os/time.h" #include "servers/display_server.h" MovieWriter *MovieWriter::writers[MovieWriter::MAX_WRITERS]; @@ -183,4 +184,29 @@ void MovieWriter::add_frame(const Ref<Image> &p_image) { void MovieWriter::end() { write_end(); + + // Print a report with various statistics. + print_line("----------------"); + String movie_path = Engine::get_singleton()->get_write_movie_path(); + if (movie_path.is_relative_path()) { + // Print absolute path to make finding the file easier, + // and to make it clickable in terminal emulators that support this. + movie_path = ProjectSettings::get_singleton()->globalize_path("res://").plus_file(movie_path); + } + print_line(vformat("Done recording movie at path: %s", movie_path)); + + const int movie_time_seconds = Engine::get_singleton()->get_frames_drawn() / fps; + const String movie_time = vformat("%s:%s:%s", + String::num(movie_time_seconds / 3600).pad_zeros(2), + String::num((movie_time_seconds % 3600) / 60).pad_zeros(2), + String::num(movie_time_seconds % 60).pad_zeros(2)); + + const int real_time_seconds = Time::get_singleton()->get_ticks_msec() / 1000; + const String real_time = vformat("%s:%s:%s", + String::num(real_time_seconds / 3600).pad_zeros(2), + String::num((real_time_seconds % 3600) / 60).pad_zeros(2), + String::num(real_time_seconds % 60).pad_zeros(2)); + + print_line(vformat("%d frames at %d FPS (movie length: %s), recorded in %s (%d%% of real-time speed).", Engine::get_singleton()->get_frames_drawn(), fps, movie_time, real_time, (float(movie_time_seconds) / real_time_seconds) * 100)); + print_line("----------------"); } diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index 6c48c4a8de..52855c5931 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -30,6 +30,10 @@ #include "navigation_server_3d.h" +#ifdef DEBUG_ENABLED +#include "core/config/project_settings.h" +#endif // DEBUG_ENABLED + NavigationServer3D *NavigationServer3D::singleton = nullptr; void NavigationServer3D::_bind_methods() { @@ -92,6 +96,8 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("process", "delta_time"), &NavigationServer3D::process); ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map"))); + + ADD_SIGNAL(MethodInfo("navigation_debug_changed")); } const NavigationServer3D *NavigationServer3D::get_singleton() { @@ -105,6 +111,19 @@ NavigationServer3D *NavigationServer3D::get_singleton_mut() { NavigationServer3D::NavigationServer3D() { ERR_FAIL_COND(singleton != nullptr); singleton = this; + +#ifdef DEBUG_ENABLED + debug_navigation_edge_connection_color = GLOBAL_DEF("debug/shapes/navigation/edge_connection_color", Color(1.0, 0.0, 1.0, 1.0)); + debug_navigation_geometry_edge_color = GLOBAL_DEF("debug/shapes/navigation/geometry_edge_color", Color(0.5, 1.0, 1.0, 1.0)); + debug_navigation_geometry_face_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_color", Color(0.5, 1.0, 1.0, 0.4)); + debug_navigation_geometry_edge_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_edge_disabled_color", Color(0.5, 0.5, 0.5, 1.0)); + debug_navigation_geometry_face_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_disabled_color", Color(0.5, 0.5, 0.5, 0.4)); + debug_navigation_enable_edge_connections = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections", true); + debug_navigation_enable_edge_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections_xray", true); + debug_navigation_enable_edge_lines = GLOBAL_DEF("debug/shapes/navigation/enable_edge_lines", true); + debug_navigation_enable_edge_lines_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_lines_xray", true); + debug_navigation_enable_geometry_face_random_color = GLOBAL_DEF("debug/shapes/navigation/enable_geometry_face_random_color", true); +#endif // DEBUG_ENABLED } NavigationServer3D::~NavigationServer3D() { @@ -121,3 +140,241 @@ NavigationServer3D *NavigationServer3DManager::new_default_server() { ERR_FAIL_COND_V(create_callback == nullptr, nullptr); return create_callback(); } + +#ifdef DEBUG_ENABLED +void NavigationServer3D::_emit_navigation_debug_changed_signal() { + if (debug_dirty) { + debug_dirty = false; + emit_signal(SNAME("navigation_debug_changed")); + } +} +#endif // DEBUG_ENABLED + +#ifdef DEBUG_ENABLED +Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_geometry_face_material() { + if (debug_navigation_geometry_face_material.is_valid()) { + return debug_navigation_geometry_face_material; + } + + bool enabled_geometry_face_random_color = get_debug_navigation_enable_geometry_face_random_color(); + + Color debug_navigation_geometry_face_color = get_debug_navigation_geometry_face_color(); + + Ref<StandardMaterial3D> face_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + face_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + face_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + face_material->set_albedo(debug_navigation_geometry_face_color); + if (enabled_geometry_face_random_color) { + face_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + face_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + } + + debug_navigation_geometry_face_material = face_material; + + return debug_navigation_geometry_face_material; +} + +Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_geometry_edge_material() { + if (debug_navigation_geometry_edge_material.is_valid()) { + return debug_navigation_geometry_edge_material; + } + + bool enabled_edge_lines_xray = get_debug_navigation_enable_edge_lines_xray(); + + Color debug_navigation_geometry_edge_color = get_debug_navigation_geometry_edge_color(); + + Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + line_material->set_albedo(debug_navigation_geometry_edge_color); + if (enabled_edge_lines_xray) { + line_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); + } + + debug_navigation_geometry_edge_material = line_material; + + return debug_navigation_geometry_edge_material; +} + +Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_geometry_face_disabled_material() { + if (debug_navigation_geometry_face_disabled_material.is_valid()) { + return debug_navigation_geometry_face_disabled_material; + } + + Color debug_navigation_geometry_face_disabled_color = get_debug_navigation_geometry_face_disabled_color(); + + Ref<StandardMaterial3D> face_disabled_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + face_disabled_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + face_disabled_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + face_disabled_material->set_albedo(debug_navigation_geometry_face_disabled_color); + + debug_navigation_geometry_face_disabled_material = face_disabled_material; + + return debug_navigation_geometry_face_disabled_material; +} + +Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_geometry_edge_disabled_material() { + if (debug_navigation_geometry_edge_disabled_material.is_valid()) { + return debug_navigation_geometry_edge_disabled_material; + } + + bool enabled_edge_lines_xray = get_debug_navigation_enable_edge_lines_xray(); + + Color debug_navigation_geometry_edge_disabled_color = get_debug_navigation_geometry_edge_disabled_color(); + + Ref<StandardMaterial3D> line_disabled_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + line_disabled_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + line_disabled_material->set_albedo(debug_navigation_geometry_edge_disabled_color); + if (enabled_edge_lines_xray) { + line_disabled_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); + } + + debug_navigation_geometry_edge_disabled_material = line_disabled_material; + + return debug_navigation_geometry_edge_disabled_material; +} + +Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_edge_connections_material() { + if (debug_navigation_edge_connections_material.is_valid()) { + return debug_navigation_edge_connections_material; + } + + bool enabled_edge_connections_xray = get_debug_navigation_enable_edge_connections_xray(); + + Color debug_navigation_edge_connection_color = get_debug_navigation_edge_connection_color(); + + Ref<StandardMaterial3D> edge_connections_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + edge_connections_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + edge_connections_material->set_albedo(debug_navigation_edge_connection_color); + if (enabled_edge_connections_xray) { + edge_connections_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); + } + edge_connections_material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MAX - 2); + + debug_navigation_edge_connections_material = edge_connections_material; + + return debug_navigation_edge_connections_material; +} + +void NavigationServer3D::set_debug_navigation_edge_connection_color(const Color &p_color) { + debug_navigation_edge_connection_color = p_color; + if (debug_navigation_edge_connections_material.is_valid()) { + debug_navigation_edge_connections_material->set_albedo(debug_navigation_edge_connection_color); + } +} + +Color NavigationServer3D::get_debug_navigation_edge_connection_color() const { + return debug_navigation_edge_connection_color; +} + +void NavigationServer3D::set_debug_navigation_geometry_edge_color(const Color &p_color) { + debug_navigation_geometry_edge_color = p_color; + if (debug_navigation_geometry_edge_material.is_valid()) { + debug_navigation_geometry_edge_material->set_albedo(debug_navigation_geometry_edge_color); + } +} + +Color NavigationServer3D::get_debug_navigation_geometry_edge_color() const { + return debug_navigation_geometry_edge_color; +} + +void NavigationServer3D::set_debug_navigation_geometry_face_color(const Color &p_color) { + debug_navigation_geometry_face_color = p_color; + if (debug_navigation_geometry_face_material.is_valid()) { + debug_navigation_geometry_face_material->set_albedo(debug_navigation_geometry_face_color); + } +} + +Color NavigationServer3D::get_debug_navigation_geometry_face_color() const { + return debug_navigation_geometry_face_color; +} + +void NavigationServer3D::set_debug_navigation_geometry_edge_disabled_color(const Color &p_color) { + debug_navigation_geometry_edge_disabled_color = p_color; + if (debug_navigation_geometry_edge_disabled_material.is_valid()) { + debug_navigation_geometry_edge_disabled_material->set_albedo(debug_navigation_geometry_edge_disabled_color); + } +} + +Color NavigationServer3D::get_debug_navigation_geometry_edge_disabled_color() const { + return debug_navigation_geometry_edge_disabled_color; +} + +void NavigationServer3D::set_debug_navigation_geometry_face_disabled_color(const Color &p_color) { + debug_navigation_geometry_face_disabled_color = p_color; + if (debug_navigation_geometry_face_disabled_material.is_valid()) { + debug_navigation_geometry_face_disabled_material->set_albedo(debug_navigation_geometry_face_disabled_color); + } +} + +Color NavigationServer3D::get_debug_navigation_geometry_face_disabled_color() const { + return debug_navigation_geometry_face_disabled_color; +} + +void NavigationServer3D::set_debug_navigation_enable_edge_connections(const bool p_value) { + debug_navigation_enable_edge_connections = p_value; + debug_dirty = true; + call_deferred("_emit_navigation_debug_changed_signal"); +} + +bool NavigationServer3D::get_debug_navigation_enable_edge_connections() const { + return debug_navigation_enable_edge_connections; +} + +void NavigationServer3D::set_debug_navigation_enable_edge_connections_xray(const bool p_value) { + debug_navigation_enable_edge_connections_xray = p_value; + if (debug_navigation_edge_connections_material.is_valid()) { + debug_navigation_edge_connections_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, debug_navigation_enable_edge_connections_xray); + } +} + +bool NavigationServer3D::get_debug_navigation_enable_edge_connections_xray() const { + return debug_navigation_enable_edge_connections_xray; +} + +void NavigationServer3D::set_debug_navigation_enable_edge_lines(const bool p_value) { + debug_navigation_enable_edge_lines = p_value; + debug_dirty = true; + call_deferred("_emit_navigation_debug_changed_signal"); +} + +bool NavigationServer3D::get_debug_navigation_enable_edge_lines() const { + return debug_navigation_enable_edge_lines; +} + +void NavigationServer3D::set_debug_navigation_enable_edge_lines_xray(const bool p_value) { + debug_navigation_enable_edge_lines_xray = p_value; + if (debug_navigation_geometry_edge_material.is_valid()) { + debug_navigation_geometry_edge_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, debug_navigation_enable_edge_lines_xray); + } +} + +bool NavigationServer3D::get_debug_navigation_enable_edge_lines_xray() const { + return debug_navigation_enable_edge_lines_xray; +} + +void NavigationServer3D::set_debug_navigation_enable_geometry_face_random_color(const bool p_value) { + debug_navigation_enable_geometry_face_random_color = p_value; + debug_dirty = true; + call_deferred("_emit_navigation_debug_changed_signal"); +} + +bool NavigationServer3D::get_debug_navigation_enable_geometry_face_random_color() const { + return debug_navigation_enable_geometry_face_random_color; +} + +void NavigationServer3D::set_debug_enabled(bool p_enabled) { + if (debug_enabled != p_enabled) { + debug_dirty = true; + } + + debug_enabled = p_enabled; + + if (debug_dirty) { + call_deferred("_emit_navigation_debug_changed_signal"); + } +} + +bool NavigationServer3D::get_debug_enabled() const { + return debug_enabled; +} +#endif // DEBUG_ENABLED diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index cf91596604..f24c0117d1 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -207,6 +207,68 @@ public: NavigationServer3D(); virtual ~NavigationServer3D(); + +#ifdef DEBUG_ENABLED + bool debug_enabled = false; + bool debug_dirty = true; + void _emit_navigation_debug_changed_signal(); + + void set_debug_enabled(bool p_enabled); + bool get_debug_enabled() const; + + Color debug_navigation_edge_connection_color = Color(1.0, 0.0, 1.0, 1.0); + Color debug_navigation_geometry_edge_color = Color(0.5, 1.0, 1.0, 1.0); + Color debug_navigation_geometry_face_color = Color(0.5, 1.0, 1.0, 0.4); + Color debug_navigation_geometry_edge_disabled_color = Color(0.5, 0.5, 0.5, 1.0); + Color debug_navigation_geometry_face_disabled_color = Color(0.5, 0.5, 0.5, 0.4); + bool debug_navigation_enable_edge_connections = true; + bool debug_navigation_enable_edge_connections_xray = true; + bool debug_navigation_enable_edge_lines = true; + bool debug_navigation_enable_edge_lines_xray = true; + bool debug_navigation_enable_geometry_face_random_color = true; + + Ref<StandardMaterial3D> debug_navigation_geometry_edge_material; + Ref<StandardMaterial3D> debug_navigation_geometry_face_material; + Ref<StandardMaterial3D> debug_navigation_geometry_edge_disabled_material; + Ref<StandardMaterial3D> debug_navigation_geometry_face_disabled_material; + Ref<StandardMaterial3D> debug_navigation_edge_connections_material; + + void set_debug_navigation_edge_connection_color(const Color &p_color); + Color get_debug_navigation_edge_connection_color() const; + + void set_debug_navigation_geometry_edge_color(const Color &p_color); + Color get_debug_navigation_geometry_edge_color() const; + + void set_debug_navigation_geometry_face_color(const Color &p_color); + Color get_debug_navigation_geometry_face_color() const; + + void set_debug_navigation_geometry_edge_disabled_color(const Color &p_color); + Color get_debug_navigation_geometry_edge_disabled_color() const; + + void set_debug_navigation_geometry_face_disabled_color(const Color &p_color); + Color get_debug_navigation_geometry_face_disabled_color() const; + + void set_debug_navigation_enable_edge_connections(const bool p_value); + bool get_debug_navigation_enable_edge_connections() const; + + void set_debug_navigation_enable_edge_connections_xray(const bool p_value); + bool get_debug_navigation_enable_edge_connections_xray() const; + + void set_debug_navigation_enable_edge_lines(const bool p_value); + bool get_debug_navigation_enable_edge_lines() const; + + void set_debug_navigation_enable_edge_lines_xray(const bool p_value); + bool get_debug_navigation_enable_edge_lines_xray() const; + + void set_debug_navigation_enable_geometry_face_random_color(const bool p_value); + bool get_debug_navigation_enable_geometry_face_random_color() const; + + Ref<StandardMaterial3D> get_debug_navigation_geometry_face_material(); + Ref<StandardMaterial3D> get_debug_navigation_geometry_edge_material(); + Ref<StandardMaterial3D> get_debug_navigation_geometry_face_disabled_material(); + Ref<StandardMaterial3D> get_debug_navigation_geometry_edge_disabled_material(); + Ref<StandardMaterial3D> get_debug_navigation_edge_connections_material(); +#endif // DEBUG_ENABLED }; typedef NavigationServer3D *(*NavigationServer3DCallback)(); diff --git a/servers/physics_2d/godot_area_2d.cpp b/servers/physics_2d/godot_area_2d.cpp index 11208f2d5b..af90f96438 100644 --- a/servers/physics_2d/godot_area_2d.cpp +++ b/servers/physics_2d/godot_area_2d.cpp @@ -247,7 +247,11 @@ void GodotArea2D::call_queries() { Callable::CallError ce; Variant ret; - monitor_callback.call((const Variant **)resptr, 5, ret, ce); + monitor_callback.callp((const Variant **)resptr, 5, ret, ce); + + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT_ONCE("Error calling event callback method " + Variant::get_callable_error_text(monitor_callback, (const Variant **)resptr, 5, ce)); + } } } else { monitored_bodies.clear(); @@ -285,7 +289,11 @@ void GodotArea2D::call_queries() { Callable::CallError ce; Variant ret; - area_monitor_callback.call((const Variant **)resptr, 5, ret, ce); + area_monitor_callback.callp((const Variant **)resptr, 5, ret, ce); + + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT_ONCE("Error calling event callback method " + Variant::get_callable_error_text(area_monitor_callback, (const Variant **)resptr, 5, ce)); + } } } else { monitored_areas.clear(); diff --git a/servers/physics_2d/godot_body_2d.cpp b/servers/physics_2d/godot_body_2d.cpp index 6873504f70..268beb1a55 100644 --- a/servers/physics_2d/godot_body_2d.cpp +++ b/servers/physics_2d/godot_body_2d.cpp @@ -683,10 +683,10 @@ void GodotBody2D::call_queries() { Callable::CallError ce; Variant rv; if (fi_callback_data->udata.get_type() != Variant::NIL) { - fi_callback_data->callable.call(vp, 2, rv, ce); + fi_callback_data->callable.callp(vp, 2, rv, ce); } else { - fi_callback_data->callable.call(vp, 1, rv, ce); + fi_callback_data->callable.callp(vp, 1, rv, ce); } } } diff --git a/servers/physics_3d/godot_area_3d.cpp b/servers/physics_3d/godot_area_3d.cpp index e2ad765d62..9765d0bf58 100644 --- a/servers/physics_3d/godot_area_3d.cpp +++ b/servers/physics_3d/godot_area_3d.cpp @@ -276,7 +276,11 @@ void GodotArea3D::call_queries() { Callable::CallError ce; Variant ret; - monitor_callback.call((const Variant **)resptr, 5, ret, ce); + monitor_callback.callp((const Variant **)resptr, 5, ret, ce); + + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT_ONCE("Error calling monitor callback method " + Variant::get_callable_error_text(monitor_callback, (const Variant **)resptr, 5, ce)); + } } } else { monitored_bodies.clear(); @@ -314,7 +318,11 @@ void GodotArea3D::call_queries() { Callable::CallError ce; Variant ret; - area_monitor_callback.call((const Variant **)resptr, 5, ret, ce); + area_monitor_callback.callp((const Variant **)resptr, 5, ret, ce); + + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT_ONCE("Error calling area monitor callback method " + Variant::get_callable_error_text(area_monitor_callback, (const Variant **)resptr, 5, ce)); + } } } else { monitored_areas.clear(); diff --git a/servers/physics_3d/godot_body_3d.cpp b/servers/physics_3d/godot_body_3d.cpp index ad97533f44..4c89106839 100644 --- a/servers/physics_3d/godot_body_3d.cpp +++ b/servers/physics_3d/godot_body_3d.cpp @@ -766,7 +766,7 @@ void GodotBody3D::call_queries() { Callable::CallError ce; int argc = (fi_callback_data->udata.get_type() == Variant::NIL) ? 1 : 2; Variant rv; - fi_callback_data->callable.call(vp, argc, rv, ce); + fi_callback_data->callable.callp(vp, argc, rv, ce); } } diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 41aae36785..26768e300c 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -147,6 +147,16 @@ PhysicsDirectBodyState2D::PhysicsDirectBodyState2D() {} /////////////////////////////////////////////////////// +Ref<PhysicsRayQueryParameters2D> PhysicsRayQueryParameters2D::create(Vector2 p_from, Vector2 p_to, uint32_t p_mask, const Vector<RID> &p_exclude) { + Ref<PhysicsRayQueryParameters2D> params; + params.instantiate(); + params->set_from(p_from); + params->set_to(p_to); + params->set_collision_mask(p_mask); + params->set_exclude(p_exclude); + return params; +} + void PhysicsRayQueryParameters2D::set_exclude(const Vector<RID> &p_exclude) { parameters.exclude.clear(); for (int i = 0; i < p_exclude.size(); i++) { @@ -165,6 +175,8 @@ Vector<RID> PhysicsRayQueryParameters2D::get_exclude() const { } void PhysicsRayQueryParameters2D::_bind_methods() { + ClassDB::bind_static_method("PhysicsRayQueryParameters2D", D_METHOD("create", "from", "to", "collision_mask", "exclude"), &PhysicsRayQueryParameters2D::create, DEFVAL(UINT32_MAX), DEFVAL(Vector<RID>())); + ClassDB::bind_method(D_METHOD("set_from", "from"), &PhysicsRayQueryParameters2D::set_from); ClassDB::bind_method(D_METHOD("get_from"), &PhysicsRayQueryParameters2D::get_from); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 7a821c64e6..6d95c591c2 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -605,6 +605,7 @@ protected: static void _bind_methods(); public: + static Ref<PhysicsRayQueryParameters2D> create(Vector2 p_from, Vector2 p_to, uint32_t p_mask, const Vector<RID> &p_exclude); const PhysicsDirectSpaceState2D::RayParameters &get_parameters() const { return parameters; } void set_from(const Vector2 &p_from) { parameters.from = p_from; } diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index a606d055f7..f25db22e66 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -184,6 +184,8 @@ Vector<RID> PhysicsRayQueryParameters3D::get_exclude() const { } void PhysicsRayQueryParameters3D::_bind_methods() { + ClassDB::bind_static_method("PhysicsRayQueryParameters3D", D_METHOD("create", "from", "to", "collision_mask", "exclude"), &PhysicsRayQueryParameters3D::create, DEFVAL(UINT32_MAX), DEFVAL(Vector<RID>())); + ClassDB::bind_method(D_METHOD("set_from", "from"), &PhysicsRayQueryParameters3D::set_from); ClassDB::bind_method(D_METHOD("get_from"), &PhysicsRayQueryParameters3D::get_from); @@ -220,6 +222,16 @@ void PhysicsRayQueryParameters3D::_bind_methods() { /////////////////////////////////////////////////////// +Ref<PhysicsRayQueryParameters3D> PhysicsRayQueryParameters3D::create(Vector3 p_from, Vector3 p_to, uint32_t p_mask, const Vector<RID> &p_exclude) { + Ref<PhysicsRayQueryParameters3D> params; + params.instantiate(); + params->set_from(p_from); + params->set_to(p_to); + params->set_collision_mask(p_mask); + params->set_exclude(p_exclude); + return params; +} + void PhysicsPointQueryParameters3D::set_exclude(const Vector<RID> &p_exclude) { parameters.exclude.clear(); for (int i = 0; i < p_exclude.size(); i++) { diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 86a41d96ef..837073409a 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -816,6 +816,7 @@ protected: static void _bind_methods(); public: + static Ref<PhysicsRayQueryParameters3D> create(Vector3 p_from, Vector3 p_to, uint32_t p_mask, const Vector<RID> &p_exclude); const PhysicsDirectSpaceState3D::RayParameters &get_parameters() const { return parameters; } void set_from(const Vector3 &p_from) { parameters.from = p_from; } diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h index b803dd6f96..be98770b90 100644 --- a/servers/rendering/dummy/rasterizer_scene_dummy.h +++ b/servers/rendering/dummy/rasterizer_scene_dummy.h @@ -35,33 +35,10 @@ class RasterizerSceneDummy : public RendererSceneRender { public: - GeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; } - void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override {} - void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override {} - void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) override {} - void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override {} - void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override {} - void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override {} - void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override {} - void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override {} - void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override {} - void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override {} - void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override {} - void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override {} - void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override {} - void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override {} - void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override {} - void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override {} - void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override {} + RenderGeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; } + void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override {} uint32_t geometry_instance_get_pair_mask() override { return 0; } - void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override {} - void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} - void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} - void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} - void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override {} - - void geometry_instance_free(GeometryInstance *p_geometry_instance) override {} /* SHADOW ATLAS API */ @@ -92,49 +69,24 @@ public: /* ENVIRONMENT API */ - RID environment_allocate() override { return RID(); } - void environment_initialize(RID p_rid) override {} - void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override {} - void environment_set_sky(RID p_env, RID p_sky) override {} - void environment_set_sky_custom_fov(RID p_env, float p_scale) override {} - void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override {} - void environment_set_bg_color(RID p_env, const Color &p_color) override {} - void environment_set_bg_energy(RID p_env, float p_energy) override {} - void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override {} - void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override {} - - void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override {} void environment_glow_set_use_bicubic_upscale(bool p_enable) override {} void environment_glow_set_use_high_quality(bool p_enable) override {} - void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) override {} void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override {} - void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) override {} + void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {} - void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override {} - void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {} - void environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {} + void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {} void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override {} void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override {} void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override {} - void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override {} - - void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override {} - - void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override {} - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) override {} void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {} void environment_set_volumetric_fog_filter_active(bool p_enable) override {} Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); } - bool is_environment(RID p_env) const override { return false; } - RS::EnvironmentBG environment_get_background(RID p_env) const override { return RS::ENV_BG_KEEP; } - int environment_get_canvas_max_layer(RID p_env) const override { return 0; } - RID camera_effects_allocate() override { return RID(); } void camera_effects_initialize(RID p_rid) override {} void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override {} @@ -179,20 +131,20 @@ public: RID voxel_gi_instance_create(RID p_voxel_gi) override { return RID(); } void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override {} bool voxel_gi_needs_update(RID p_probe) const override { return false; } - void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override {} + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) override {} void voxel_gi_set_quality(RS::VoxelGIQuality) override {} - void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_info = nullptr) override {} - void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} - void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override {} + void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_info = nullptr) override {} + void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} + void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override {} void set_scene_pass(uint64_t p_pass) override {} void set_time(double p_time, double p_step) override {} void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) override {} RID render_buffers_create() override { return RID(); } - void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override {} + void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override {} void gi_set_use_half_resolution(bool p_enable) override {} void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override {} @@ -203,7 +155,14 @@ public: TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) override { return TypedArray<Image>(); } - bool free(RID p_rid) override { return false; } + bool free(RID p_rid) override { + if (is_environment(p_rid)) { + environment_free(p_rid); + return true; + } else { + return false; + } + } void update() override {} void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override {} diff --git a/servers/rendering/dummy/storage/material_storage.h b/servers/rendering/dummy/storage/material_storage.h index 6721284b23..e25a2ac3a9 100644 --- a/servers/rendering/dummy/storage/material_storage.h +++ b/servers/rendering/dummy/storage/material_storage.h @@ -38,23 +38,23 @@ namespace RendererDummy { class MaterialStorage : public RendererMaterialStorage { public: - /* GLOBAL VARIABLE API */ + /* GLOBAL SHADER UNIFORM API */ - virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override {} - virtual void global_variable_remove(const StringName &p_name) override {} - virtual Vector<StringName> global_variable_get_list() const override { return Vector<StringName>(); } + virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override {} + virtual void global_shader_uniform_remove(const StringName &p_name) override {} + virtual Vector<StringName> global_shader_uniform_get_list() const override { return Vector<StringName>(); } - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) override {} - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) override {} - virtual Variant global_variable_get(const StringName &p_name) const override { return Variant(); } - virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override { return RS::GLOBAL_VAR_TYPE_MAX; } + virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override {} + virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override {} + virtual Variant global_shader_uniform_get(const StringName &p_name) const override { return Variant(); } + virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override { return RS::GLOBAL_VAR_TYPE_MAX; } - virtual void global_variables_load_settings(bool p_load_textures = true) override {} - virtual void global_variables_clear() override {} + virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override {} + virtual void global_shader_uniforms_clear() override {} - virtual int32_t global_variables_instance_allocate(RID p_instance) override { return 0; } - virtual void global_variables_instance_free(RID p_instance) override {} - virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override {} + virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override { return 0; } + virtual void global_shader_uniforms_instance_free(RID p_instance) override {} + virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override {} /* SHADER API */ @@ -66,7 +66,7 @@ public: virtual void shader_set_path_hint(RID p_shader, const String &p_code) override {} virtual String shader_get_code(RID p_shader) const override { return ""; } - virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {} + virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {} virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override {} virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override { return RID(); } @@ -89,7 +89,7 @@ public: virtual bool material_is_animated(RID p_material) override { return false; } virtual bool material_casts_shadows(RID p_material) override { return false; } - virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {} + virtual void material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) override {} virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {} }; diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h index 8dfcd978ac..aab5145982 100644 --- a/servers/rendering/dummy/storage/mesh_storage.h +++ b/servers/rendering/dummy/storage/mesh_storage.h @@ -37,17 +37,44 @@ namespace RendererDummy { class MeshStorage : public RendererMeshStorage { +private: + struct DummyMesh : public RID { + Vector<RS::SurfaceData> surfaces; + int blend_shape_count; + RS::BlendShapeMode blend_shape_mode; + PackedFloat32Array blend_shape_values; + }; + + mutable RID_Owner<DummyMesh> mesh_owner; + public: /* MESH API */ - virtual RID mesh_allocate() override { return RID(); } - virtual void mesh_initialize(RID p_rid) override {} + virtual RID mesh_allocate() override { + return mesh_owner.allocate_rid(); + } + + virtual void mesh_initialize(RID p_rid) override { + mesh_owner.initialize_rid(p_rid, DummyMesh()); + } virtual void mesh_free(RID p_rid) override {} virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override {} virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override { return false; } - virtual void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override {} + virtual void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override { + DummyMesh *m = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_COND(!m); + m->surfaces.push_back(RS::SurfaceData()); + RS::SurfaceData *s = &m->surfaces.write[m->surfaces.size() - 1]; + s->format = p_surface.format; + s->primitive = p_surface.primitive; + s->vertex_data = p_surface.vertex_data; + s->attribute_data = p_surface.attribute_data; + s->vertex_count = p_surface.vertex_count; + s->index_data = p_surface.index_data; + s->index_count = p_surface.index_count; + } virtual int mesh_get_blend_shape_count(RID p_mesh) const override { return 0; } @@ -61,8 +88,19 @@ public: virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override {} virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const override { return RID(); } - virtual RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const override { return RS::SurfaceData(); } - virtual int mesh_get_surface_count(RID p_mesh) const override { return 0; } + virtual RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const override { + DummyMesh *m = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_COND_V(!m, RS::SurfaceData()); + RS::SurfaceData s = m->surfaces[p_surface]; + return s; + } + + virtual int mesh_get_surface_count(RID p_mesh) const override { + DummyMesh *m = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_COND_V(!m, 0); + print_line(m->surfaces.size()); + return m->surfaces.size(); + } virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override {} virtual AABB mesh_get_custom_aabb(RID p_mesh) const override { return AABB(); } diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index dea68ac61c..86e5e4802b 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -605,9 +605,13 @@ void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from, } if (p_antialiased) { - float border_size = 2.0; - if (p_width < border_size) { - border_size = p_width; + // Use the same antialiasing feather size as StyleBoxFlat's default + // (but doubled, as it's specified for both sides here). + // This value is empirically determined to provide good antialiasing quality + // while not making lines appear too soft. + float border_size = 1.25f; + if (p_width < 1.0f) { + border_size *= p_width; } Vector2 dir2 = diff.normalized(); @@ -774,9 +778,13 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point Color *colors_ptr = colors.ptrw(); if (p_antialiased) { - float border_size = 2.0; - if (p_width < border_size) { - border_size = p_width; + // Use the same antialiasing feather size as StyleBoxFlat's default + // (but doubled, as it's specified for both sides here). + // This value is empirically determined to provide good antialiasing quality + // while not making lines appear too soft. + float border_size = 1.25f; + if (p_width < 1.0f) { + border_size *= p_width; } Color color2 = Color(1, 1, 1, 0); @@ -1906,11 +1914,11 @@ void RendererCanvasCull::update_visibility_notifiers() { if (!visibility_notifier->enter_callable.is_null()) { if (RSG::threaded) { - visibility_notifier->enter_callable.call_deferred(nullptr, 0); + visibility_notifier->enter_callable.call_deferredp(nullptr, 0); } else { Callable::CallError ce; Variant ret; - visibility_notifier->enter_callable.call(nullptr, 0, ret, ce); + visibility_notifier->enter_callable.callp(nullptr, 0, ret, ce); } } } else { @@ -1919,11 +1927,11 @@ void RendererCanvasCull::update_visibility_notifiers() { if (!visibility_notifier->exit_callable.is_null()) { if (RSG::threaded) { - visibility_notifier->exit_callable.call_deferred(nullptr, 0); + visibility_notifier->exit_callable.call_deferredp(nullptr, 0); } else { Callable::CallError ce; Variant ret; - visibility_notifier->exit_callable.call(nullptr, 0, ret, ce); + visibility_notifier->exit_callable.callp(nullptr, 0, ret, ce); } } } diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp index b331ec2c1d..80e71a0df3 100644 --- a/servers/rendering/renderer_compositor.cpp +++ b/servers/rendering/renderer_compositor.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "core/os/os.h" #include "core/string/print_string.h" +#include "servers/xr_server.h" RendererCompositor *(*RendererCompositor::_create_func)() = nullptr; bool RendererCompositor::low_end = false; @@ -46,7 +47,11 @@ bool RendererCompositor::is_xr_enabled() const { } RendererCompositor::RendererCompositor() { - xr_enabled = GLOBAL_GET("xr/shaders/enabled"); + if (XRServer::get_xr_mode() == XRServer::XRMODE_DEFAULT) { + xr_enabled = GLOBAL_GET("xr/shaders/enabled"); + } else { + xr_enabled = XRServer::get_xr_mode() == XRServer::XRMODE_ON; + } } RendererCanvasRender *RendererCanvasRender::singleton = nullptr; diff --git a/servers/rendering/renderer_geometry_instance.cpp b/servers/rendering/renderer_geometry_instance.cpp new file mode 100644 index 0000000000..675659f4c8 --- /dev/null +++ b/servers/rendering/renderer_geometry_instance.cpp @@ -0,0 +1,138 @@ +/*************************************************************************/ +/* renderer_geometry_instance.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "servers/rendering/renderer_geometry_instance.h" + +void RenderGeometryInstanceBase::set_skeleton(RID p_skeleton) { + data->skeleton = p_skeleton; + + _mark_dirty(); + data->dirty_dependencies = true; +} + +void RenderGeometryInstanceBase::set_material_override(RID p_override) { + data->material_override = p_override; + + _mark_dirty(); + data->dirty_dependencies = true; +} + +void RenderGeometryInstanceBase::set_material_overlay(RID p_overlay) { + data->material_overlay = p_overlay; + + _mark_dirty(); + data->dirty_dependencies = true; +} + +void RenderGeometryInstanceBase::set_surface_materials(const Vector<RID> &p_materials) { + data->surface_materials = p_materials; + + _mark_dirty(); + data->dirty_dependencies = true; +} + +void RenderGeometryInstanceBase::set_mesh_instance(RID p_mesh_instance) { + mesh_instance = p_mesh_instance; + + _mark_dirty(); +} + +void RenderGeometryInstanceBase::set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { + transform = p_transform; + mirror = p_transform.basis.determinant() < 0; + data->aabb = p_aabb; + transformed_aabb = p_transformed_aabb; + + Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); + // handle non uniform scale here + + float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); + float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); + non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; + + lod_model_scale = max_scale; +} + +void RenderGeometryInstanceBase::set_lod_bias(float p_lod_bias) { + lod_bias = p_lod_bias; +} + +void RenderGeometryInstanceBase::set_layer_mask(uint32_t p_layer_mask) { + layer_mask = p_layer_mask; +} + +void RenderGeometryInstanceBase::set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) { + fade_near = p_enable_near; + fade_near_begin = p_near_begin; + fade_near_end = p_near_end; + fade_far = p_enable_far; + fade_far_begin = p_far_begin; + fade_far_end = p_far_end; +} + +void RenderGeometryInstanceBase::set_parent_fade_alpha(float p_alpha) { + parent_fade_alpha = p_alpha; +} + +void RenderGeometryInstanceBase::set_transparency(float p_transparency) { + force_alpha = CLAMP(1.0 - p_transparency, 0, 1); +} + +void RenderGeometryInstanceBase::set_use_baked_light(bool p_enable) { + data->use_baked_light = p_enable; + + _mark_dirty(); +} + +void RenderGeometryInstanceBase::set_use_dynamic_gi(bool p_enable) { + data->use_dynamic_gi = p_enable; + + _mark_dirty(); +} + +void RenderGeometryInstanceBase::set_instance_shader_uniforms_offset(int32_t p_offset) { + shader_uniforms_offset = p_offset; + + _mark_dirty(); +} + +void RenderGeometryInstanceBase::set_cast_double_sided_shadows(bool p_enable) { + data->cast_double_sided_shadows = p_enable; + + _mark_dirty(); +} + +Transform3D RenderGeometryInstanceBase::get_transform() { + return transform; +} + +AABB RenderGeometryInstanceBase::get_aabb() { + return data->aabb; +} diff --git a/servers/rendering/renderer_geometry_instance.h b/servers/rendering/renderer_geometry_instance.h new file mode 100644 index 0000000000..fecb9878c2 --- /dev/null +++ b/servers/rendering/renderer_geometry_instance.h @@ -0,0 +1,150 @@ +/*************************************************************************/ +/* renderer_geometry_instance.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RENDERER_GEOMETRY_INSTANCE_H +#define RENDERER_GEOMETRY_INSTANCE_H + +#include "core/math/rect2.h" +#include "core/math/transform_3d.h" +#include "core/math/vector3.h" +#include "core/templates/rid.h" +#include "storage/utilities.h" + +// API definition for our RenderGeometryInstance class so we can expose this through GDExternal in the near future +class RenderGeometryInstance { +public: + virtual ~RenderGeometryInstance() {} + + virtual void _mark_dirty() = 0; + + virtual void set_skeleton(RID p_skeleton) = 0; + virtual void set_material_override(RID p_override) = 0; + virtual void set_material_overlay(RID p_overlay) = 0; + virtual void set_surface_materials(const Vector<RID> &p_materials) = 0; + virtual void set_mesh_instance(RID p_mesh_instance) = 0; + virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) = 0; + virtual void set_lod_bias(float p_lod_bias) = 0; + virtual void set_layer_mask(uint32_t p_layer_mask) = 0; + virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) = 0; + virtual void set_parent_fade_alpha(float p_alpha) = 0; + virtual void set_transparency(float p_transparency) = 0; + virtual void set_use_baked_light(bool p_enable) = 0; + virtual void set_use_dynamic_gi(bool p_enable) = 0; + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) = 0; + virtual void set_lightmap_capture(const Color *p_sh9) = 0; + virtual void set_instance_shader_uniforms_offset(int32_t p_offset) = 0; + virtual void set_cast_double_sided_shadows(bool p_enable) = 0; + + virtual Transform3D get_transform() = 0; + virtual AABB get_aabb() = 0; + + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) = 0; + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) = 0; + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0; + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) = 0; + + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) = 0; +}; + +// Base implementation of RenderGeometryInstance shared by internal renderers. +class RenderGeometryInstanceBase : public RenderGeometryInstance { +public: + // setup + uint32_t base_flags = 0; + uint32_t flags_cache = 0; + + // used during rendering + float depth = 0; + + RID mesh_instance; + + Transform3D transform; + bool mirror = false; // move into data? + AABB transformed_aabb; //needed for LOD + bool non_uniform_scale = false; + float lod_model_scale = 1.0; + float lod_bias = 0.0; + + uint32_t layer_mask = 1; + + bool fade_near = false; + float fade_near_begin = 0; + float fade_near_end = 0; + bool fade_far = false; + float fade_far_begin = 0; + float fade_far_end = 0; + + float parent_fade_alpha = 1.0; + float force_alpha = 1.0; + + int32_t shader_uniforms_offset = -1; + + struct Data { + //data used less often goes into regular heap + RID base; + RS::InstanceType base_type; + + RID skeleton; + Vector<RID> surface_materials; + RID material_override; + RID material_overlay; + AABB aabb; + + bool use_baked_light = false; + bool use_dynamic_gi = false; + bool cast_double_sided_shadows = false; + bool dirty_dependencies = false; + + DependencyTracker dependency_tracker; + }; + + Data *data = nullptr; + + virtual void set_skeleton(RID p_skeleton) override; + virtual void set_material_override(RID p_override) override; + virtual void set_material_overlay(RID p_overlay) override; + virtual void set_surface_materials(const Vector<RID> &p_materials) override; + virtual void set_mesh_instance(RID p_mesh_instance) override; + virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override; + virtual void set_lod_bias(float p_lod_bias) override; + virtual void set_layer_mask(uint32_t p_layer_mask) override; + virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override; + virtual void set_parent_fade_alpha(float p_alpha) override; + virtual void set_transparency(float p_transparency) override; + virtual void set_use_baked_light(bool p_enable) override; + virtual void set_use_dynamic_gi(bool p_enable) override; + virtual void set_instance_shader_uniforms_offset(int32_t p_offset) override; + virtual void set_cast_double_sided_shadows(bool p_enable) override; + + virtual Transform3D get_transform() override; + virtual AABB get_aabb() override; +}; + +#endif // RENDERER_GEOMETRY_INSTANCE_H diff --git a/servers/rendering/renderer_rd/effects/vrs.cpp b/servers/rendering/renderer_rd/effects/vrs.cpp index fa0b99fef9..68cfd43d90 100644 --- a/servers/rendering/renderer_rd/effects/vrs.cpp +++ b/servers/rendering/renderer_rd/effects/vrs.cpp @@ -146,10 +146,11 @@ void VRS::update_vrs_texture(RID p_vrs_fb, RID p_render_target) { if (vrs_mode == RS::VIEWPORT_VRS_TEXTURE) { RID vrs_texture = texture_storage->render_target_get_vrs_texture(p_render_target); if (vrs_texture.is_valid()) { - Texture *texture = texture_storage->get_texture(vrs_texture); - if (texture) { + RID rd_texture = texture_storage->texture_get_rd_texture(vrs_texture); + int layers = texture_storage->texture_get_layers(vrs_texture); + if (rd_texture.is_valid()) { // Copy into our density buffer - copy_vrs(texture->rd_texture, p_vrs_fb, texture->layers > 1); + copy_vrs(rd_texture, p_vrs_fb, layers > 1); } } } else if (vrs_mode == RS::VIEWPORT_VRS_XR) { @@ -157,10 +158,12 @@ void VRS::update_vrs_texture(RID p_vrs_fb, RID p_render_target) { if (interface.is_valid()) { RID vrs_texture = interface->get_vrs_texture(); if (vrs_texture.is_valid()) { - Texture *texture = texture_storage->get_texture(vrs_texture); - if (texture) { + RID rd_texture = texture_storage->texture_get_rd_texture(vrs_texture); + int layers = texture_storage->texture_get_layers(vrs_texture); + + if (rd_texture.is_valid()) { // Copy into our density buffer - copy_vrs(texture->rd_texture, p_vrs_fb, texture->layers > 1); + copy_vrs(rd_texture, p_vrs_fb, layers > 1); } } } diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp index 987c1dbb52..58f4c855a4 100644 --- a/servers/rendering/renderer_rd/environment/fog.cpp +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -145,23 +145,23 @@ Fog::FogMaterialData::~FogMaterialData() { free_parameters_uniform_set(uniform_set); } -RendererRD::ShaderData *Fog::_create_fog_shader_func() { +RendererRD::MaterialStorage::ShaderData *Fog::_create_fog_shader_func() { FogShaderData *shader_data = memnew(FogShaderData); return shader_data; } -RendererRD::ShaderData *Fog::_create_fog_shader_funcs() { +RendererRD::MaterialStorage::ShaderData *Fog::_create_fog_shader_funcs() { return Fog::get_singleton()->_create_fog_shader_func(); }; -RendererRD::MaterialData *Fog::_create_fog_material_func(FogShaderData *p_shader) { +RendererRD::MaterialStorage::MaterialData *Fog::_create_fog_material_func(FogShaderData *p_shader) { FogMaterialData *material_data = memnew(FogMaterialData); material_data->shader_data = p_shader; //update will happen later anyway so do nothing. return material_data; } -RendererRD::MaterialData *Fog::_create_fog_material_funcs(RendererRD::ShaderData *p_shader) { +RendererRD::MaterialStorage::MaterialData *Fog::_create_fog_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader) { return Fog::get_singleton()->_create_fog_material_func(static_cast<FogShaderData *>(p_shader)); }; @@ -190,8 +190,8 @@ void Fog::init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_lay volumetric_fog_modes.push_back(""); volumetric_fog.shader.initialize(volumetric_fog_modes); - material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_shader_funcs); - material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_material_funcs); + material_storage->shader_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_FOG, _create_fog_shader_funcs); + material_storage->material_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_FOG, _create_fog_material_funcs); volumetric_fog.volume_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::VolumeUBO)); } @@ -246,7 +246,7 @@ ALBEDO = vec3(1.0); material_storage->material_initialize(volumetric_fog.default_material); material_storage->material_set_shader(volumetric_fog.default_material, volumetric_fog.default_shader); - FogMaterialData *md = static_cast<FogMaterialData *>(material_storage->material_get_data(volumetric_fog.default_material, RendererRD::SHADER_TYPE_FOG)); + FogMaterialData *md = static_cast<FogMaterialData *>(material_storage->material_get_data(volumetric_fog.default_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG)); volumetric_fog.default_shader_rd = volumetric_fog.shader.version_get_shader(md->shader_data->version, 0); Vector<RD::Uniform> uniforms; @@ -276,7 +276,7 @@ ALBEDO = vec3(1.0); RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -378,7 +378,7 @@ void Fog::FogShaderData::set_default_texture_param(const StringName &p_name, RID } } -void Fog::FogShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void Fog::FogShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { RBMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { @@ -602,7 +602,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); float z_near = p_cam_projection.get_z_near(); float z_far = p_cam_projection.get_z_far(); - float fog_end = p_settings.env->volumetric_fog_length; + float fog_end = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env); Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near)); Vector2 fog_near_size; @@ -627,10 +627,10 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P params.fog_volume_size[1] = p_settings.vfog->height; params.fog_volume_size[2] = p_settings.vfog->depth; - params.use_temporal_reprojection = p_settings.env->volumetric_fog_temporal_reprojection; + params.use_temporal_reprojection = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env); params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; - params.detail_spread = p_settings.env->volumetric_fog_detail_spread; - params.temporal_blend = p_settings.env->volumetric_fog_temporal_reprojection_amount; + params.detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); + params.temporal_blend = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection_amount(p_settings.env); Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); @@ -701,7 +701,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P FogMaterialData *material = nullptr; if (fog_material.is_valid()) { - material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG)); + material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG)); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -709,7 +709,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P if (!material) { fog_material = volumetric_fog.default_material; - material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG)); + material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG)); } ERR_FAIL_COND(!material); @@ -732,14 +732,15 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P // Local fog volume. Vector3i points[8]; Vector3 fog_size = Vector3(p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); - points[0] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); - points[1] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); - points[2] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); - points[3] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); - points[4] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); - points[5] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); - points[6] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); - points[7] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); + float volumetric_fog_detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); + points[0] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[1] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[2] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[3] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[4] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[5] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[6] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[7] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); min = Vector3i(int32_t(p_settings.vfog->width) - 1, int32_t(p_settings.vfog->height) - 1, int32_t(p_settings.vfog->depth) - 1); max = Vector3i(1, 1, 1); @@ -785,7 +786,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z); } - if (any_uses_time || p_settings.env->volumetric_fog_temporal_reprojection) { + if (any_uses_time || RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) { RenderingServerDefault::redraw_request(); } @@ -804,7 +805,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; if (p_settings.shadow_atlas_depth.is_null()) { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK)); } else { u.append_id(p_settings.shadow_atlas_depth); } @@ -820,7 +821,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P if (p_settings.directional_shadow_depth.is_valid()) { u.append_id(p_settings.directional_shadow_depth); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK)); } uniforms.push_back(u); copy_uniforms.push_back(u); @@ -985,8 +986,8 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 19; - RID radiance_texture = texture_storage->texture_rd_get_default(p_settings.is_using_radiance_cubemap_array ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); - RID sky_texture = p_settings.env->sky.is_valid() ? p_settings.sky->sky_get_radiance_texture_rd(p_settings.env->sky) : RID(); + RID radiance_texture = texture_storage->texture_rd_get_default(p_settings.is_using_radiance_cubemap_array ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + RID sky_texture = RendererSceneRenderRD::get_singleton()->environment_get_sky(p_settings.env).is_valid() ? p_settings.sky->sky_get_radiance_texture_rd(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_settings.env)) : RID(); u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture); uniforms.push_back(u); } @@ -1008,7 +1009,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P p_settings.vfog->process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0); } - bool using_sdfgi = p_settings.env->volumetric_fog_gi_inject > 0.0001 && p_settings.env->sdfgi_enabled && (p_settings.sdfgi != nullptr); + bool using_sdfgi = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.0001 && RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_enabled(p_settings.env) && (p_settings.sdfgi != nullptr); if (using_sdfgi) { if (p_settings.vfog->sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_settings.vfog->sdfgi_uniform_set)) { @@ -1042,8 +1043,8 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P } } - p_settings.vfog->length = p_settings.env->volumetric_fog_length; - p_settings.vfog->spread = p_settings.env->volumetric_fog_detail_spread; + p_settings.vfog->length = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env); + p_settings.vfog->spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); VolumetricFogShader::ParamsUBO params; @@ -1051,7 +1052,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); float z_near = p_cam_projection.get_z_near(); float z_far = p_cam_projection.get_z_far(); - float fog_end = p_settings.env->volumetric_fog_length; + float fog_end = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env); Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near)); Vector2 fog_near_size; @@ -1067,16 +1068,16 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P params.fog_frustum_size_end[0] = fog_far_size.x; params.fog_frustum_size_end[1] = fog_far_size.y; - params.ambient_inject = p_settings.env->volumetric_fog_ambient_inject * p_settings.env->ambient_light_energy; + params.ambient_inject = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_ambient_inject(p_settings.env) * RendererSceneRenderRD::get_singleton()->environment_get_ambient_light_energy(p_settings.env); params.z_far = z_far; params.fog_frustum_end = fog_end; - Color ambient_color = p_settings.env->ambient_light.srgb_to_linear(); + Color ambient_color = RendererSceneRenderRD::get_singleton()->environment_get_ambient_light(p_settings.env).srgb_to_linear(); params.ambient_color[0] = ambient_color.r; params.ambient_color[1] = ambient_color.g; params.ambient_color[2] = ambient_color.b; - params.sky_contribution = p_settings.env->ambient_sky_contribution; + params.sky_contribution = RendererSceneRenderRD::get_singleton()->environment_get_ambient_sky_contribution(p_settings.env); params.fog_volume_size[0] = p_settings.vfog->width; params.fog_volume_size[1] = p_settings.vfog->height; @@ -1084,20 +1085,20 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P params.directional_light_count = p_directional_light_count; - Color emission = p_settings.env->volumetric_fog_emission.srgb_to_linear(); - params.base_emission[0] = emission.r * p_settings.env->volumetric_fog_emission_energy; - params.base_emission[1] = emission.g * p_settings.env->volumetric_fog_emission_energy; - params.base_emission[2] = emission.b * p_settings.env->volumetric_fog_emission_energy; - params.base_density = p_settings.env->volumetric_fog_density; + Color emission = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission(p_settings.env).srgb_to_linear(); + params.base_emission[0] = emission.r * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env); + params.base_emission[1] = emission.g * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env); + params.base_emission[2] = emission.b * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env); + params.base_density = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_density(p_settings.env); - Color base_scattering = p_settings.env->volumetric_fog_scattering.srgb_to_linear(); + Color base_scattering = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_scattering(p_settings.env).srgb_to_linear(); params.base_scattering[0] = base_scattering.r; params.base_scattering[1] = base_scattering.g; params.base_scattering[2] = base_scattering.b; - params.phase_g = p_settings.env->volumetric_fog_anisotropy; + params.phase_g = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_anisotropy(p_settings.env); - params.detail_spread = p_settings.env->volumetric_fog_detail_spread; - params.gi_inject = p_settings.env->volumetric_fog_gi_inject; + params.detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); + params.gi_inject = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env); params.cam_rotation[0] = p_cam_transform.basis[0][0]; params.cam_rotation[1] = p_cam_transform.basis[1][0]; @@ -1112,14 +1113,14 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P params.cam_rotation[10] = p_cam_transform.basis[2][2]; params.cam_rotation[11] = 0; params.filter_axis = 0; - params.max_voxel_gi_instances = p_settings.env->volumetric_fog_gi_inject > 0.001 ? p_voxel_gi_count : 0; + params.max_voxel_gi_instances = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.001 ? p_voxel_gi_count : 0; params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); - params.use_temporal_reprojection = p_settings.env->volumetric_fog_temporal_reprojection; - params.temporal_blend = p_settings.env->volumetric_fog_temporal_reprojection_amount; + params.use_temporal_reprojection = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env); + params.temporal_blend = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection_amount(p_settings.env); { uint32_t cluster_size = p_settings.cluster_builder->get_cluster_size(); @@ -1135,7 +1136,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P params.screen_size[1] = p_settings.rb_size.y; } - Basis sky_transform = p_settings.env->sky_orientation; + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_settings.env); sky_transform = sky_transform.inverse() * p_cam_transform.basis; RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform); @@ -1157,7 +1158,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P RD::get_singleton()->compute_list_add_barrier(compute_list); // Copy fog to history buffer - if (p_settings.env->volumetric_fog_temporal_reprojection) { + if (RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) { RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->copy_uniform_set, 0); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); diff --git a/servers/rendering/renderer_rd/environment/fog.h b/servers/rendering/renderer_rd/environment/fog.h index 61a5d80d20..171f9f3b88 100644 --- a/servers/rendering/renderer_rd/environment/fog.h +++ b/servers/rendering/renderer_rd/environment/fog.h @@ -36,7 +36,6 @@ #include "servers/rendering/environment/renderer_fog.h" #include "servers/rendering/renderer_rd/cluster_builder_rd.h" #include "servers/rendering/renderer_rd/environment/gi.h" -#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" #include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl.gen.h" #include "servers/rendering/storage/utilities.h" @@ -181,7 +180,7 @@ private: Vector3i _point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform); - struct FogShaderData : public RendererRD::ShaderData { + struct FogShaderData : public RendererRD::MaterialStorage::ShaderData { bool valid = false; RID version; @@ -201,7 +200,7 @@ private: virtual void set_path_hint(const String &p_hint); virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; @@ -213,7 +212,7 @@ private: virtual ~FogShaderData(); }; - struct FogMaterialData : public RendererRD::MaterialData { + struct FogMaterialData : public RendererRD::MaterialStorage::MaterialData { FogShaderData *shader_data = nullptr; RID uniform_set; bool uniform_set_updated; @@ -224,11 +223,11 @@ private: virtual ~FogMaterialData(); }; - RendererRD::ShaderData *_create_fog_shader_func(); - static RendererRD::ShaderData *_create_fog_shader_funcs(); + RendererRD::MaterialStorage::ShaderData *_create_fog_shader_func(); + static RendererRD::MaterialStorage::ShaderData *_create_fog_shader_funcs(); - RendererRD::MaterialData *_create_fog_material_func(FogShaderData *p_shader); - static RendererRD::MaterialData *_create_fog_material_funcs(RendererRD::ShaderData *p_shader); + RendererRD::MaterialStorage::MaterialData *_create_fog_material_func(FogShaderData *p_shader); + static RendererRD::MaterialStorage::MaterialData *_create_fog_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader); public: static Fog *get_singleton() { return singleton; } @@ -318,7 +317,7 @@ public: GI *gi; GI::SDFGI *sdfgi; GI::RenderBuffersGI *rbgi; - RendererSceneEnvironmentRD *env; + RID env; SkyRD *sky; }; void volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index cb3de07c31..feafcc42c9 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -374,15 +374,15 @@ RID GI::voxel_gi_get_sdf_texture(RID p_voxel_gi) { //////////////////////////////////////////////////////////////////////////////// // SDFGI -void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi) { +void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); gi = p_gi; - num_cascades = p_env->sdfgi_cascades; - min_cell_size = p_env->sdfgi_min_cell_size; - uses_occlusion = p_env->sdfgi_use_occlusion; - y_scale_mode = p_env->sdfgi_y_scale; + num_cascades = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_cascades(p_env); + min_cell_size = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_min_cell_size(p_env); + uses_occlusion = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_use_occlusion(p_env); + y_scale_mode = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_y_scale(p_env); static const float y_scale[3] = { 2.0, 1.5, 1.0 }; y_mult = y_scale[y_scale_mode]; cascades.resize(num_cascades); @@ -734,7 +734,7 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world if (j < cascades.size()) { u.append_id(cascades[j].sdf_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -978,7 +978,7 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world if (j < cascades.size()) { u.append_id(cascades[j].sdf_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -991,7 +991,7 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world if (j < cascades.size()) { u.append_id(cascades[j].light_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1004,7 +1004,7 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world if (j < cascades.size()) { u.append_id(cascades[j].light_aniso_0_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1017,7 +1017,7 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world if (j < cascades.size()) { u.append_id(cascades[j].light_aniso_1_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1101,11 +1101,11 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world cascades[i].integrate_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 0); } - bounce_feedback = p_env->sdfgi_bounce_feedback; - energy = p_env->sdfgi_energy; - normal_bias = p_env->sdfgi_normal_bias; - probe_bias = p_env->sdfgi_probe_bias; - reads_sky = p_env->sdfgi_read_sky_light; + bounce_feedback = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_bounce_feedback(p_env); + energy = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_energy(p_env); + normal_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_normal_bias(p_env); + probe_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_probe_bias(p_env); + reads_sky = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_read_sky_light(p_env); } void GI::SDFGI::erase() { @@ -1163,12 +1163,12 @@ void GI::SDFGI::erase() { } } -void GI::SDFGI::update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position) { - bounce_feedback = p_env->sdfgi_bounce_feedback; - energy = p_env->sdfgi_energy; - normal_bias = p_env->sdfgi_normal_bias; - probe_bias = p_env->sdfgi_probe_bias; - reads_sky = p_env->sdfgi_read_sky_light; +void GI::SDFGI::update(RID p_env, const Vector3 &p_world_position) { + bounce_feedback = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_bounce_feedback(p_env); + energy = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_energy(p_env); + normal_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_normal_bias(p_env); + probe_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_probe_bias(p_env); + reads_sky = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_read_sky_light(p_env); int32_t drag_margin = (cascade_size / SDFGI::PROBE_DIVISOR) / 2; @@ -1268,7 +1268,7 @@ void GI::SDFGI::update_light() { RD::get_singleton()->draw_command_end_label(); } -void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, SkyRD::Sky *p_sky) { +void GI::SDFGI::update_probes(RID p_env, SkyRD::Sky *p_sky) { RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes"); SDFGIShader::IntegratePushConstant push_constant; @@ -1284,29 +1284,29 @@ void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, SkyRD::Sky *p_s push_constant.ray_bias = probe_bias; push_constant.image_size[0] = probe_axis_count * probe_axis_count; push_constant.image_size[1] = probe_axis_count; - push_constant.store_ambient_texture = p_env->volumetric_fog_enabled; + push_constant.store_ambient_texture = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_enabled(p_env); RID sky_uniform_set = gi->sdfgi_shader.integrate_default_sky_uniform_set; push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_DISABLED; push_constant.y_mult = y_mult; - if (reads_sky && p_env) { - push_constant.sky_energy = p_env->bg_energy; + if (reads_sky && p_env.is_valid()) { + push_constant.sky_energy = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); - if (p_env->background == RS::ENV_BG_CLEAR_COLOR) { + if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_CLEAR_COLOR) { push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; Color c = RSG::texture_storage->get_default_clear_color().srgb_to_linear(); push_constant.sky_color[0] = c.r; push_constant.sky_color[1] = c.g; push_constant.sky_color[2] = c.b; - } else if (p_env->background == RS::ENV_BG_COLOR) { + } else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_COLOR) { push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; - Color c = p_env->bg_color; + Color c = RendererSceneRenderRD::get_singleton()->environment_get_bg_color(p_env); push_constant.sky_color[0] = c.r; push_constant.sky_color[1] = c.g; push_constant.sky_color[2] = c.b; - } else if (p_env->background == RS::ENV_BG_SKY) { + } else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_SKY) { if (p_sky && p_sky->radiance.is_valid()) { if (integrate_sky_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(integrate_sky_uniform_set)) { Vector<RD::Uniform> uniforms; @@ -1498,7 +1498,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projection if (i < cascades.size()) { u.append_id(cascades[i].sdf_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1511,7 +1511,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projection if (i < cascades.size()) { u.append_id(cascades[i].light_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1524,7 +1524,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projection if (i < cascades.size()) { u.append_id(cascades[i].light_aniso_0_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1537,7 +1537,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projection if (i < cascades.size()) { u.append_id(cascades[i].light_aniso_1_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1591,34 +1591,24 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projection push_constant.max_cascades = cascades.size(); push_constant.screen_size[0] = p_width; push_constant.screen_size[1] = p_height; - push_constant.probe_axis_size = probe_axis_count; - push_constant.use_occlusion = uses_occlusion; push_constant.y_mult = y_mult; push_constant.z_near = -p_projections[v].get_z_near(); - push_constant.cam_transform[0] = p_transform.basis.rows[0][0]; - push_constant.cam_transform[1] = p_transform.basis.rows[1][0]; - push_constant.cam_transform[2] = p_transform.basis.rows[2][0]; - push_constant.cam_transform[3] = 0; - push_constant.cam_transform[4] = p_transform.basis.rows[0][1]; - push_constant.cam_transform[5] = p_transform.basis.rows[1][1]; - push_constant.cam_transform[6] = p_transform.basis.rows[2][1]; - push_constant.cam_transform[7] = 0; - push_constant.cam_transform[8] = p_transform.basis.rows[0][2]; - push_constant.cam_transform[9] = p_transform.basis.rows[1][2]; - push_constant.cam_transform[10] = p_transform.basis.rows[2][2]; - push_constant.cam_transform[11] = 0; - push_constant.cam_transform[12] = p_transform.origin.x; - push_constant.cam_transform[13] = p_transform.origin.y; - push_constant.cam_transform[14] = p_transform.origin.z; - push_constant.cam_transform[15] = 1; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + push_constant.cam_basis[i][j] = p_transform.basis.rows[j][i]; + } + } + push_constant.cam_origin[0] = p_transform.origin[0]; + push_constant.cam_origin[1] = p_transform.origin[1]; + push_constant.cam_origin[2] = p_transform.origin[2]; // need to properly unproject for asymmetric projection matrices in stereo.. Projection inv_projection = p_projections[v].inverse(); for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - push_constant.inv_projection[i * 4 + j] = inv_projection.matrix[i][j]; + for (int j = 0; j < 3; j++) { + push_constant.inv_projection[j][i] = inv_projection.matrix[i][j]; } } @@ -1947,7 +1937,7 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r } } -void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) { +void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) { //print_line("rendering region " + itos(p_region)); RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... @@ -2428,7 +2418,7 @@ void GI::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_co //////////////////////////////////////////////////////////////////////////////// // VoxelGIInstance -void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { +void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); uint32_t data_version = gi->voxel_gi_get_data_version(probe); @@ -2951,10 +2941,10 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID //this could probably be better parallelized in compute.. for (int i = 0; i < (int)p_dynamic_objects.size(); i++) { - RendererSceneRender::GeometryInstance *instance = p_dynamic_objects[i]; + RenderGeometryInstance *instance = p_dynamic_objects[i]; //transform aabb to voxel_gi - AABB aabb = (to_probe_xform * p_scene_render->geometry_instance_get_transform(instance)).xform(p_scene_render->geometry_instance_get_aabb(instance)); + AABB aabb = (to_probe_xform * instance->get_transform()).xform(instance->get_aabb()); //this needs to wrap to grid resolution to avoid jitter //also extend margin a bit just in case @@ -3353,9 +3343,9 @@ void GI::init(SkyRD *p_sky) { u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; if (p_sky->sky_use_cubemap_array) { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_WHITE)); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE)); } uniforms.push_back(u); } @@ -3477,7 +3467,7 @@ void GI::free() { } } -GI::SDFGI *GI::create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) { +GI::SDFGI *GI::create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) { SDFGI *sdfgi = memnew(SDFGI); sdfgi->create(p_env, p_world_position, p_requested_history_size, this); @@ -3550,7 +3540,7 @@ void GI::setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_tra } if (texture == RID()) { - texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); + texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); } if (texture != rb->rbgi.voxel_gi_textures[i]) { @@ -3761,7 +3751,7 @@ void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { u.append_id(rb->sdfgi->cascades[j].sdf_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3774,7 +3764,7 @@ void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { u.append_id(rb->sdfgi->cascades[j].light_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3787,7 +3777,7 @@ void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { u.append_id(rb->sdfgi->cascades[j].light_aniso_0_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3800,7 +3790,7 @@ void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { u.append_id(rb->sdfgi->cascades[j].light_aniso_1_tex); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3812,7 +3802,7 @@ void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, if (rb->sdfgi) { u.append_id(rb->sdfgi->occlusion_texture); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } uniforms.push_back(u); } @@ -3854,7 +3844,7 @@ void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, if (rb->sdfgi) { u.append_id(rb->sdfgi->lightprobe_texture); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); } uniforms.push_back(u); } @@ -3876,7 +3866,7 @@ void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 14; - RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); u.append_id(buffer); uniforms.push_back(u); } @@ -3914,7 +3904,7 @@ void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 19; - RID buffer = p_vrs_slices[v].is_valid() ? p_vrs_slices[v] : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_VRS); + RID buffer = p_vrs_slices[v].is_valid() ? p_vrs_slices[v] : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_VRS); u.append_id(buffer); uniforms.push_back(u); } @@ -3960,7 +3950,7 @@ bool GI::voxel_gi_needs_update(RID p_probe) const { return voxel_gi->last_probe_version != voxel_gi_get_version(voxel_gi->probe); } -void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { +void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); ERR_FAIL_COND(!voxel_gi); diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h index f4e32a8dd0..304df1605b 100644 --- a/servers/rendering/renderer_rd/environment/gi.h +++ b/servers/rendering/renderer_rd/environment/gi.h @@ -36,7 +36,6 @@ #include "servers/rendering/environment/renderer_gi.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/environment/sky.h" -#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" #include "servers/rendering/renderer_rd/shaders/environment/gi.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl.gen.h" @@ -79,9 +78,9 @@ public: float energy = 1.0; float bias = 1.4; float normal_bias = 0.0; - float propagation = 0.7; + float propagation = 0.5; bool interior = false; - bool use_two_bounces = false; + bool use_two_bounces = true; uint32_t version = 1; uint32_t data_version = 1; @@ -233,16 +232,13 @@ private: uint32_t max_cascades; int32_t screen_size[2]; - uint32_t use_occlusion; float y_mult; - uint32_t probe_axis_size; float z_near; - float reserved1; - float reserved2; - float cam_transform[16]; - float inv_projection[16]; + float inv_projection[3][4]; + float cam_basis[3][3]; + float cam_origin[3]; }; SdfgiDebugShaderRD debug; @@ -471,7 +467,7 @@ public: Transform3D transform; - void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); + void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; @@ -614,11 +610,11 @@ public: int32_t cascade_dynamic_light_count[SDFGI::MAX_CASCADES]; //used dynamically RID integrate_sky_uniform_set; - void create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi); + void create(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi); void erase(); - void update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position); + void update(RID p_env, const Vector3 &p_world_position); void update_light(); - void update_probes(RendererSceneEnvironmentRD *p_env, RendererRD::SkyRD::Sky *p_sky); + void update_probes(RID p_env, RendererRD::SkyRD::Sky *p_sky); void store_probes(); int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const; void update_cascades(); @@ -627,7 +623,7 @@ public: void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render); - void render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); + void render_region(RID p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); void render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render); }; @@ -772,7 +768,7 @@ public: void init(RendererRD::SkyRD *p_sky); void free(); - SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); + SDFGI *create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); void setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render); void process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render); @@ -780,7 +776,7 @@ public: RID voxel_gi_instance_create(RID p_base); void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform); bool voxel_gi_needs_update(RID p_probe) const; - void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 6f32c15d95..6433a39863 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -164,7 +164,7 @@ void SkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, R } } -void SkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void SkyRD::SkyShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { @@ -419,21 +419,22 @@ void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bo radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, 0, 1, RD::TEXTURE_SLICE_CUBEMAP); RD::get_singleton()->set_resource_name(radiance_base_cubemap, "radiance base cubemap"); + RD::TextureFormat tf; tf.format = p_texture_format; - tf.width = 64; // Always 64x64 - tf.height = 64; + tf.width = p_low_quality ? 64 : p_size >> 1; // Always 64x64 when using REALTIME. + tf.height = p_low_quality ? 64 : p_size >> 1; tf.texture_type = RD::TEXTURE_TYPE_CUBE; tf.array_layers = 6; - tf.mipmaps = 7; + tf.mipmaps = p_low_quality ? 7 : mipmaps - 1; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; downsampled_radiance_cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView()); RD::get_singleton()->set_resource_name(downsampled_radiance_cubemap, "downsampled radiance cubemap"); { - uint32_t mmw = 64; - uint32_t mmh = 64; - downsampled_layer.mipmaps.resize(7); + uint32_t mmw = tf.width; + uint32_t mmh = tf.height; + downsampled_layer.mipmaps.resize(tf.mipmaps); for (int j = 0; j < downsampled_layer.mipmaps.size(); j++) { ReflectionData::DownsampleLayer::Mipmap &mm = downsampled_layer.mipmaps.write[j]; mm.size.width = mmw; @@ -654,7 +655,7 @@ RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shade if (radiance.is_valid() && p_version <= SKY_TEXTURE_SET_QUARTER_RES) { u.append_id(radiance); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } uniforms.push_back(u); } @@ -670,9 +671,9 @@ RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shade } } else { if (p_version < SKY_TEXTURE_SET_CUBEMAP) { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } } uniforms.push_back(u); @@ -689,9 +690,9 @@ RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shade } } else { if (p_version < SKY_TEXTURE_SET_CUBEMAP) { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } } uniforms.push_back(u); @@ -788,24 +789,24 @@ Ref<Image> SkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, con //////////////////////////////////////////////////////////////////////////////// // SkyRD -RendererRD::ShaderData *SkyRD::_create_sky_shader_func() { +RendererRD::MaterialStorage::ShaderData *SkyRD::_create_sky_shader_func() { SkyShaderData *shader_data = memnew(SkyShaderData); return shader_data; } -RendererRD::ShaderData *SkyRD::_create_sky_shader_funcs() { +RendererRD::MaterialStorage::ShaderData *SkyRD::_create_sky_shader_funcs() { // !BAS! Why isn't _create_sky_shader_func not just static too? return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_shader_func(); }; -RendererRD::MaterialData *SkyRD::_create_sky_material_func(SkyShaderData *p_shader) { +RendererRD::MaterialStorage::MaterialData *SkyRD::_create_sky_material_func(SkyShaderData *p_shader) { SkyMaterialData *material_data = memnew(SkyMaterialData); material_data->shader_data = p_shader; //update will happen later anyway so do nothing. return material_data; } -RendererRD::MaterialData *SkyRD::_create_sky_material_funcs(RendererRD::ShaderData *p_shader) { +RendererRD::MaterialStorage::MaterialData *SkyRD::_create_sky_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader) { // !BAS! same here, we could just make _create_sky_material_func static? return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_material_func(static_cast<SkyShaderData *>(p_shader)); }; @@ -854,8 +855,8 @@ void SkyRD::init() { } // register our shader funds - material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_SKY, _create_sky_shader_funcs); - material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_SKY, _create_sky_material_funcs); + material_storage->shader_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_SKY, _create_sky_shader_funcs); + material_storage->material_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_SKY, _create_sky_material_funcs); { ShaderCompiler::DefaultIdentifierActions actions; @@ -911,7 +912,7 @@ void SkyRD::init() { actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; sky_shader.compiler.initialize(actions); } @@ -936,7 +937,7 @@ void sky() { material_storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader); - SkyMaterialData *md = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_shader.default_material, RendererRD::SHADER_TYPE_SKY)); + SkyMaterialData *md = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); sky_shader.default_shader_rd = sky_shader.shader.version_get_shader(md->shader_data->version, SKY_VERSION_BACKGROUND); sky_scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkySceneState::UBO)); @@ -969,7 +970,7 @@ void sky() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -998,7 +999,7 @@ void sky() { RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID vfog = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); + RID vfog = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); u.append_id(vfog); uniforms.push_back(u); } @@ -1032,21 +1033,21 @@ void sky() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); uniforms.push_back(u); } @@ -1079,7 +1080,7 @@ SkyRD::~SkyRD() { // cleanup anything created in init... RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - SkyMaterialData *md = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_shader.default_material, RendererRD::SHADER_TYPE_SKY)); + SkyMaterialData *md = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); sky_shader.shader.version_free(md->shader_data->version); RD::get_singleton()->free(sky_scene_state.directional_light_buffer); RD::get_singleton()->free(sky_scene_state.uniform_buffer); @@ -1105,23 +1106,23 @@ SkyRD::~SkyRD() { RD::get_singleton()->free(index_buffer); //array gets freed as dependency } -void SkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { +void SkyRD::setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); SkyMaterialData *material = nullptr; - Sky *sky = get_sky(p_env->sky); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); RID sky_material; SkyShaderData *shader_data = nullptr; if (sky) { - sky_material = sky_get_material(p_env->sky); + sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); if (sky_material.is_valid()) { - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -1129,7 +1130,7 @@ void SkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const if (!material) { sky_material = sky_shader.default_material; - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); } ERR_FAIL_COND(!material); @@ -1304,32 +1305,32 @@ void SkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const } sky_scene_state.ubo.z_far = p_projection.get_z_far(); - sky_scene_state.ubo.fog_enabled = p_env->fog_enabled; - sky_scene_state.ubo.fog_density = p_env->fog_density; - sky_scene_state.ubo.fog_aerial_perspective = p_env->fog_aerial_perspective; - Color fog_color = p_env->fog_light_color.srgb_to_linear(); - float fog_energy = p_env->fog_light_energy; + sky_scene_state.ubo.fog_enabled = RendererSceneRenderRD::get_singleton()->environment_get_fog_enabled(p_env); + sky_scene_state.ubo.fog_density = RendererSceneRenderRD::get_singleton()->environment_get_fog_density(p_env); + sky_scene_state.ubo.fog_aerial_perspective = RendererSceneRenderRD::get_singleton()->environment_get_fog_aerial_perspective(p_env); + Color fog_color = RendererSceneRenderRD::get_singleton()->environment_get_fog_light_color(p_env).srgb_to_linear(); + float fog_energy = RendererSceneRenderRD::get_singleton()->environment_get_fog_light_energy(p_env); sky_scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; sky_scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; sky_scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; - sky_scene_state.ubo.fog_sun_scatter = p_env->fog_sun_scatter; + sky_scene_state.ubo.fog_sun_scatter = RendererSceneRenderRD::get_singleton()->environment_get_fog_sun_scatter(p_env); RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo); } -void SkyRD::update(RendererSceneEnvironmentRD *p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); - Sky *sky = get_sky(p_env->sky); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); ERR_FAIL_COND(!sky); - RID sky_material = sky_get_material(p_env->sky); + RID sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); SkyMaterialData *material = nullptr; if (sky_material.is_valid()) { - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -1337,7 +1338,7 @@ void SkyRD::update(RendererSceneEnvironmentRD *p_env, const Projection &p_projec if (!material) { sky_material = sky_shader.default_material; - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); } ERR_FAIL_COND(!material); @@ -1346,7 +1347,7 @@ void SkyRD::update(RendererSceneEnvironmentRD *p_env, const Projection &p_projec ERR_FAIL_COND(!shader_data); - float multiplier = p_env->bg_energy; + float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY; RS::SkyMode sky_mode = sky->mode; @@ -1486,26 +1487,26 @@ void SkyRD::update(RendererSceneEnvironmentRD *p_env, const Projection &p_projec } } -void SkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) { +void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); ERR_FAIL_COND(p_view_count == 0); ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); - Sky *sky = get_sky(p_env->sky); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); SkyMaterialData *material = nullptr; RID sky_material; - RS::EnvironmentBG background = p_env->background; + RS::EnvironmentBG background = RendererSceneRenderRD::get_singleton()->environment_get_background(p_env); if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) { ERR_FAIL_COND(!sky); - sky_material = sky_get_material(p_env->sky); + sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); if (sky_material.is_valid()) { - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -1513,13 +1514,13 @@ void SkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, b if (!material) { sky_material = sky_shader.default_material; - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); } } if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) { sky_material = sky_scene_state.fog_material; - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); } ERR_FAIL_COND(!material); @@ -1528,11 +1529,11 @@ void SkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, b ERR_FAIL_COND(!shader_data); - Basis sky_transform = p_env->sky_orientation; + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float multiplier = p_env->bg_energy; - float custom_fov = p_env->sky_custom_fov; + float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); + float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera Projection camera; @@ -1593,23 +1594,23 @@ void SkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, b RD::get_singleton()->draw_list_end(); } -void SkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); ERR_FAIL_COND(p_view_count == 0); ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); - Sky *sky = get_sky(p_env->sky); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); ERR_FAIL_COND(!sky); SkyMaterialData *material = nullptr; RID sky_material; - sky_material = sky_get_material(p_env->sky); + sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); if (sky_material.is_valid()) { - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -1617,7 +1618,7 @@ void SkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_vie if (!material) { sky_material = sky_shader.default_material; - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); } ERR_FAIL_COND(!material); @@ -1626,11 +1627,11 @@ void SkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_vie ERR_FAIL_COND(!shader_data); - Basis sky_transform = p_env->sky_orientation; + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float multiplier = p_env->bg_energy; - float custom_fov = p_env->sky_custom_fov; + float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); + float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera Projection camera; @@ -1678,26 +1679,26 @@ void SkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_vie } } -void SkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); ERR_FAIL_COND(p_view_count == 0); ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); - Sky *sky = get_sky(p_env->sky); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); SkyMaterialData *material = nullptr; RID sky_material; - RS::EnvironmentBG background = p_env->background; + RS::EnvironmentBG background = RendererSceneRenderRD::get_singleton()->environment_get_background(p_env); if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) { ERR_FAIL_COND(!sky); - sky_material = sky_get_material(p_env->sky); + sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); if (sky_material.is_valid()) { - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -1705,13 +1706,13 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, if (!material) { sky_material = sky_shader.default_material; - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); } } if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) { sky_material = sky_scene_state.fog_material; - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); + material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); } ERR_FAIL_COND(!material); @@ -1720,11 +1721,11 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, ERR_FAIL_COND(!shader_data); - Basis sky_transform = p_env->sky_orientation; + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float multiplier = p_env->bg_energy; - float custom_fov = p_env->sky_custom_fov; + float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); + float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera Projection camera; diff --git a/servers/rendering/renderer_rd/environment/sky.h b/servers/rendering/renderer_rd/environment/sky.h index c3962f20b7..080165c112 100644 --- a/servers/rendering/renderer_rd/environment/sky.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -34,7 +34,6 @@ #include "core/templates/rid_owner.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" -#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" #include "servers/rendering/renderer_rd/shaders/environment/sky.glsl.gen.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_scene_render.h" @@ -108,7 +107,7 @@ private: // 128 is the max size of a push constant. We can replace "pad" but we can't add any more. }; - struct SkyShaderData : public RendererRD::ShaderData { + struct SkyShaderData : public RendererRD::MaterialStorage::ShaderData { bool valid = false; RID version; @@ -132,7 +131,7 @@ private: virtual void set_code(const String &p_Code); virtual void set_path_hint(const String &p_hint); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; @@ -232,7 +231,7 @@ public: RID default_shader_rd; } sky_shader; - struct SkyMaterialData : public RendererRD::MaterialData { + struct SkyMaterialData : public RendererRD::MaterialStorage::MaterialData { SkyShaderData *shader_data = nullptr; RID uniform_set; bool uniform_set_updated; @@ -286,22 +285,22 @@ public: mutable RID_Owner<Sky, true> sky_owner; int roughness_layers; - RendererRD::ShaderData *_create_sky_shader_func(); - static RendererRD::ShaderData *_create_sky_shader_funcs(); + RendererRD::MaterialStorage::ShaderData *_create_sky_shader_func(); + static RendererRD::MaterialStorage::ShaderData *_create_sky_shader_funcs(); - RendererRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader); - static RendererRD::MaterialData *_create_sky_material_funcs(RendererRD::ShaderData *p_shader); + RendererRD::MaterialStorage::MaterialData *_create_sky_material_func(SkyShaderData *p_shader); + static RendererRD::MaterialStorage::MaterialData *_create_sky_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader); SkyRD(); void init(); void set_texture_format(RD::DataFormat p_texture_format); ~SkyRD(); - void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); - void update(RendererSceneEnvironmentRD *p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); - void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer - void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); - void draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); + void setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); + void update(RID p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); + void draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer + void update_res_buffers(RID p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); + void draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); void invalidate_sky(Sky *p_sky); void update_dirty_skys(); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 4a55a04cd4..8754e90647 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -923,7 +923,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat scene_state.ubo.use_ambient_cubemap = false; } else { float energy = environment_get_ambient_light_energy(p_render_data->environment); - Color color = environment_get_ambient_light_color(p_render_data->environment); + Color color = environment_get_ambient_light(p_render_data->environment); color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; @@ -945,16 +945,16 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat scene_state.ubo.use_reflection_cubemap = false; } - scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_render_data->environment); - scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_render_data->environment); + scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_channel_affect(p_render_data->environment); + scene_state.ubo.ssao_light_affect = environment_get_ssao_direct_light_affect(p_render_data->environment); uint32_t ss_flags = 0; if (p_opaque_render_buffers) { - ss_flags |= environment_is_ssao_enabled(p_render_data->environment) ? 1 : 0; - ss_flags |= environment_is_ssil_enabled(p_render_data->environment) ? 2 : 0; + ss_flags |= environment_get_ssao_enabled(p_render_data->environment) ? 1 : 0; + ss_flags |= environment_get_ssil_enabled(p_render_data->environment) ? 2 : 0; } scene_state.ubo.ss_effects_flags = ss_flags; - scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_render_data->environment); + scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment); scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment); scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment); scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); @@ -1076,7 +1076,7 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i instance_data.flags = inst->flags_cache; instance_data.gi_offset = inst->gi_offset_cache; instance_data.layer_mask = inst->layer_mask; - instance_data.instance_uniforms_ofs = uint32_t(inst->shader_parameters_offset); + instance_data.instance_uniforms_ofs = uint32_t(inst->shader_uniforms_offset); instance_data.lightmap_uv_scale[0] = inst->lightmap_uv_scale.position.x; instance_data.lightmap_uv_scale[1] = inst->lightmap_uv_scale.position.y; instance_data.lightmap_uv_scale[2] = inst->lightmap_uv_scale.size.x; @@ -1410,7 +1410,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (p_render_data->render_buffers.is_valid()) { render_buffer = static_cast<RenderBufferDataForwardClustered *>(render_buffers_get_data(p_render_data->render_buffers)); } - RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment); static const int texture_multisamples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8 }; //first of all, make a new render pass @@ -1435,7 +1434,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool using_sdfgi = false; bool using_voxelgi = false; bool reverse_cull = false; - bool using_ssil = p_render_data->environment.is_valid() && environment_is_ssil_enabled(p_render_data->environment); + bool using_ssil = p_render_data->environment.is_valid() && environment_get_ssil_enabled(p_render_data->environment); if (render_buffer) { screen_size.x = render_buffer->width; @@ -1449,21 +1448,21 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co using_voxelgi = true; } - if (!p_render_data->environment.is_valid() && using_voxelgi) { + if (p_render_data->environment.is_null() && using_voxelgi) { depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI; - } else if (p_render_data->environment.is_valid() && (environment_is_ssr_enabled(p_render_data->environment) || environment_is_sdfgi_enabled(p_render_data->environment) || using_voxelgi)) { - if (environment_is_sdfgi_enabled(p_render_data->environment)) { + } else if (p_render_data->environment.is_valid() && (environment_get_ssr_enabled(p_render_data->environment) || environment_get_sdfgi_enabled(p_render_data->environment) || using_voxelgi)) { + if (environment_get_sdfgi_enabled(p_render_data->environment)) { depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also voxelgi using_sdfgi = true; } else { depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; } - if (environment_is_ssr_enabled(p_render_data->environment)) { + if (environment_get_ssr_enabled(p_render_data->environment)) { using_separate_specular = true; using_ssr = true; color_pass_flags |= COLOR_PASS_FLAG_SEPARATE_SPECULAR; } - } else if (p_render_data->environment.is_valid() && (environment_is_ssao_enabled(p_render_data->environment) || using_ssil || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) { + } else if (p_render_data->environment.is_valid() && (environment_get_ssao_enabled(p_render_data->environment) || using_ssil || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) { depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS; } @@ -1504,7 +1503,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { p_render_data->environment = RID(); //no environment on interiors - env = nullptr; } reverse_cull = true; // for some reason our views are inverted @@ -1556,7 +1554,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_is_fog_enabled(p_render_data->environment)) { + if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_get_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } @@ -1566,7 +1564,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_is_fog_enabled(p_render_data->environment)) { + if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_get_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } @@ -1596,11 +1594,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co projection = correction * p_render_data->cam_projection; } - sky.setup(env, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); + sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); - RID sky_rid = env->sky; + RID sky_rid = environment_get_sky(p_render_data->environment); if (sky_rid.is_valid()) { - sky.update(env, projection, p_render_data->cam_transform, time); + sky.update(p_render_data->environment, projection, p_render_data->cam_transform, time); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -1616,7 +1614,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES; bool depth_pre_pass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable")) && depth_framebuffer.is_valid(); - bool using_ssao = depth_pre_pass && p_render_data->render_buffers.is_valid() && p_render_data->environment.is_valid() && environment_is_ssao_enabled(p_render_data->environment); + bool using_ssao = depth_pre_pass && p_render_data->render_buffers.is_valid() && p_render_data->environment.is_valid() && environment_get_ssao_enabled(p_render_data->environment); bool continue_depth = false; if (depth_pre_pass) { //depth pre pass @@ -1755,9 +1753,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co Projection correction; correction.set_depth_correction(true); Projection projection = correction * p_render_data->cam_projection; - sky.draw(env, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->cam_transform, time); + sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->cam_transform, time); } else { - sky.draw(env, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); + sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); } RD::get_singleton()->draw_command_end_label(); } @@ -1873,7 +1871,7 @@ void RenderForwardClustered::_render_shadow_begin() { scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { +void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -1963,7 +1961,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) { RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { +void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -2002,7 +2000,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering 3D Material"); RD::get_singleton()->draw_command_begin_label("Render 3D Material"); @@ -2051,7 +2049,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardClustered::_render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering UV2"); RD::get_singleton()->draw_command_begin_label("Render UV2"); @@ -2121,7 +2119,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { +void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { RENDER_TIMESTAMP("Render SDFGI"); RD::get_singleton()->draw_command_begin_label("Render SDFGI Voxel"); @@ -2267,15 +2265,18 @@ void RenderForwardClustered::_update_render_base_uniform_set() { case RS::DECAL_FILTER_NEAREST: { sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; - case RS::DECAL_FILTER_NEAREST_MIPMAPS: { - sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - } break; case RS::DECAL_FILTER_LINEAR: { sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; + case RS::DECAL_FILTER_NEAREST_MIPMAPS: { + sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + } break; case RS::DECAL_FILTER_LINEAR_MIPMAPS: { sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; + case RS::DECAL_FILTER_NEAREST_MIPMAPS_ANISOTROPIC: { + sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + } break; case RS::DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC: { sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; @@ -2294,15 +2295,18 @@ void RenderForwardClustered::_update_render_base_uniform_set() { case RS::LIGHT_PROJECTOR_FILTER_NEAREST: { sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; - case RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS: { - sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - } break; case RS::LIGHT_PROJECTOR_FILTER_LINEAR: { sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; + case RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS: { + sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + } break; case RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS: { sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; + case RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS_ANISOTROPIC: { + sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + } break; case RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC: { sampler = material_storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; @@ -2383,7 +2387,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 14; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -2435,7 +2439,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (p_radiance_texture.is_valid()) { radiance_texture = p_radiance_texture; } else { - radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); } RD::Uniform u; u.binding = 2; @@ -2452,7 +2456,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (ref_texture.is_valid()) { u.append_id(ref_texture); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); } uniforms.push_back(u); } @@ -2466,7 +2470,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend texture = shadow_atlas_get_texture(p_render_data->shadow_atlas); } if (!texture.is_valid()) { - texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_DEPTH); + texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH); } u.append_id(texture); uniforms.push_back(u); @@ -2478,7 +2482,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) { u.append_id(directional_shadow_get_texture()); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_DEPTH)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH)); } uniforms.push_back(u); } @@ -2487,7 +2491,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { if (p_render_data && i < p_render_data->lightmaps->size()) { RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]); @@ -2505,7 +2509,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { if (p_render_data && i < (int)p_render_data->voxel_gi_instances->size()) { RID tex = gi.voxel_gi_instance_get_texture((*p_render_data->voxel_gi_instances)[i]); @@ -2535,7 +2539,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID dbt = rb ? render_buffers_get_back_depth_texture(p_render_data->render_buffers) : RID(); - RID texture = (dbt.is_valid()) ? dbt : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_DEPTH); + RID texture = (dbt.is_valid()) ? dbt : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH); u.append_id(texture); uniforms.push_back(u); } @@ -2544,7 +2548,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_data->render_buffers) : RID(); - RID texture = bbt.is_valid() ? bbt : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + RID texture = bbt.is_valid() ? bbt : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); u.append_id(texture); uniforms.push_back(u); } @@ -2554,7 +2558,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_NORMAL); + RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_NORMAL); u.append_id(texture); uniforms.push_back(u); } @@ -2564,7 +2568,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID aot = rb ? render_buffers_get_ao_texture(p_render_data->render_buffers) : RID(); - RID texture = aot.is_valid() ? aot : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + RID texture = aot.is_valid() ? aot : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); u.append_id(texture); uniforms.push_back(u); } @@ -2574,7 +2578,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID ambient_buffer = rb ? render_buffers_get_gi_ambient_texture(p_render_data->render_buffers) : RID(); - RID texture = ambient_buffer.is_valid() ? ambient_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + RID texture = ambient_buffer.is_valid() ? ambient_buffer : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); u.append_id(texture); uniforms.push_back(u); } @@ -2584,7 +2588,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 14; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID reflection_buffer = rb ? render_buffers_get_gi_reflection_texture(p_render_data->render_buffers) : RID(); - RID texture = reflection_buffer.is_valid() ? reflection_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + RID texture = reflection_buffer.is_valid() ? reflection_buffer : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); u.append_id(texture); uniforms.push_back(u); } @@ -2596,7 +2600,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (rb && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) { t = render_buffers_get_sdfgi_irradiance_probes(p_render_data->render_buffers); } else { - t = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + t = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); } u.append_id(t); uniforms.push_back(u); @@ -2608,7 +2612,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (rb && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) { u.append_id(render_buffers_get_sdfgi_occlusion_texture(p_render_data->render_buffers)); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); } uniforms.push_back(u); } @@ -2627,10 +2631,10 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (rb && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) { vfog = render_buffers_get_volumetric_fog_texture(p_render_data->render_buffers); if (vfog.is_null()) { - vfog = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); + vfog = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); } } else { - vfog = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); + vfog = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); } u.append_id(vfog); uniforms.push_back(u); @@ -2640,7 +2644,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 19; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID ssil = rb ? render_buffers_get_ssil_texture(p_render_data->render_buffers) : RID(); - RID texture = ssil.is_valid() ? ssil : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + RID texture = ssil.is_valid() ? ssil : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); u.append_id(texture); uniforms.push_back(u); } @@ -2664,12 +2668,16 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 1; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(scene_state.instance_buffer[RENDER_LIST_SECONDARY]); + RID instance_buffer = scene_state.instance_buffer[RENDER_LIST_SECONDARY]; + if (instance_buffer == RID()) { + instance_buffer = scene_shader.default_vec4_xform_buffer; // any buffer will do since its not used + } + u.append_id(instance_buffer); uniforms.push_back(u); } { // No radiance texture. - RID radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + RID radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; @@ -2679,7 +2687,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te { // No reflection atlas. - RID ref_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); + RID ref_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; @@ -2692,7 +2700,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_DEPTH); + RID texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH); u.append_id(texture); uniforms.push_back(u); } @@ -2702,7 +2710,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_DEPTH); + RID texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH); u.append_id(texture); uniforms.push_back(u); } @@ -2713,7 +2721,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { u.append_id(default_tex); } @@ -2727,7 +2735,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { u.append_id(default_tex); } @@ -2792,24 +2800,23 @@ RID RenderForwardClustered::_render_buffers_get_velocity_texture(RID p_render_bu RenderForwardClustered *RenderForwardClustered::singleton = nullptr; -void RenderForwardClustered::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - if (ginstance->dirty_list_element.in_list()) { +void RenderForwardClustered::GeometryInstanceForwardClustered::_mark_dirty() { + if (dirty_list_element.in_list()) { return; } //clear surface caches - GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches; + GeometryInstanceSurfaceDataCache *surf = surface_caches; while (surf) { GeometryInstanceSurfaceDataCache *next = surf->next; - geometry_instance_surface_alloc.free(surf); + RenderForwardClustered::get_singleton()->geometry_instance_surface_alloc.free(surf); surf = next; } - ginstance->surface_caches = nullptr; + surface_caches = nullptr; - geometry_instance_dirty_list.add(&ginstance->dirty_list_element); + RenderForwardClustered::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element); } void RenderForwardClustered::_geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { @@ -2863,7 +2870,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet void *surface_shadow = nullptr; if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip && p_material->shader_data->cull_mode == SceneShaderForwardClustered::ShaderData::CULL_BACK) { flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL; - material_shadow = static_cast<SceneShaderForwardClustered::MaterialData *>(RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::SHADER_TYPE_3D)); + material_shadow = static_cast<SceneShaderForwardClustered::MaterialData *>(RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); RID shadow_mesh = mesh_storage->mesh_get_shadow_mesh(p_mesh); @@ -2924,7 +2931,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material_chain( while (material->next_pass.is_valid()) { RID next_pass = material->next_pass; - material = static_cast<SceneShaderForwardClustered::MaterialData *>(material_storage->material_get_data(next_pass, RendererRD::SHADER_TYPE_3D)); + material = static_cast<SceneShaderForwardClustered::MaterialData *>(material_storage->material_get_data(next_pass, RendererRD::MaterialStorage::SHADER_TYPE_3D)); if (!material || !material->shader_data->valid) { break; } @@ -2944,7 +2951,7 @@ void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForw SceneShaderForwardClustered::MaterialData *material = nullptr; if (m_src.is_valid()) { - material = static_cast<SceneShaderForwardClustered::MaterialData *>(material_storage->material_get_data(m_src, RendererRD::SHADER_TYPE_3D)); + material = static_cast<SceneShaderForwardClustered::MaterialData *>(material_storage->material_get_data(m_src, RendererRD::MaterialStorage::SHADER_TYPE_3D)); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -2955,7 +2962,7 @@ void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForw material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker); } } else { - material = static_cast<SceneShaderForwardClustered::MaterialData *>(material_storage->material_get_data(scene_shader.default_material, RendererRD::SHADER_TYPE_3D)); + material = static_cast<SceneShaderForwardClustered::MaterialData *>(material_storage->material_get_data(scene_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); m_src = scene_shader.default_material; } @@ -2966,7 +2973,7 @@ void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForw if (ginstance->data->material_overlay.is_valid()) { m_src = ginstance->data->material_overlay; - material = static_cast<SceneShaderForwardClustered::MaterialData *>(material_storage->material_get_data(m_src, RendererRD::SHADER_TYPE_3D)); + material = static_cast<SceneShaderForwardClustered::MaterialData *>(material_storage->material_get_data(m_src, RendererRD::MaterialStorage::SHADER_TYPE_3D)); if (material && material->shader_data->valid) { if (ginstance->data->dirty_dependencies) { material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker); @@ -2977,7 +2984,7 @@ void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForw } } -void RenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geometry_instance) { +void RenderForwardClustered::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) { RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton(); RendererRD::ParticlesStorage *particles_storage = RendererRD::ParticlesStorage::get_singleton(); GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); @@ -3136,7 +3143,7 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::D case Dependency::DEPENDENCY_CHANGED_PARTICLES: case Dependency::DEPENDENCY_CHANGED_MULTIMESH: case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { - static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } break; case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata); @@ -3150,10 +3157,10 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::D } } void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { - static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } -RendererSceneRender::GeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) { +RenderGeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) { RS::InstanceType type = RSG::utilities->get_base_type(p_base); ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); @@ -3166,155 +3173,47 @@ RendererSceneRender::GeometryInstance *RenderForwardClustered::geometry_instance ginstance->data->dependency_tracker.changed_callback = _geometry_instance_dependency_changed; ginstance->data->dependency_tracker.deleted_callback = _geometry_instance_dependency_deleted; - _geometry_instance_mark_dirty(ginstance); + ginstance->_mark_dirty(); return ginstance; } -void RenderForwardClustered::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->skeleton = p_skeleton; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_override = p_override; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_overlay = p_overlay; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->surface_materials = p_materials; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->mesh_instance = p_mesh_instance; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) { uint64_t frame = RSG::rasterizer->get_frame_number(); - if (frame != ginstance->prev_transform_change_frame) { - ginstance->prev_transform = ginstance->transform; - ginstance->prev_transform_change_frame = frame; - ginstance->prev_transform_dirty = true; + if (frame != prev_transform_change_frame) { + prev_transform = transform; + prev_transform_change_frame = frame; + prev_transform_dirty = true; } - ginstance->transform = p_transform; - ginstance->mirror = p_transform.basis.determinant() < 0; - ginstance->data->aabb = p_aabb; - ginstance->transformed_aabb = p_transformed_aabb; - Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); - // handle non uniform scale here - - float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); - float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); - - ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; - - ginstance->lod_model_scale = max_scale; -} -void RenderForwardClustered::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lod_bias = p_lod_bias; -} -void RenderForwardClustered::geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->fade_near = p_enable_near; - ginstance->fade_near_begin = p_near_begin; - ginstance->fade_near_end = p_near_end; - ginstance->fade_far = p_enable_far; - ginstance->fade_far_begin = p_far_begin; - ginstance->fade_far_end = p_far_end; + RenderGeometryInstanceBase::set_transform(p_transform, p_aabb, p_transformed_aabbb); } -void RenderForwardClustered::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->parent_fade_alpha = p_alpha; -} +void RenderForwardClustered::GeometryInstanceForwardClustered::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { + lightmap_instance = p_lightmap_instance; + lightmap_uv_scale = p_lightmap_uv_scale; + lightmap_slice_index = p_lightmap_slice_index; -void RenderForwardClustered::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->force_alpha = CLAMP(1.0 - p_transparency, 0, 1); + _mark_dirty(); } -void RenderForwardClustered::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_baked_light = p_enable; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_dynamic_gi = p_enable; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lightmap_instance = p_lightmap_instance; - ginstance->lightmap_uv_scale = p_lightmap_uv_scale; - ginstance->lightmap_slice_index = p_lightmap_slice_index; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::set_lightmap_capture(const Color *p_sh9) { if (p_sh9) { - if (ginstance->lightmap_sh == nullptr) { - ginstance->lightmap_sh = geometry_instance_lightmap_sh.alloc(); + if (lightmap_sh == nullptr) { + lightmap_sh = RenderForwardClustered::get_singleton()->geometry_instance_lightmap_sh.alloc(); } - memcpy(ginstance->lightmap_sh->sh, p_sh9, sizeof(Color) * 9); + memcpy(lightmap_sh->sh, p_sh9, sizeof(Color) * 9); } else { - if (ginstance->lightmap_sh != nullptr) { - geometry_instance_lightmap_sh.free(ginstance->lightmap_sh); - ginstance->lightmap_sh = nullptr; + if (lightmap_sh != nullptr) { + RenderForwardClustered::get_singleton()->geometry_instance_lightmap_sh.free(lightmap_sh); + lightmap_sh = nullptr; } } - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->shader_parameters_offset = p_offset; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->data->cast_double_sided_shadows = p_enable; - _geometry_instance_mark_dirty(ginstance); + _mark_dirty(); } -void RenderForwardClustered::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->layer_mask = p_layer_mask; -} - -void RenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry_instance) { +void RenderForwardClustered::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); if (ginstance->lightmap_sh != nullptr) { @@ -3333,47 +3232,25 @@ void RenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry uint32_t RenderForwardClustered::geometry_instance_get_pair_mask() { return (1 << RS::INSTANCE_VOXEL_GI); } -void RenderForwardClustered::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) { -} -void RenderForwardClustered::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { -} -void RenderForwardClustered::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) { -} - -Transform3D RenderForwardClustered::geometry_instance_get_transform(GeometryInstance *p_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance); - ERR_FAIL_COND_V(!ginstance, Transform3D()); - return ginstance->transform; -} - -AABB RenderForwardClustered::geometry_instance_get_aabb(GeometryInstance *p_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance); - ERR_FAIL_COND_V(!ginstance, AABB()); - return ginstance->data->aabb; -} -void RenderForwardClustered::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { if (p_voxel_gi_instance_count > 0) { - ginstance->voxel_gi_instances[0] = p_voxel_gi_instances[0]; + voxel_gi_instances[0] = p_voxel_gi_instances[0]; } else { - ginstance->voxel_gi_instances[0] = RID(); + voxel_gi_instances[0] = RID(); } if (p_voxel_gi_instance_count > 1) { - ginstance->voxel_gi_instances[1] = p_voxel_gi_instances[1]; + voxel_gi_instances[1] = p_voxel_gi_instances[1]; } else { - ginstance->voxel_gi_instances[1] = RID(); + voxel_gi_instances[1] = RID(); } } -void RenderForwardClustered::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->using_projectors = p_projector; - ginstance->using_softshadows = p_softshadow; - _geometry_instance_mark_dirty(ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) { + using_projectors = p_projector; + using_softshadows = p_softshadow; + _mark_dirty(); } void RenderForwardClustered::_update_shader_quality_settings() { @@ -3404,12 +3281,18 @@ void RenderForwardClustered::_update_shader_quality_settings() { sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL; sc.constant_id = SPEC_CONSTANT_DECAL_FILTER; - sc.bool_value = decals_get_filter() == RS::DECAL_FILTER_NEAREST_MIPMAPS || decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS || decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC; + sc.bool_value = decals_get_filter() == RS::DECAL_FILTER_NEAREST_MIPMAPS || + decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS || + decals_get_filter() == RS::DECAL_FILTER_NEAREST_MIPMAPS_ANISOTROPIC || + decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC; spec_constants.push_back(sc); sc.constant_id = SPEC_CONSTANT_PROJECTOR_FILTER; - sc.bool_value = light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS || light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS || light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC; + sc.bool_value = light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS || + light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS || + light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS_ANISOTROPIC || + light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC; spec_constants.push_back(sc); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 2bdf48c72f..7e71406af8 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -427,7 +427,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { HashMap<Size2i, RID> sdfgi_framebuffer_size_cache; struct GeometryInstanceData; - struct GeometryInstanceForwardClustered; + class GeometryInstanceForwardClustered; struct GeometryInstanceLightmapSH { Color sh[9]; @@ -487,73 +487,48 @@ class RenderForwardClustered : public RendererSceneRenderRD { GeometryInstanceForwardClustered *owner = nullptr; }; - struct GeometryInstanceForwardClustered : public GeometryInstance { + class GeometryInstanceForwardClustered : public RenderGeometryInstanceBase { + public: + // lightmap + RID lightmap_instance; + Rect2 lightmap_uv_scale; + uint32_t lightmap_slice_index; + GeometryInstanceLightmapSH *lightmap_sh = nullptr; + //used during rendering - bool mirror = false; - bool non_uniform_scale = false; - float lod_bias = 0.0; - float lod_model_scale = 1.0; - AABB transformed_aabb; //needed for LOD - float depth = 0; + uint32_t gi_offset_cache = 0; - uint32_t flags_cache = 0; bool store_transform_cache = true; - int32_t shader_parameters_offset = -1; - uint32_t lightmap_slice_index; - Rect2 lightmap_uv_scale; - uint32_t layer_mask = 1; RID transforms_uniform_set; uint32_t instance_count = 0; uint32_t trail_steps = 1; - RID mesh_instance; bool can_sdfgi = false; bool using_projectors = false; bool using_softshadows = false; - bool fade_near = false; - float fade_near_begin = 0; - float fade_near_end = 0; - bool fade_far = false; - float fade_far_begin = 0; - float fade_far_end = 0; - float force_alpha = 1.0; - float parent_fade_alpha = 1.0; //used during setup - uint32_t base_flags = 0; uint64_t prev_transform_change_frame = 0xFFFFFFFF; bool prev_transform_dirty = true; - Transform3D transform; Transform3D prev_transform; RID voxel_gi_instances[MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE]; - RID lightmap_instance; - GeometryInstanceLightmapSH *lightmap_sh = nullptr; GeometryInstanceSurfaceDataCache *surface_caches = nullptr; SelfList<GeometryInstanceForwardClustered> dirty_list_element; - struct Data { - //data used less often goes into regular heap - RID base; - RS::InstanceType base_type; - - RID skeleton; - Vector<RID> surface_materials; - RID material_override; - RID material_overlay; - AABB aabb; + GeometryInstanceForwardClustered() : + dirty_list_element(this) {} - bool use_dynamic_gi = false; - bool use_baked_light = true; - bool cast_double_sided_shadows = false; - bool mirror = false; - bool dirty_dependencies = false; + virtual void _mark_dirty() override; - DependencyTracker dependency_tracker; - }; + virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override; + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; + virtual void set_lightmap_capture(const Color *p_sh9) override; - Data *data = nullptr; + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override {} + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - GeometryInstanceForwardClustered() : - dirty_list_element(this) {} + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override; }; static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker); @@ -568,8 +543,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh); void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, RID p_mat_src, RID p_mesh); void _geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh); - void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance); - void _geometry_instance_update(GeometryInstance *p_geometry_instance); + void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance); void _update_dirty_geometry_instances(); /* Render List */ @@ -640,52 +614,27 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; - virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override; public: + static RenderForwardClustered *get_singleton() { return singleton; } + _FORCE_INLINE_ virtual void update_uniform_sets() override { base_uniform_set_updated = true; _update_render_base_uniform_set(); } - virtual GeometryInstance *geometry_instance_create(RID p_base) override; - virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override; - virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override; - virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) override; - virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) override; - virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override; - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override; - virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override; - virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override; - virtual void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override; - virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override; - virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override; - virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; - virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override; - virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override; - virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override; - - virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) override; - virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) override; - - virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) override; + virtual RenderGeometryInstance *geometry_instance_create(RID p_base) override; + virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override; virtual uint32_t geometry_instance_get_pair_mask() override; - virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override; - virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; - virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override; - virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - - virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override; virtual bool free(RID p_rid) override; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index a2995a8902..556db086b2 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -392,7 +392,7 @@ void SceneShaderForwardClustered::ShaderData::set_default_texture_param(const St } } -void SceneShaderForwardClustered::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void SceneShaderForwardClustered::ShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { @@ -488,7 +488,7 @@ SceneShaderForwardClustered::ShaderData::~ShaderData() { } } -RendererRD::ShaderData *SceneShaderForwardClustered::_create_shader_func() { +RendererRD::MaterialStorage::ShaderData *SceneShaderForwardClustered::_create_shader_func() { ShaderData *shader_data = memnew(ShaderData); singleton->shader_list.add(&shader_data->shader_list_element); return shader_data; @@ -512,7 +512,7 @@ SceneShaderForwardClustered::MaterialData::~MaterialData() { free_parameters_uniform_set(uniform_set); } -RendererRD::MaterialData *SceneShaderForwardClustered::_create_material_func(ShaderData *p_shader) { +RendererRD::MaterialStorage::MaterialData *SceneShaderForwardClustered::_create_material_func(ShaderData *p_shader) { MaterialData *material_data = memnew(MaterialData); material_data->shader_data = p_shader; //update will happen later anyway so do nothing. @@ -610,8 +610,8 @@ void SceneShaderForwardClustered::init(const String p_defines) { valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS); - material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_shader_funcs); - material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_material_funcs); + material_storage->shader_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_3D, _create_shader_funcs); + material_storage->material_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_3D, _create_material_funcs); { //shader compiler @@ -682,7 +682,7 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; actions.renames["DEPTH"] = "gl_FragDepth"; actions.renames["OUTPUT_IS_SRGB"] = "true"; - actions.renames["FOG"] = "custom_fog"; + actions.renames["FOG"] = "fog"; actions.renames["RADIANCE"] = "custom_radiance"; actions.renames["IRRADIANCE"] = "custom_irradiance"; actions.renames["BONE_INDICES"] = "bone_attrib"; @@ -693,6 +693,11 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.renames["CUSTOM3"] = "custom3_attrib"; actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; + actions.renames["NODE_POSITION_WORLD"] = "model_matrix[3].xyz"; + actions.renames["CAMERA_POSITION_WORLD"] = "scene_data.inv_view_matrix[3].xyz"; + actions.renames["CAMERA_DIRECTION_WORLD"] = "scene_data.view_matrix[3].xyz"; + actions.renames["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz"; + actions.renames["VIEW_INDEX"] = "ViewIndex"; actions.renames["VIEW_MONO_LEFT"] = "0"; actions.renames["VIEW_RIGHT"] = "1"; @@ -788,7 +793,7 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; actions.instance_uniform_index_variable = "instances.data[instance_index_interp].instance_uniforms_ofs"; compiler.initialize(actions); @@ -817,7 +822,7 @@ void fragment() { material_storage->material_initialize(default_material); material_storage->material_set_shader(default_material, default_shader); - MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(default_material, RendererRD::SHADER_TYPE_3D)); + MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); default_shader_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS); default_shader_sdfgi_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF); @@ -845,7 +850,7 @@ void fragment() { material_storage->material_initialize(overdraw_material); material_storage->material_set_shader(overdraw_material, overdraw_material_shader); - MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(overdraw_material, RendererRD::SHADER_TYPE_3D)); + MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(overdraw_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); overdraw_material_shader_ptr = md->shader_data; overdraw_material_uniform_set = md->uniform_set; } diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index fb001d6933..fa9ebde1b2 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -93,7 +93,7 @@ public: SHADER_SPECIALIZATION_DIRECTIONAL_SOFT_SHADOWS = 1 << 3, }; - struct ShaderData : public RendererRD::ShaderData { + struct ShaderData : public RendererRD::MaterialStorage::ShaderData { enum BlendMode { //used internally BLEND_MODE_MIX, BLEND_MODE_ADD, @@ -182,7 +182,7 @@ public: virtual void set_code(const String &p_Code); virtual void set_path_hint(const String &p_path); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; @@ -198,12 +198,12 @@ public: SelfList<ShaderData>::List shader_list; - RendererRD::ShaderData *_create_shader_func(); - static RendererRD::ShaderData *_create_shader_funcs() { + RendererRD::MaterialStorage::ShaderData *_create_shader_func(); + static RendererRD::MaterialStorage::ShaderData *_create_shader_funcs() { return static_cast<SceneShaderForwardClustered *>(singleton)->_create_shader_func(); } - struct MaterialData : public RendererRD::MaterialData { + struct MaterialData : public RendererRD::MaterialStorage::MaterialData { ShaderData *shader_data = nullptr; RID uniform_set; uint64_t last_pass = 0; @@ -216,8 +216,8 @@ public: virtual ~MaterialData(); }; - RendererRD::MaterialData *_create_material_func(ShaderData *p_shader); - static RendererRD::MaterialData *_create_material_funcs(RendererRD::ShaderData *p_shader) { + RendererRD::MaterialStorage::MaterialData *_create_material_func(ShaderData *p_shader); + static RendererRD::MaterialStorage::MaterialData *_create_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader) { return static_cast<SceneShaderForwardClustered *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader)); } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 0ca71080fc..ffd47cc163 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -337,7 +337,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ if (p_radiance_texture.is_valid()) { radiance_texture = p_radiance_texture; } else { - radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); } RD::Uniform u; u.binding = 2; @@ -354,7 +354,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ if (ref_texture.is_valid()) { u.append_id(ref_texture); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); } uniforms.push_back(u); } @@ -368,7 +368,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ texture = shadow_atlas_get_texture(p_render_data->shadow_atlas); } if (!texture.is_valid()) { - texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_DEPTH); + texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH); } u.append_id(texture); uniforms.push_back(u); @@ -380,7 +380,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) { u.append_id(directional_shadow_get_texture()); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_DEPTH)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH)); } uniforms.push_back(u); } @@ -391,7 +391,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { if (p_render_data && i < p_render_data->lightmaps->size()) { RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]); @@ -412,7 +412,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(MAX_VOXEL_GI_INSTANCESS); - RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { if (i < (int)p_voxel_gi_instances.size()) { RID tex = gi.voxel_gi_instance_get_texture(p_voxel_gi_instances[i]); @@ -443,7 +443,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID dbt = rb ? render_buffers_get_back_depth_texture(p_render_data->render_buffers) : RID(); - RID texture = (dbt.is_valid()) ? dbt : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_DEPTH); + RID texture = (dbt.is_valid()) ? dbt : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH); u.append_id(texture); uniforms.push_back(u); } @@ -452,7 +452,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_data->render_buffers) : RID(); - RID texture = bbt.is_valid() ? bbt : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + RID texture = bbt.is_valid() ? bbt : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); u.append_id(texture); uniforms.push_back(u); } @@ -497,7 +497,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (p_render_data->render_buffers.is_valid()) { render_buffer = static_cast<RenderBufferDataForwardMobile *>(render_buffers_get_data(p_render_data->render_buffers)); } - RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment); RENDER_TIMESTAMP("Setup 3D Scene"); @@ -540,7 +539,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (render_buffer->color_fbs[FB_CONFIG_FOUR_SUBPASSES].is_null()) { // can't do blit subpass using_subpass_post_process = false; - } else if (env && (env->glow_enabled || env->auto_exposure || camera_effects_uses_dof(p_render_data->camera_effects))) { + } else if (p_render_data->environment.is_valid() && (environment_get_glow_enabled(p_render_data->environment) || environment_get_auto_exposure(p_render_data->environment) || camera_effects_uses_dof(p_render_data->camera_effects))) { // can't do blit subpass using_subpass_post_process = false; } @@ -570,7 +569,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { p_render_data->environment = RID(); //no environment on interiors - env = nullptr; } reverse_cull = true; @@ -612,7 +610,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color clear_color.g *= bg_energy; clear_color.b *= bg_energy; /* - if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { + if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_get_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } @@ -624,7 +622,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color clear_color.g *= bg_energy; clear_color.b *= bg_energy; /* - if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { + if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_get_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } @@ -655,11 +653,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color projection = correction * p_render_data->cam_projection; } - sky.setup(env, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); + sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); - RID sky_rid = env->sky; + RID sky_rid = environment_get_sky(p_render_data->environment); if (sky_rid.is_valid()) { - sky.update(env, projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); + sky.update(p_render_data->environment, projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -683,9 +681,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color Projection correction; correction.set_depth_correction(true); Projection projection = correction * p_render_data->cam_projection; - sky.update_res_buffers(env, 1, &projection, p_render_data->cam_transform, time); + sky.update_res_buffers(p_render_data->environment, 1, &projection, p_render_data->cam_transform, time); } else { - sky.update_res_buffers(env, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); + sky.update_res_buffers(p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); } RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers @@ -707,7 +705,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS; } - if (!is_environment(p_render_data->environment) || environment_is_fog_enabled(p_render_data->environment)) { + if (!is_environment(p_render_data->environment) || environment_get_fog_enabled(p_render_data->environment)) { spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG; } } @@ -782,9 +780,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color Projection correction; correction.set_depth_correction(true); Projection projection = correction * p_render_data->cam_projection; - sky.draw(draw_list, env, framebuffer, 1, &projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); + sky.draw(draw_list, p_render_data->environment, framebuffer, 1, &projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); } else { - sky.draw(draw_list, env, framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); + sky.draw(draw_list, p_render_data->environment, framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); } RD::get_singleton()->draw_command_end_label(); // Draw Sky Subpass @@ -907,7 +905,7 @@ void RenderForwardMobile::_render_shadow_begin() { render_list[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { +void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -1001,7 +999,7 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) { /* */ -void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering 3D Material"); RD::get_singleton()->draw_command_begin_label("Render 3D Material"); @@ -1047,7 +1045,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c RD::get_singleton()->draw_command_end_label(); } -void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering UV2"); RD::get_singleton()->draw_command_begin_label("Render UV2"); @@ -1114,11 +1112,11 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in RD::get_singleton()->draw_command_end_label(); } -void RenderForwardMobile::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { +void RenderForwardMobile::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { // we don't do GI in low end.. } -void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { +void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -1216,15 +1214,18 @@ void RenderForwardMobile::_update_render_base_uniform_set() { case RS::DECAL_FILTER_NEAREST: { sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; - case RS::DECAL_FILTER_NEAREST_MIPMAPS: { - sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - } break; case RS::DECAL_FILTER_LINEAR: { sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; + case RS::DECAL_FILTER_NEAREST_MIPMAPS: { + sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + } break; case RS::DECAL_FILTER_LINEAR_MIPMAPS: { sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; + case RS::DECAL_FILTER_NEAREST_MIPMAPS_ANISOTROPIC: { + sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + } break; case RS::DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC: { sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; @@ -1243,15 +1244,18 @@ void RenderForwardMobile::_update_render_base_uniform_set() { case RS::LIGHT_PROJECTOR_FILTER_NEAREST: { sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; - case RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS: { - sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - } break; case RS::LIGHT_PROJECTOR_FILTER_LINEAR: { sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; + case RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS: { + sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + } break; case RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS: { sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; + case RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS_ANISOTROPIC: { + sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + } break; case RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC: { sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } break; @@ -1332,7 +1336,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 14; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -1663,7 +1667,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, scene_state.ubo.use_ambient_cubemap = false; } else { float energy = environment_get_ambient_light_energy(p_render_data->environment); - Color color = environment_get_ambient_light_color(p_render_data->environment); + Color color = environment_get_ambient_light(p_render_data->environment); color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; @@ -1685,11 +1689,11 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, scene_state.ubo.use_reflection_cubemap = false; } - scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_render_data->environment); - scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_render_data->environment); - scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_render_data->environment); + scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_get_ssao_enabled(p_render_data->environment); + scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_channel_affect(p_render_data->environment); + scene_state.ubo.ssao_light_affect = environment_get_ssao_direct_light_affect(p_render_data->environment); - scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_render_data->environment); + scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment); scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment); scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment); scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); @@ -1899,7 +1903,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr push_constant.flags = inst->flags_cache; push_constant.gi_offset = inst->gi_offset_cache; push_constant.layer_mask = inst->layer_mask; - push_constant.instance_uniforms_ofs = uint32_t(inst->shader_parameters_offset); + push_constant.instance_uniforms_ofs = uint32_t(inst->shader_uniforms_offset); if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) { // abuse lightmap_uv_scale[0] here, should not be needed here @@ -2056,7 +2060,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr /* Geometry instance */ -RendererSceneRender::GeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base) { +RenderGeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base) { RS::InstanceType type = RSG::utilities->get_base_type(p_base); ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); @@ -2066,165 +2070,36 @@ RendererSceneRender::GeometryInstance *RenderForwardMobile::geometry_instance_cr ginstance->data->base = p_base; ginstance->data->base_type = type; - _geometry_instance_mark_dirty(ginstance); + ginstance->_mark_dirty(); return ginstance; } -void RenderForwardMobile::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->skeleton = p_skeleton; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_override = p_override; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_overlay = p_overlay; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->surface_materials = p_materials; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->mesh_instance = p_mesh_instance; - - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->transform = p_transform; - ginstance->mirror = p_transform.basis.determinant() < 0; - ginstance->data->aabb = p_aabb; - ginstance->transformed_aabb = p_transformed_aabb; - - Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); - // handle non uniform scale here - - float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); - float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); - ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; - - ginstance->lod_model_scale = max_scale; -} - -void RenderForwardMobile::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->layer_mask = p_layer_mask; -} - -void RenderForwardMobile::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lod_bias = p_lod_bias; -} - -void RenderForwardMobile::geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) { -} - -void RenderForwardMobile::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) { -} +void RenderForwardMobile::GeometryInstanceForwardMobile::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { + lightmap_instance = p_lightmap_instance; + lightmap_uv_scale = p_lightmap_uv_scale; + lightmap_slice_index = p_lightmap_slice_index; -void RenderForwardMobile::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) { + _mark_dirty(); } -void RenderForwardMobile::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_baked_light = p_enable; - - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) { - // !BAS! do we support this in mobile? - // GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - // ERR_FAIL_COND(!ginstance); - // ginstance->data->use_dynamic_gi = p_enable; - // _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lightmap_instance = p_lightmap_instance; - ginstance->lightmap_uv_scale = p_lightmap_uv_scale; - ginstance->lightmap_slice_index = p_lightmap_slice_index; - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardMobile::GeometryInstanceForwardMobile::set_lightmap_capture(const Color *p_sh9) { if (p_sh9) { - if (ginstance->lightmap_sh == nullptr) { - ginstance->lightmap_sh = geometry_instance_lightmap_sh.alloc(); + if (lightmap_sh == nullptr) { + lightmap_sh = RenderForwardMobile::get_singleton()->geometry_instance_lightmap_sh.alloc(); } - memcpy(ginstance->lightmap_sh->sh, p_sh9, sizeof(Color) * 9); + memcpy(lightmap_sh->sh, p_sh9, sizeof(Color) * 9); } else { - if (ginstance->lightmap_sh != nullptr) { - geometry_instance_lightmap_sh.free(ginstance->lightmap_sh); - ginstance->lightmap_sh = nullptr; + if (lightmap_sh != nullptr) { + RenderForwardMobile::get_singleton()->geometry_instance_lightmap_sh.free(lightmap_sh); + lightmap_sh = nullptr; } } - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->shader_parameters_offset = p_offset; - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->data->cast_double_sided_shadows = p_enable; - _geometry_instance_mark_dirty(ginstance); + _mark_dirty(); } -Transform3D RenderForwardMobile::geometry_instance_get_transform(GeometryInstance *p_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_instance); - ERR_FAIL_COND_V(!ginstance, Transform3D()); - return ginstance->transform; -} - -AABB RenderForwardMobile::geometry_instance_get_aabb(GeometryInstance *p_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_instance); - ERR_FAIL_COND_V(!ginstance, AABB()); - return ginstance->data->aabb; -} - -void RenderForwardMobile::geometry_instance_free(GeometryInstance *p_geometry_instance) { +void RenderForwardMobile::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); if (ginstance->lightmap_sh != nullptr) { @@ -2244,26 +2119,23 @@ uint32_t RenderForwardMobile::geometry_instance_get_pair_mask() { return ((1 << RS::INSTANCE_LIGHT) + (1 << RS::INSTANCE_REFLECTION_PROBE) + (1 << RS::INSTANCE_DECAL)); } -void RenderForwardMobile::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->omni_light_count = 0; - ginstance->spot_light_count = 0; +void RenderForwardMobile::GeometryInstanceForwardMobile::pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) { + omni_light_count = 0; + spot_light_count = 0; for (uint32_t i = 0; i < p_light_instance_count; i++) { - RS::LightType type = light_instance_get_type(p_light_instances[i]); + RS::LightType type = RenderForwardMobile::get_singleton()->light_instance_get_type(p_light_instances[i]); switch (type) { case RS::LIGHT_OMNI: { - if (ginstance->omni_light_count < (uint32_t)MAX_RDL_CULL) { - ginstance->omni_lights[ginstance->omni_light_count] = light_instance_get_forward_id(p_light_instances[i]); - ginstance->omni_light_count++; + if (omni_light_count < (uint32_t)MAX_RDL_CULL) { + omni_lights[omni_light_count] = RenderForwardMobile::get_singleton()->light_instance_get_forward_id(p_light_instances[i]); + omni_light_count++; } } break; case RS::LIGHT_SPOT: { - if (ginstance->spot_light_count < (uint32_t)MAX_RDL_CULL) { - ginstance->spot_lights[ginstance->spot_light_count] = light_instance_get_forward_id(p_light_instances[i]); - ginstance->spot_light_count++; + if (spot_light_count < (uint32_t)MAX_RDL_CULL) { + spot_lights[spot_light_count] = RenderForwardMobile::get_singleton()->light_instance_get_forward_id(p_light_instances[i]); + spot_light_count++; } } break; default: @@ -2272,56 +2144,42 @@ void RenderForwardMobile::geometry_instance_pair_light_instances(GeometryInstanc } } -void RenderForwardMobile::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->reflection_probe_count = p_reflection_probe_instance_count < (uint32_t)MAX_RDL_CULL ? p_reflection_probe_instance_count : (uint32_t)MAX_RDL_CULL; - for (uint32_t i = 0; i < ginstance->reflection_probe_count; i++) { - ginstance->reflection_probes[i] = reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]); +void RenderForwardMobile::GeometryInstanceForwardMobile::pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { + reflection_probe_count = p_reflection_probe_instance_count < (uint32_t)MAX_RDL_CULL ? p_reflection_probe_instance_count : (uint32_t)MAX_RDL_CULL; + for (uint32_t i = 0; i < reflection_probe_count; i++) { + reflection_probes[i] = RenderForwardMobile::get_singleton()->reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]); } } -void RenderForwardMobile::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->decals_count = p_decal_instance_count < (uint32_t)MAX_RDL_CULL ? p_decal_instance_count : (uint32_t)MAX_RDL_CULL; - for (uint32_t i = 0; i < ginstance->decals_count; i++) { - ginstance->decals[i] = decal_instance_get_forward_id(p_decal_instances[i]); +void RenderForwardMobile::GeometryInstanceForwardMobile::pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) { + decals_count = p_decal_instance_count < (uint32_t)MAX_RDL_CULL ? p_decal_instance_count : (uint32_t)MAX_RDL_CULL; + for (uint32_t i = 0; i < decals_count; i++) { + decals[i] = RenderForwardMobile::get_singleton()->decal_instance_get_forward_id(p_decal_instances[i]); } } -void RenderForwardMobile::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { - // We do not have this here! -} - -void RenderForwardMobile::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->use_projector = p_projector; - ginstance->use_soft_shadow = p_softshadow; +void RenderForwardMobile::GeometryInstanceForwardMobile::set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) { + use_projector = p_projector; + use_soft_shadow = p_softshadow; } -void RenderForwardMobile::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - if (ginstance->dirty_list_element.in_list()) { +void RenderForwardMobile::GeometryInstanceForwardMobile::_mark_dirty() { + if (dirty_list_element.in_list()) { return; } //clear surface caches - GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches; + GeometryInstanceSurfaceDataCache *surf = surface_caches; while (surf) { GeometryInstanceSurfaceDataCache *next = surf->next; - geometry_instance_surface_alloc.free(surf); + RenderForwardMobile::get_singleton()->geometry_instance_surface_alloc.free(surf); surf = next; } - ginstance->surface_caches = nullptr; + surface_caches = nullptr; - geometry_instance_dirty_list.add(&ginstance->dirty_list_element); + RenderForwardMobile::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element); } void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { @@ -2375,7 +2233,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI void *surface_shadow = nullptr; if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip) { flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL; - material_shadow = static_cast<SceneShaderForwardMobile::MaterialData *>(RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::SHADER_TYPE_3D)); + material_shadow = static_cast<SceneShaderForwardMobile::MaterialData *>(RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); RID shadow_mesh = mesh_storage->mesh_get_shadow_mesh(p_mesh); @@ -2434,7 +2292,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material_chain(Geo while (material->next_pass.is_valid()) { RID next_pass = material->next_pass; - material = static_cast<SceneShaderForwardMobile::MaterialData *>(material_storage->material_get_data(next_pass, RendererRD::SHADER_TYPE_3D)); + material = static_cast<SceneShaderForwardMobile::MaterialData *>(material_storage->material_get_data(next_pass, RendererRD::MaterialStorage::SHADER_TYPE_3D)); if (!material || !material->shader_data->valid) { break; } @@ -2454,7 +2312,7 @@ void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForward SceneShaderForwardMobile::MaterialData *material = nullptr; if (m_src.is_valid()) { - material = static_cast<SceneShaderForwardMobile::MaterialData *>(material_storage->material_get_data(m_src, RendererRD::SHADER_TYPE_3D)); + material = static_cast<SceneShaderForwardMobile::MaterialData *>(material_storage->material_get_data(m_src, RendererRD::MaterialStorage::SHADER_TYPE_3D)); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -2465,7 +2323,7 @@ void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForward material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker); } } else { - material = static_cast<SceneShaderForwardMobile::MaterialData *>(material_storage->material_get_data(scene_shader.default_material, RendererRD::SHADER_TYPE_3D)); + material = static_cast<SceneShaderForwardMobile::MaterialData *>(material_storage->material_get_data(scene_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); m_src = scene_shader.default_material; } @@ -2476,7 +2334,7 @@ void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForward if (ginstance->data->material_overlay.is_valid()) { m_src = ginstance->data->material_overlay; - material = static_cast<SceneShaderForwardMobile::MaterialData *>(material_storage->material_get_data(m_src, RendererRD::SHADER_TYPE_3D)); + material = static_cast<SceneShaderForwardMobile::MaterialData *>(material_storage->material_get_data(m_src, RendererRD::MaterialStorage::SHADER_TYPE_3D)); if (material && material->shader_data->valid) { if (ginstance->data->dirty_dependencies) { material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker); @@ -2487,7 +2345,7 @@ void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForward } } -void RenderForwardMobile::_geometry_instance_update(GeometryInstance *p_geometry_instance) { +void RenderForwardMobile::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) { RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton(); RendererRD::ParticlesStorage *particles_storage = RendererRD::ParticlesStorage::get_singleton(); GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); @@ -2641,7 +2499,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::Depe case Dependency::DEPENDENCY_CHANGED_PARTICLES: case Dependency::DEPENDENCY_CHANGED_MULTIMESH: case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { - static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } break; case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata); @@ -2655,7 +2513,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::Depe } } void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { - static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } /* misc */ @@ -2706,12 +2564,18 @@ void RenderForwardMobile::_update_shader_quality_settings() { sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL; sc.constant_id = SPEC_CONSTANT_DECAL_USE_MIPMAPS; - sc.bool_value = decals_get_filter() == RS::DECAL_FILTER_NEAREST_MIPMAPS || decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS || decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC; + sc.bool_value = decals_get_filter() == RS::DECAL_FILTER_NEAREST_MIPMAPS || + decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS || + decals_get_filter() == RS::DECAL_FILTER_NEAREST_MIPMAPS_ANISOTROPIC || + decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC; spec_constants.push_back(sc); sc.constant_id = SPEC_CONSTANT_PROJECTOR_USE_MIPMAPS; - sc.bool_value = light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS || light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS || light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC; + sc.bool_value = light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS || + light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS || + light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS_ANISOTROPIC || + light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC; spec_constants.push_back(sc); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index 5b1109512a..4a7112eb81 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -160,7 +160,7 @@ protected: // PASS_MODE_SDF, }; - struct GeometryInstanceForwardMobile; + class GeometryInstanceForwardMobile; struct GeometryInstanceSurfaceDataCache; struct RenderElementInfo; @@ -212,14 +212,14 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; - virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override; uint64_t lightmap_texture_array_version = 0xFFFFFFFF; @@ -518,14 +518,8 @@ protected: GeometryInstanceForwardMobile *owner = nullptr; }; - // !BAS! GeometryInstanceForwardClustered and GeometryInstanceForwardMobile will likely have a lot of overlap - // may need to think about making this its own class like GeometryInstanceRD? - - struct GeometryInstanceForwardMobile : public GeometryInstance { - // setup - uint32_t base_flags = 0; - uint32_t flags_cache = 0; - + class GeometryInstanceForwardMobile : public RenderGeometryInstanceBase { + public: // this structure maps to our push constant in our shader and is populated right before our draw call struct PushConstant { float transform[16]; @@ -543,28 +537,18 @@ protected: // PushConstant push_constant; // we populate this from our instance data //used during rendering - uint32_t layer_mask = 1; RID transforms_uniform_set; - float depth = 0; - bool mirror = false; bool use_projector = false; bool use_soft_shadow = false; - Transform3D transform; bool store_transform_cache = true; // if true we copy our transform into our PushConstant, if false we use our transforms UBO and clear our PushConstants transform - bool non_uniform_scale = false; - AABB transformed_aabb; //needed for LOD - float lod_bias = 0.0; - float lod_model_scale = 1.0; - int32_t shader_parameters_offset = -1; uint32_t instance_count = 0; uint32_t trail_steps = 1; - RID mesh_instance; // lightmap uint32_t gi_offset_cache = 0; // !BAS! Should rename this to lightmap_offset_cache, in forward clustered this was shared between gi and lightmap - uint32_t lightmap_slice_index; - Rect2 lightmap_uv_scale; RID lightmap_instance; + Rect2 lightmap_uv_scale; + uint32_t lightmap_slice_index; GeometryInstanceLightmapSH *lightmap_sh = nullptr; // culled light info @@ -582,30 +566,20 @@ protected: // do we use this? SelfList<GeometryInstanceForwardMobile> dirty_list_element; - struct Data { - //data used less often goes into regular heap - RID base; - RS::InstanceType base_type; - - RID skeleton; - Vector<RID> surface_materials; - RID material_override; - RID material_overlay; - AABB aabb; - - bool use_baked_light = true; - bool cast_double_sided_shadows = false; - // bool mirror = false; // !BAS! Does not seem used, we already have this in the main struct + GeometryInstanceForwardMobile() : + dirty_list_element(this) {} - bool dirty_dependencies = false; + virtual void _mark_dirty() override; - DependencyTracker dependency_tracker; - }; + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; + virtual void set_lightmap_capture(const Color *p_sh9) override; - Data *data = nullptr; + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override; + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override; + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} - GeometryInstanceForwardMobile() : - dirty_list_element(this) {} + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override; }; _FORCE_INLINE_ void _fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance); @@ -613,6 +587,8 @@ protected: void _update_shader_quality_settings() override; public: + static RenderForwardMobile *get_singleton() { return singleton; } + virtual RID reflection_probe_create_framebuffer(RID p_color, RID p_depth) override; static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker); @@ -627,41 +603,13 @@ public: void _geometry_instance_add_surface_with_material(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh); void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, RID p_mat_src, RID p_mesh); void _geometry_instance_add_surface(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, RID p_material, RID p_mesh); - void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance); - void _geometry_instance_update(GeometryInstance *p_geometry_instance); + void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance); void _update_dirty_geometry_instances(); - virtual GeometryInstance *geometry_instance_create(RID p_base) override; - virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override; - virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override; - virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) override; - virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) override; - virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override; - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override; - virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override; - virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override; - virtual void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override; - virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override; - virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override; - virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; - virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override; - virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override; - virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override; - - virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) override; - virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) override; - - virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) override; + virtual RenderGeometryInstance *geometry_instance_create(RID p_base) override; + virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override; virtual uint32_t geometry_instance_get_pair_mask() override; - virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override; - virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; - virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override; - virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - - virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override; virtual bool free(RID p_rid) override; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index ee902e5c52..01b54607bc 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -349,7 +349,7 @@ void SceneShaderForwardMobile::ShaderData::set_default_texture_param(const Strin } } -void SceneShaderForwardMobile::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void SceneShaderForwardMobile::ShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { @@ -445,7 +445,7 @@ SceneShaderForwardMobile::ShaderData::~ShaderData() { } } -RendererRD::ShaderData *SceneShaderForwardMobile::_create_shader_func() { +RendererRD::MaterialStorage::ShaderData *SceneShaderForwardMobile::_create_shader_func() { ShaderData *shader_data = memnew(ShaderData); singleton->shader_list.add(&shader_data->shader_list_element); return shader_data; @@ -469,7 +469,7 @@ SceneShaderForwardMobile::MaterialData::~MaterialData() { free_parameters_uniform_set(uniform_set); } -RendererRD::MaterialData *SceneShaderForwardMobile::_create_material_func(ShaderData *p_shader) { +RendererRD::MaterialStorage::MaterialData *SceneShaderForwardMobile::_create_material_func(ShaderData *p_shader) { MaterialData *material_data = memnew(MaterialData); material_data->shader_data = p_shader; //update will happen later anyway so do nothing. @@ -512,8 +512,8 @@ void SceneShaderForwardMobile::init(const String p_defines) { } } - material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_shader_funcs); - material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_material_funcs); + material_storage->shader_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_3D, _create_shader_funcs); + material_storage->material_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_3D, _create_material_funcs); { //shader compiler @@ -584,7 +584,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; actions.renames["DEPTH"] = "gl_FragDepth"; actions.renames["OUTPUT_IS_SRGB"] = "true"; - actions.renames["FOG"] = "custom_fog"; + actions.renames["FOG"] = "fog"; actions.renames["RADIANCE"] = "custom_radiance"; actions.renames["IRRADIANCE"] = "custom_irradiance"; actions.renames["BONE_INDICES"] = "bone_attrib"; @@ -595,6 +595,11 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.renames["CUSTOM3"] = "custom3_attrib"; actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; + actions.renames["NODE_POSITION_WORLD"] = "model_matrix[3].xyz"; + actions.renames["CAMERA_POSITION_WORLD"] = "scene_data.inv_view_matrix[3].xyz"; + actions.renames["CAMERA_DIRECTION_WORLD"] = "scene_data.view_matrix[3].xyz"; + actions.renames["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz"; + actions.renames["VIEW_INDEX"] = "ViewIndex"; actions.renames["VIEW_MONO_LEFT"] = "0"; actions.renames["VIEW_RIGHT"] = "1"; @@ -685,7 +690,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs"; actions.apply_luminance_multiplier = true; // apply luminance multiplier to screen texture @@ -716,7 +721,7 @@ void fragment() { material_storage->material_initialize(default_material); material_storage->material_set_shader(default_material, default_shader); - MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(default_material, RendererRD::SHADER_TYPE_3D)); + MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); default_shader_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS); default_material_shader_ptr = md->shader_data; @@ -743,7 +748,7 @@ void fragment() { material_storage->material_initialize(overdraw_material); material_storage->material_set_shader(overdraw_material, overdraw_material_shader); - MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(overdraw_material, RendererRD::SHADER_TYPE_3D)); + MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(overdraw_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); overdraw_material_shader_ptr = md->shader_data; overdraw_material_uniform_set = md->uniform_set; } diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index 0dbed0b07a..e208334547 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -55,7 +55,7 @@ public: SHADER_VERSION_MAX }; - struct ShaderData : public RendererRD::ShaderData { + struct ShaderData : public RendererRD::MaterialStorage::ShaderData { enum BlendMode { //used internally BLEND_MODE_MIX, BLEND_MODE_ADD, @@ -142,7 +142,7 @@ public: virtual void set_path_hint(const String &p_path); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; @@ -157,12 +157,12 @@ public: virtual ~ShaderData(); }; - RendererRD::ShaderData *_create_shader_func(); - static RendererRD::ShaderData *_create_shader_funcs() { + RendererRD::MaterialStorage::ShaderData *_create_shader_func(); + static RendererRD::MaterialStorage::ShaderData *_create_shader_funcs() { return static_cast<SceneShaderForwardMobile *>(singleton)->_create_shader_func(); } - struct MaterialData : public RendererRD::MaterialData { + struct MaterialData : public RendererRD::MaterialStorage::MaterialData { ShaderData *shader_data = nullptr; RID uniform_set; uint64_t last_pass = 0; @@ -177,8 +177,8 @@ public: SelfList<ShaderData>::List shader_list; - RendererRD::MaterialData *_create_material_func(ShaderData *p_shader); - static RendererRD::MaterialData *_create_material_funcs(RendererRD::ShaderData *p_shader) { + RendererRD::MaterialStorage::MaterialData *_create_material_func(ShaderData *p_shader); + static RendererRD::MaterialStorage::MaterialData *_create_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader) { return static_cast<SceneShaderForwardMobile *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader)); } diff --git a/core/multiplayer/multiplayer.h b/servers/rendering/renderer_rd/framebuffer_cache_rd.cpp index f4c965b0f8..9baa86a32d 100644 --- a/core/multiplayer/multiplayer.h +++ b/servers/rendering/renderer_rd/framebuffer_cache_rd.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* multiplayer.h */ +/* framebuffer_cache_rd.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,53 +28,37 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef MULTIPLAYER_H -#define MULTIPLAYER_H +#include "framebuffer_cache_rd.h" -#include "core/variant/binder_common.h" +FramebufferCacheRD *FramebufferCacheRD::singleton = nullptr; -#include "core/string/string_name.h" - -namespace Multiplayer { - -enum TransferMode { - TRANSFER_MODE_UNRELIABLE, - TRANSFER_MODE_UNRELIABLE_ORDERED, - TRANSFER_MODE_RELIABLE -}; - -enum RPCMode { - RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default) - RPC_MODE_ANY_PEER, // Any peer can call this RPC - RPC_MODE_AUTHORITY, // Only the node's multiplayer authority (server by default) can call this RPC -}; - -struct RPCConfig { - StringName name; - RPCMode rpc_mode = RPC_MODE_DISABLED; - bool call_local = false; - TransferMode transfer_mode = TRANSFER_MODE_RELIABLE; - int channel = 0; - - bool operator==(RPCConfig const &p_other) const { - return name == p_other.name; +void FramebufferCacheRD::_invalidate(Cache *p_cache) { + if (p_cache->prev) { + p_cache->prev->next = p_cache->next; + } else { + // At beginning of table + uint32_t table_idx = p_cache->hash % HASH_TABLE_SIZE; + hash_table[table_idx] = p_cache->next; } -}; -struct SortRPCConfig { - StringName::AlphCompare compare; - bool operator()(const RPCConfig &p_a, const RPCConfig &p_b) const { - return compare(p_a.name, p_b.name); + if (p_cache->next) { + p_cache->next->prev = p_cache->prev; } -}; - -}; // namespace Multiplayer -// This is needed for proper docs generation (i.e. not "Multiplayer."-prefixed). -typedef Multiplayer::RPCMode RPCMode; -typedef Multiplayer::TransferMode TransferMode; + cache_allocator.free(p_cache); + cache_instances_used--; +} +void FramebufferCacheRD::_framebuffer_invalidation_callback(void *p_userdata) { + singleton->_invalidate(reinterpret_cast<Cache *>(p_userdata)); +} -VARIANT_ENUM_CAST(RPCMode); -VARIANT_ENUM_CAST(TransferMode); +FramebufferCacheRD::FramebufferCacheRD() { + ERR_FAIL_COND(singleton != nullptr); + singleton = this; +} -#endif // MULTIPLAYER_H +FramebufferCacheRD::~FramebufferCacheRD() { + if (cache_instances_used > 0) { + ERR_PRINT("At exit: " + itos(cache_instances_used) + " framebuffer cache instance(s) still in use."); + } +} diff --git a/servers/rendering/renderer_rd/framebuffer_cache_rd.h b/servers/rendering/renderer_rd/framebuffer_cache_rd.h new file mode 100644 index 0000000000..f360e0fc6b --- /dev/null +++ b/servers/rendering/renderer_rd/framebuffer_cache_rd.h @@ -0,0 +1,310 @@ +/*************************************************************************/ +/* framebuffer_cache_rd.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef FRAMEBUFFER_CACHE_RD_H +#define FRAMEBUFFER_CACHE_RD_H + +#include "core/templates/local_vector.h" +#include "core/templates/paged_allocator.h" +#include "servers/rendering/rendering_device.h" + +class FramebufferCacheRD : public Object { + GDCLASS(FramebufferCacheRD, Object) + + struct Cache { + Cache *prev = nullptr; + Cache *next = nullptr; + uint32_t hash = 0; + RID cache; + LocalVector<RID> textures; + LocalVector<RD::FramebufferPass> passes; + uint32_t views = 0; + }; + + PagedAllocator<Cache> cache_allocator; + + enum { + HASH_TABLE_SIZE = 16381 // Prime + }; + + Cache *hash_table[HASH_TABLE_SIZE] = {}; + + static _FORCE_INLINE_ uint32_t _hash_pass(const RD::FramebufferPass &p, uint32_t h) { + h = hash_murmur3_one_32(p.depth_attachment, h); + h = hash_murmur3_one_32(p.vrs_attachment, h); + + h = hash_murmur3_one_32(p.color_attachments.size(), h); + for (int i = 0; i < p.color_attachments.size(); i++) { + h = hash_murmur3_one_32(p.color_attachments[i], h); + } + + h = hash_murmur3_one_32(p.resolve_attachments.size(), h); + for (int i = 0; i < p.resolve_attachments.size(); i++) { + h = hash_murmur3_one_32(p.resolve_attachments[i], h); + } + + h = hash_murmur3_one_32(p.preserve_attachments.size(), h); + for (int i = 0; i < p.preserve_attachments.size(); i++) { + h = hash_murmur3_one_32(p.preserve_attachments[i], h); + } + + return h; + } + + static _FORCE_INLINE_ bool _compare_pass(const RD::FramebufferPass &a, const RD::FramebufferPass &b) { + if (a.depth_attachment != b.depth_attachment) { + return false; + } + + if (a.vrs_attachment != b.vrs_attachment) { + return false; + } + + if (a.color_attachments.size() != b.color_attachments.size()) { + return false; + } + + for (int i = 0; i < a.color_attachments.size(); i++) { + if (a.color_attachments[i] != b.color_attachments[i]) { + return false; + } + } + + if (a.resolve_attachments.size() != b.resolve_attachments.size()) { + return false; + } + + for (int i = 0; i < a.resolve_attachments.size(); i++) { + if (a.resolve_attachments[i] != b.resolve_attachments[i]) { + return false; + } + } + + if (a.preserve_attachments.size() != b.preserve_attachments.size()) { + return false; + } + + for (int i = 0; i < a.preserve_attachments.size(); i++) { + if (a.preserve_attachments[i] != b.preserve_attachments[i]) { + return false; + } + } + + return true; + } + + _FORCE_INLINE_ uint32_t _hash_rids(uint32_t h, const RID &arg) { + return hash_murmur3_one_64(arg.get_id(), h); + } + + template <typename... Args> + uint32_t _hash_rids(uint32_t h, const RID &arg, Args... args) { + h = hash_murmur3_one_64(arg.get_id(), h); + return _hash_rids(h, args...); + } + + _FORCE_INLINE_ bool _compare_args(uint32_t idx, const LocalVector<RID> &textures, const RID &arg) { + return textures[idx] == arg; + } + + template <typename... Args> + _FORCE_INLINE_ bool _compare_args(uint32_t idx, const LocalVector<RID> &textures, const RID &arg, Args... args) { + if (textures[idx] != arg) { + return false; + } + return _compare_args(idx + 1, textures, args...); + } + + _FORCE_INLINE_ void _create_args(Vector<RID> &textures, const RID &arg) { + textures.push_back(arg); + } + + template <typename... Args> + _FORCE_INLINE_ void _create_args(Vector<RID> &textures, const RID &arg, Args... args) { + textures.push_back(arg); + _create_args(textures, args...); + } + + static FramebufferCacheRD *singleton; + + uint32_t cache_instances_used = 0; + + void _invalidate(Cache *p_cache); + static void _framebuffer_invalidation_callback(void *p_userdata); + + RID _allocate_from_data(uint32_t p_views, uint32_t p_hash, uint32_t p_table_idx, const Vector<RID> &p_textures, const Vector<RD::FramebufferPass> &p_passes) { + RID rid; + if (p_passes.size()) { + rid = RD::get_singleton()->framebuffer_create_multipass(p_textures, p_passes, RD::INVALID_ID, p_views); + } else { + rid = RD::get_singleton()->framebuffer_create(p_textures, RD::INVALID_ID, p_views); + } + + ERR_FAIL_COND_V(rid.is_null(), rid); + + Cache *c = cache_allocator.alloc(); + c->views = p_views; + c->cache = rid; + c->hash = p_hash; + c->textures.resize(p_textures.size()); + for (uint32_t i = 0; i < c->textures.size(); i++) { + c->textures[i] = p_textures[i]; + } + c->passes.resize(p_passes.size()); + for (uint32_t i = 0; i < c->passes.size(); i++) { + c->passes[i] = p_passes[i]; + } + c->prev = nullptr; + c->next = hash_table[p_table_idx]; + if (hash_table[p_table_idx]) { + hash_table[p_table_idx]->prev = c; + } + hash_table[p_table_idx] = c; + + RD::get_singleton()->framebuffer_set_invalidation_callback(rid, _framebuffer_invalidation_callback, c); + + cache_instances_used++; + + return rid; + } + +public: + template <typename... Args> + RID get_cache(Args... args) { + uint32_t h = hash_murmur3_one_32(1); //1 view + h = hash_murmur3_one_32(sizeof...(Args), h); + h = _hash_args(h, args...); + h = hash_murmur3_one_32(0, h); // 0 passes + h = hash_fmix32(h); + + uint32_t table_idx = h % HASH_TABLE_SIZE; + { + const Cache *c = hash_table[table_idx]; + + while (c) { + if (c->hash == h && c->passes.size() == 0 && c->textures.size() == sizeof...(Args) && c->views == 1 && _compare_args(0, c->textures, args...)) { + return c->cache; + } + c = c->next; + } + } + + // Not in cache, create: + + Vector<RID> textures; + _create_args(textures, args...); + + return _allocate_from_data(1, h, table_idx, textures, Vector<RD::FramebufferPass>()); + } + + template <typename... Args> + RID get_cache_multiview(uint32_t p_views, Args... args) { + uint32_t h = hash_murmur3_one_32(p_views); + h = hash_murmur3_one_32(sizeof...(Args), h); + h = _hash_args(h, args...); + h = hash_murmur3_one_32(0, h); // 0 passes + h = hash_fmix32(h); + + uint32_t table_idx = h % HASH_TABLE_SIZE; + { + const Cache *c = hash_table[table_idx]; + + while (c) { + if (c->hash == h && c->passes.size() == 0 && c->textures.size() == sizeof...(Args) && c->views == p_views && _compare_args(0, c->textures, args...)) { + return c->cache; + } + c = c->next; + } + } + + // Not in cache, create: + + Vector<RID> textures; + _create_args(textures, args...); + + return _allocate_from_data(p_views, h, table_idx, textures, Vector<RD::FramebufferPass>()); + } + + RID get_cache_multipass(const Vector<RID> &p_textures, const Vector<RD::FramebufferPass> &p_passes, uint32_t p_views = 1) { + uint32_t h = hash_murmur3_one_32(p_views); + h = hash_murmur3_one_32(p_textures.size()); + for (int i = 0; i < p_textures.size(); i++) { + h = hash_murmur3_one_64(p_textures[i].get_id(), h); + } + h = hash_murmur3_one_32(p_passes.size()); + for (int i = 0; i < p_passes.size(); i++) { + h = _hash_pass(p_passes[i], h); + } + + h = hash_fmix32(h); + + uint32_t table_idx = h % HASH_TABLE_SIZE; + { + const Cache *c = hash_table[table_idx]; + + while (c) { + if (c->hash == h && c->views == p_views && c->textures.size() == (uint32_t)p_textures.size() && c->passes.size() == (uint32_t)p_passes.size()) { + bool all_ok = true; + + for (int i = 0; i < p_textures.size(); i++) { + if (p_textures[i] != c->textures[i]) { + all_ok = false; + break; + } + } + + if (all_ok) { + for (int i = 0; i < p_passes.size(); i++) { + if (!_compare_pass(p_passes[i], c->passes[i])) { + all_ok = false; + break; + } + } + } + + if (all_ok) { + return c->cache; + } + } + c = c->next; + } + } + + // Not in cache, create: + return _allocate_from_data(p_views, h, table_idx, p_textures, p_passes); + } + + static FramebufferCacheRD *get_singleton() { return singleton; } + + FramebufferCacheRD(); + ~FramebufferCacheRD(); +}; + +#endif // FRAMEBUFFER_CACHE_RD_H diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index a58cdd5066..c1b08ee4c9 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -192,7 +192,7 @@ RendererCanvasRender::PolygonID RendererCanvasRenderRD::request_polygon(const Ve vd.stride = 0; descriptions.write[1] = vd; - buffers.write[1] = mesh_storage->mesh_get_default_rd_buffer(RendererRD::DEFAULT_RD_BUFFER_COLOR); + buffers.write[1] = mesh_storage->mesh_get_default_rd_buffer(RendererRD::MeshStorage::DEFAULT_RD_BUFFER_COLOR); } //uvs @@ -220,7 +220,7 @@ RendererCanvasRender::PolygonID RendererCanvasRenderRD::request_polygon(const Ve vd.stride = 0; descriptions.write[2] = vd; - buffers.write[2] = mesh_storage->mesh_get_default_rd_buffer(RendererRD::DEFAULT_RD_BUFFER_TEX_UV); + buffers.write[2] = mesh_storage->mesh_get_default_rd_buffer(RendererRD::MeshStorage::DEFAULT_RD_BUFFER_TEX_UV); } //bones @@ -253,7 +253,7 @@ RendererCanvasRender::PolygonID RendererCanvasRenderRD::request_polygon(const Ve vd.stride = 0; descriptions.write[3] = vd; - buffers.write[3] = mesh_storage->mesh_get_default_rd_buffer(RendererRD::DEFAULT_RD_BUFFER_BONES); + buffers.write[3] = mesh_storage->mesh_get_default_rd_buffer(RendererRD::MeshStorage::DEFAULT_RD_BUFFER_BONES); } //weights @@ -286,7 +286,7 @@ RendererCanvasRender::PolygonID RendererCanvasRenderRD::request_polygon(const Ve vd.stride = 0; descriptions.write[4] = vd; - buffers.write[4] = mesh_storage->mesh_get_default_rd_buffer(RendererRD::DEFAULT_RD_BUFFER_WEIGHTS); + buffers.write[4] = mesh_storage->mesh_get_default_rd_buffer(RendererRD::MeshStorage::DEFAULT_RD_BUFFER_WEIGHTS); } //check that everything is as it should be @@ -988,7 +988,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo } else { screen = texture_storage->render_target_get_rd_backbuffer(p_to_render_target); if (screen.is_null()) { //unallocated backbuffer - screen = RendererRD::TextureStorage::get_singleton()->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); + screen = RendererRD::TextureStorage::get_singleton()->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); } } u.append_id(screen); @@ -1031,7 +1031,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 9; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -1115,7 +1115,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co if (material != prev_material) { CanvasMaterialData *material_data = nullptr; if (material.is_valid()) { - material_data = static_cast<CanvasMaterialData *>(material_storage->material_get_data(material, RendererRD::SHADER_TYPE_2D)); + material_data = static_cast<CanvasMaterialData *>(material_storage->material_get_data(material, RendererRD::MaterialStorage::SHADER_TYPE_2D)); } if (material_data) { @@ -1304,7 +1304,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p Size2i ssize = texture_storage->render_target_get_size(p_to_render_target); Transform3D screen_transform; - screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); + screen_transform.translate_local(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f)); _update_transform_to_mat4(screen_transform, state_buffer.screen_transform); _update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform); @@ -1383,7 +1383,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material; if (material.is_valid()) { - CanvasMaterialData *md = static_cast<CanvasMaterialData *>(material_storage->material_get_data(material, RendererRD::SHADER_TYPE_2D)); + CanvasMaterialData *md = static_cast<CanvasMaterialData *>(material_storage->material_get_data(material, RendererRD::MaterialStorage::SHADER_TYPE_2D)); if (md && md->shader_data->valid) { if (md->shader_data->uses_screen_texture && canvas_group_owner == nullptr) { if (!material_screen_texture_found) { @@ -2171,7 +2171,7 @@ void RendererCanvasRenderRD::CanvasShaderData::set_default_texture_param(const S } } -void RendererCanvasRenderRD::CanvasShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void RendererCanvasRenderRD::CanvasShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { @@ -2261,7 +2261,7 @@ RendererCanvasRenderRD::CanvasShaderData::~CanvasShaderData() { } } -RendererRD::ShaderData *RendererCanvasRenderRD::_create_shader_func() { +RendererRD::MaterialStorage::ShaderData *RendererCanvasRenderRD::_create_shader_func() { CanvasShaderData *shader_data = memnew(CanvasShaderData); return shader_data; } @@ -2276,7 +2276,7 @@ RendererCanvasRenderRD::CanvasMaterialData::~CanvasMaterialData() { free_parameters_uniform_set(uniform_set); } -RendererRD::MaterialData *RendererCanvasRenderRD::_create_material_func(CanvasShaderData *p_shader) { +RendererRD::MaterialStorage::MaterialData *RendererCanvasRenderRD::_create_material_func(CanvasShaderData *p_shader) { CanvasMaterialData *material_data = memnew(CanvasMaterialData); material_data->shader_data = p_shader; //update will happen later anyway so do nothing. @@ -2469,7 +2469,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() { actions.default_repeat = ShaderLanguage::REPEAT_DISABLE; actions.base_varying_index = 4; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; shader.compiler.initialize(actions); } @@ -2629,8 +2629,8 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() { state.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size"); //create functions for shader and material - material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_2D, _create_shader_funcs); - material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_2D, _create_material_funcs); + material_storage->shader_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_2D, _create_shader_funcs); + material_storage->material_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_2D, _create_material_funcs); state.time = 0; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 1c0567b677..5eb4cee4c6 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -149,7 +149,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { ShaderCompiler compiler; } shader; - struct CanvasShaderData : public RendererRD::ShaderData { + struct CanvasShaderData : public RendererRD::MaterialStorage::ShaderData { enum BlendMode { //used internally BLEND_MODE_MIX, BLEND_MODE_ADD, @@ -180,7 +180,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { virtual void set_code(const String &p_Code); virtual void set_path_hint(const String &p_path); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; @@ -193,12 +193,12 @@ class RendererCanvasRenderRD : public RendererCanvasRender { virtual ~CanvasShaderData(); }; - RendererRD::ShaderData *_create_shader_func(); - static RendererRD::ShaderData *_create_shader_funcs() { + RendererRD::MaterialStorage::ShaderData *_create_shader_func(); + static RendererRD::MaterialStorage::ShaderData *_create_shader_funcs() { return static_cast<RendererCanvasRenderRD *>(singleton)->_create_shader_func(); } - struct CanvasMaterialData : public RendererRD::MaterialData { + struct CanvasMaterialData : public RendererRD::MaterialStorage::MaterialData { CanvasShaderData *shader_data = nullptr; RID uniform_set; @@ -208,8 +208,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender { virtual ~CanvasMaterialData(); }; - RendererRD::MaterialData *_create_material_func(CanvasShaderData *p_shader); - static RendererRD::MaterialData *_create_material_funcs(RendererRD::ShaderData *p_shader) { + RendererRD::MaterialStorage::MaterialData *_create_material_func(CanvasShaderData *p_shader); + static RendererRD::MaterialStorage::MaterialData *_create_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader) { return static_cast<RendererCanvasRenderRD *>(singleton)->_create_material_func(static_cast<CanvasShaderData *>(p_shader)); } diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index a61172c8f5..967b725b9e 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -249,6 +249,7 @@ RendererCompositorRD *RendererCompositorRD::singleton = nullptr; RendererCompositorRD::RendererCompositorRD() { uniform_set_cache = memnew(UniformSetCacheRD); + framebuffer_cache = memnew(FramebufferCacheRD); { String shader_cache_dir = Engine::get_singleton()->get_shader_cache_path(); @@ -316,5 +317,6 @@ RendererCompositorRD::RendererCompositorRD() { RendererCompositorRD::~RendererCompositorRD() { memdelete(uniform_set_cache); + memdelete(framebuffer_cache); ShaderRD::set_shader_cache_dir(String()); } diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index 564c26bfe4..a28335f800 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -37,6 +37,7 @@ #include "servers/rendering/renderer_rd/environment/fog.h" #include "servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h" #include "servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h" +#include "servers/rendering/renderer_rd/framebuffer_cache_rd.h" #include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h" #include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h" #include "servers/rendering/renderer_rd/storage_rd/light_storage.h" @@ -50,6 +51,7 @@ class RendererCompositorRD : public RendererCompositor { protected: UniformSetCacheRD *uniform_set_cache = nullptr; + FramebufferCacheRD *framebuffer_cache = nullptr; RendererCanvasRenderRD *canvas = nullptr; RendererRD::Utilities *utilities = nullptr; RendererRD::LightStorage *light_storage = nullptr; diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp deleted file mode 100644 index 0d9477d850..0000000000 --- a/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************/ -/* renderer_scene_environment_rd.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" - -uint64_t RendererSceneEnvironmentRD::auto_exposure_counter = 2; - -void RendererSceneEnvironmentRD::set_ambient_light(const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) { - ambient_light = p_color; - ambient_source = p_ambient; - ambient_light_energy = p_energy; - ambient_sky_contribution = p_sky_contribution; - reflection_source = p_reflection_source; -} - -void RendererSceneEnvironmentRD::set_tonemap(RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { - exposure = p_exposure; - tone_mapper = p_tone_mapper; - if (!auto_exposure && p_auto_exposure) { - auto_exposure_version = ++auto_exposure_counter; - } - auto_exposure = p_auto_exposure; - white = p_white; - min_luminance = p_min_luminance; - max_luminance = p_max_luminance; - auto_exp_speed = p_auto_exp_speed; - auto_exp_scale = p_auto_exp_scale; -} - -void RendererSceneEnvironmentRD::set_glow(bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) { - ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7"); - glow_enabled = p_enable; - glow_levels = p_levels; - glow_intensity = p_intensity; - glow_strength = p_strength; - glow_mix = p_mix; - glow_bloom = p_bloom_threshold; - glow_blend_mode = p_blend_mode; - glow_hdr_bleed_threshold = p_hdr_bleed_threshold; - glow_hdr_bleed_scale = p_hdr_bleed_scale; - glow_hdr_luminance_cap = p_hdr_luminance_cap; - glow_map_strength = p_glow_map_strength; - glow_map = p_glow_map; -} - -void RendererSceneEnvironmentRD::set_sdfgi(bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { - sdfgi_enabled = p_enable; - sdfgi_cascades = p_cascades; - sdfgi_min_cell_size = p_min_cell_size; - sdfgi_use_occlusion = p_use_occlusion; - sdfgi_bounce_feedback = p_bounce_feedback; - sdfgi_read_sky_light = p_read_sky; - sdfgi_energy = p_energy; - sdfgi_normal_bias = p_normal_bias; - sdfgi_probe_bias = p_probe_bias; - sdfgi_y_scale = p_y_scale; -} - -void RendererSceneEnvironmentRD::set_fog(bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { - fog_enabled = p_enable; - fog_light_color = p_light_color; - fog_light_energy = p_light_energy; - fog_sun_scatter = p_sun_scatter; - fog_density = p_density; - fog_height = p_height; - fog_height_density = p_height_density; - fog_aerial_perspective = p_fog_aerial_perspective; -} - -void RendererSceneEnvironmentRD::set_volumetric_fog(bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { - volumetric_fog_enabled = p_enable; - volumetric_fog_density = p_density; - volumetric_fog_scattering = p_albedo; - volumetric_fog_emission = p_emission; - volumetric_fog_emission_energy = p_emission_energy; - volumetric_fog_anisotropy = p_anisotropy, - volumetric_fog_length = p_length; - volumetric_fog_detail_spread = p_detail_spread; - volumetric_fog_gi_inject = p_gi_inject; - volumetric_fog_temporal_reprojection = p_temporal_reprojection; - volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount; - volumetric_fog_ambient_inject = p_ambient_inject; -} - -void RendererSceneEnvironmentRD::set_ssr(bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { - ssr_enabled = p_enable; - ssr_max_steps = p_max_steps; - ssr_fade_in = p_fade_int; - ssr_fade_out = p_fade_out; - ssr_depth_tolerance = p_depth_tolerance; -} - -void RendererSceneEnvironmentRD::set_ssao(bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) { - ssao_enabled = p_enable; - ssao_radius = p_radius; - ssao_intensity = p_intensity; - ssao_power = p_power; - ssao_detail = p_detail; - ssao_horizon = p_horizon; - ssao_sharpness = p_sharpness; - ssao_direct_light_affect = p_light_affect; - ssao_ao_channel_affect = p_ao_channel_affect; -} diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h b/servers/rendering/renderer_rd/renderer_scene_environment_rd.h deleted file mode 100644 index d9f78b3bc3..0000000000 --- a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************/ -/* renderer_scene_environment_rd.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RENDERER_SCENE_ENVIRONMENT_RD_H -#define RENDERER_SCENE_ENVIRONMENT_RD_H - -#include "servers/rendering/renderer_scene_render.h" -#include "servers/rendering/rendering_device.h" - -class RendererSceneEnvironmentRD { -private: - static uint64_t auto_exposure_counter; - -public: - // BG - RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR; - RID sky; - float sky_custom_fov = 0.0; - Basis sky_orientation; - Color bg_color; - float bg_energy = 1.0; - int canvas_max_layer = 0; - RS::EnvironmentAmbientSource ambient_source = RS::ENV_AMBIENT_SOURCE_BG; - Color ambient_light; - float ambient_light_energy = 1.0; - float ambient_sky_contribution = 1.0; - RS::EnvironmentReflectionSource reflection_source = RS::ENV_REFLECTION_SOURCE_BG; - - /// Tonemap - - RS::EnvironmentToneMapper tone_mapper; - float exposure = 1.0; - float white = 1.0; - bool auto_exposure = false; - float min_luminance = 0.2; - float max_luminance = 8.0; - float auto_exp_speed = 0.2; - float auto_exp_scale = 0.5; - uint64_t auto_exposure_version = 0; - - // Fog - bool fog_enabled = false; - Color fog_light_color = Color(0.5, 0.6, 0.7); - float fog_light_energy = 1.0; - float fog_sun_scatter = 0.0; - float fog_density = 0.001; - float fog_height = 0.0; - float fog_height_density = 0.0; //can be negative to invert effect - float fog_aerial_perspective = 0.0; - - /// Volumetric Fog - /// - bool volumetric_fog_enabled = false; - float volumetric_fog_density = 0.01; - Color volumetric_fog_scattering = Color(1, 1, 1); - Color volumetric_fog_emission = Color(0, 0, 0); - float volumetric_fog_emission_energy = 0.0; - float volumetric_fog_anisotropy = 0.2; - float volumetric_fog_length = 64.0; - float volumetric_fog_detail_spread = 2.0; - float volumetric_fog_gi_inject = 0.0; - bool volumetric_fog_temporal_reprojection = true; - float volumetric_fog_temporal_reprojection_amount = 0.9; - float volumetric_fog_ambient_inject = 0.0; - - /// Glow - - bool glow_enabled = false; - Vector<float> glow_levels; - float glow_intensity = 0.8; - float glow_strength = 1.0; - float glow_bloom = 0.0; - float glow_mix = 0.01; - RS::EnvironmentGlowBlendMode glow_blend_mode = RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT; - float glow_hdr_bleed_threshold = 1.0; - float glow_hdr_luminance_cap = 12.0; - float glow_hdr_bleed_scale = 2.0; - float glow_map_strength = 0.0f; - RID glow_map = RID(); - - /// SSAO - - bool ssao_enabled = false; - float ssao_radius = 1.0; - float ssao_intensity = 2.0; - float ssao_power = 1.5; - float ssao_detail = 0.5; - float ssao_horizon = 0.06; - float ssao_sharpness = 0.98; - float ssao_direct_light_affect = 0.0; - float ssao_ao_channel_affect = 0.0; - - /// SSR - /// - bool ssr_enabled = false; - int ssr_max_steps = 64; - float ssr_fade_in = 0.15; - float ssr_fade_out = 2.0; - float ssr_depth_tolerance = 0.2; - - /// SSIL - /// - bool ssil_enabled = false; - float ssil_radius = 5.0; - float ssil_intensity = 1.0; - float ssil_sharpness = 0.98; - float ssil_normal_rejection = 1.0; - - /// SDFGI - bool sdfgi_enabled = false; - int sdfgi_cascades = 4; - float sdfgi_min_cell_size = 0.2; - bool sdfgi_use_occlusion = false; - float sdfgi_bounce_feedback = 0.5; - bool sdfgi_read_sky_light = true; - float sdfgi_energy = 1.0; - float sdfgi_normal_bias = 1.1; - float sdfgi_probe_bias = 1.1; - RS::EnvironmentSDFGIYScale sdfgi_y_scale = RS::ENV_SDFGI_Y_SCALE_75_PERCENT; - - /// Adjustments - - bool adjustments_enabled = false; - float adjustments_brightness = 1.0f; - float adjustments_contrast = 1.0f; - float adjustments_saturation = 1.0f; - bool use_1d_color_correction = false; - RID color_correction = RID(); - - void set_ambient_light(const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source); - void set_tonemap(RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); - void set_glow(bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map); - void set_sdfgi(bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias); - void set_fog(bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective); - void set_volumetric_fog(bool p_enable, float p_density, const Color &p_scatterin, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject); - void set_ssr(bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance); - void set_ssao(bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect); -}; - -#endif // RENDERER_SCENE_ENVIRONMENT_RD_H diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 3161f03192..8b3b7050d2 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -51,9 +51,8 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) { } void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); - bool needs_sdfgi = env && env->sdfgi_enabled; + bool needs_sdfgi = p_environment.is_valid() && environment_get_sdfgi_enabled(p_environment); if (!needs_sdfgi) { if (rb->sdfgi != nullptr) { @@ -68,7 +67,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment static const uint32_t history_frames_to_converge[RS::ENV_SDFGI_CONVERGE_MAX] = { 5, 10, 15, 20, 25, 30 }; uint32_t requested_history_size = history_frames_to_converge[gi.sdfgi_frames_to_converge]; - if (rb->sdfgi && (rb->sdfgi->num_cascades != env->sdfgi_cascades || rb->sdfgi->min_cell_size != env->sdfgi_min_cell_size || requested_history_size != rb->sdfgi->history_size || rb->sdfgi->uses_occlusion != env->sdfgi_use_occlusion || rb->sdfgi->y_scale_mode != env->sdfgi_y_scale)) { + if (rb->sdfgi && (rb->sdfgi->num_cascades != environment_get_sdfgi_cascades(p_environment) || rb->sdfgi->min_cell_size != environment_get_sdfgi_min_cell_size(p_environment) || requested_history_size != rb->sdfgi->history_size || rb->sdfgi->uses_occlusion != environment_get_sdfgi_use_occlusion(p_environment) || rb->sdfgi->y_scale_mode != environment_get_sdfgi_y_scale(p_environment))) { //configuration changed, erase rb->sdfgi->erase(); memdelete(rb->sdfgi); @@ -78,10 +77,10 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment RendererRD::GI::SDFGI *sdfgi = rb->sdfgi; if (sdfgi == nullptr) { // re-create - rb->sdfgi = gi.create_sdfgi(env, p_world_position, requested_history_size); + rb->sdfgi = gi.create_sdfgi(p_environment, p_world_position, requested_history_size); } else { //check for updates - rb->sdfgi->update(env, p_world_position); + rb->sdfgi->update(p_environment, p_world_position); } } @@ -159,145 +158,6 @@ Ref<Image> RendererSceneRenderRD::sky_bake_panorama(RID p_sky, float p_energy, b return sky.sky_bake_panorama(p_sky, p_energy, p_bake_irradiance, p_size); } -RID RendererSceneRenderRD::environment_allocate() { - return environment_owner.allocate_rid(); -} -void RendererSceneRenderRD::environment_initialize(RID p_rid) { - environment_owner.initialize_rid(p_rid, RendererSceneEnvironmentRD()); -} - -void RendererSceneRenderRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->background = p_bg; -} - -void RendererSceneRenderRD::environment_set_sky(RID p_env, RID p_sky) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky = p_sky; -} - -void RendererSceneRenderRD::environment_set_sky_custom_fov(RID p_env, float p_scale) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky_custom_fov = p_scale; -} - -void RendererSceneRenderRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky_orientation = p_orientation; -} - -void RendererSceneRenderRD::environment_set_bg_color(RID p_env, const Color &p_color) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->bg_color = p_color; -} - -void RendererSceneRenderRD::environment_set_bg_energy(RID p_env, float p_energy) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->bg_energy = p_energy; -} - -void RendererSceneRenderRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->canvas_max_layer = p_max_layer; -} - -void RendererSceneRenderRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->set_ambient_light(p_color, p_ambient, p_energy, p_sky_contribution, p_reflection_source); -} - -RS::EnvironmentBG RendererSceneRenderRD::environment_get_background(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX); - return env->background; -} - -RID RendererSceneRenderRD::environment_get_sky(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, RID()); - return env->sky; -} - -float RendererSceneRenderRD::environment_get_sky_custom_fov(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->sky_custom_fov; -} - -Basis RendererSceneRenderRD::environment_get_sky_orientation(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Basis()); - return env->sky_orientation; -} - -Color RendererSceneRenderRD::environment_get_bg_color(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Color()); - return env->bg_color; -} - -float RendererSceneRenderRD::environment_get_bg_energy(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->bg_energy; -} - -int RendererSceneRenderRD::environment_get_canvas_max_layer(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->canvas_max_layer; -} - -Color RendererSceneRenderRD::environment_get_ambient_light_color(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Color()); - return env->ambient_light; -} - -RS::EnvironmentAmbientSource RendererSceneRenderRD::environment_get_ambient_source(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG); - return env->ambient_source; -} - -float RendererSceneRenderRD::environment_get_ambient_light_energy(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->ambient_light_energy; -} - -float RendererSceneRenderRD::environment_get_ambient_sky_contribution(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->ambient_sky_contribution; -} - -RS::EnvironmentReflectionSource RendererSceneRenderRD::environment_get_reflection_source(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_DISABLED); - return env->reflection_source; -} - -void RendererSceneRenderRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->set_tonemap(p_tone_mapper, p_exposure, p_white, p_auto_exposure, p_min_luminance, p_max_luminance, p_auto_exp_speed, p_auto_exp_scale); -} - -void RendererSceneRenderRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->set_glow(p_enable, p_levels, p_intensity, p_strength, p_mix, p_bloom_threshold, p_blend_mode, p_hdr_bleed_threshold, p_hdr_bleed_scale, p_hdr_luminance_cap, p_glow_map_strength, p_glow_map); -} - void RendererSceneRenderRD::environment_glow_set_use_bicubic_upscale(bool p_enable) { glow_bicubic_upscale = p_enable; } @@ -306,79 +166,6 @@ void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable) glow_high_quality = p_enable; } -void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - if (!is_dynamic_gi_supported()) { - return; - } - - env->set_sdfgi(p_enable, p_cascades, p_min_cell_size, p_y_scale, p_use_occlusion, p_bounce_feedback, p_read_sky, p_energy, p_normal_bias, p_probe_bias); -} - -void RendererSceneRenderRD::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - env->set_fog(p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_fog_aerial_perspective); -} - -bool RendererSceneRenderRD::environment_is_fog_enabled(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, false); - - return env->fog_enabled; -} -Color RendererSceneRenderRD::environment_get_fog_light_color(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Color()); - return env->fog_light_color; -} -float RendererSceneRenderRD::environment_get_fog_light_energy(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->fog_light_energy; -} -float RendererSceneRenderRD::environment_get_fog_sun_scatter(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->fog_sun_scatter; -} -float RendererSceneRenderRD::environment_get_fog_density(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->fog_density; -} -float RendererSceneRenderRD::environment_get_fog_height(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - - return env->fog_height; -} -float RendererSceneRenderRD::environment_get_fog_height_density(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->fog_height_density; -} - -float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->fog_aerial_perspective; -} - -void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - if (!is_volumetric_supported()) { - return; - } - - env->set_volumetric_fog(p_enable, p_density, p_albedo, p_emission, p_emission_energy, p_anisotropy, p_length, p_detail_spread, p_gi_inject, p_temporal_reprojection, p_temporal_reprojection_amount, p_ambient_inject); -} - void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) { volumetric_fog_size = p_size; volumetric_fog_depth = p_depth; @@ -399,13 +186,6 @@ void RendererSceneRenderRD::environment_set_sdfgi_frames_to_update_light(RS::Env gi.sdfgi_frames_to_update_light = p_update; } -void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - env->set_ssr(p_enable, p_max_steps, p_fade_int, p_fade_out, p_depth_tolerance); -} - void RendererSceneRenderRD::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) { ssr_roughness_quality = p_quality; } @@ -414,13 +194,6 @@ RS::EnvironmentSSRRoughnessQuality RendererSceneRenderRD::environment_get_ssr_ro return ssr_roughness_quality; } -void RendererSceneRenderRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - env->set_ssao(p_enable, p_radius, p_intensity, p_power, p_detail, p_horizon, p_sharpness, p_light_affect, p_ao_channel_affect); -} - void RendererSceneRenderRD::environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) { ssao_quality = p_quality; ssao_half_size = p_half_size; @@ -430,17 +203,6 @@ void RendererSceneRenderRD::environment_set_ssao_quality(RS::EnvironmentSSAOQual ssao_fadeout_to = p_fadeout_to; } -void RendererSceneRenderRD::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - env->ssil_enabled = p_enable; - env->ssil_radius = p_radius; - env->ssil_intensity = p_intensity; - env->ssil_sharpness = p_sharpness; - env->ssil_normal_rejection = p_normal_rejection; -} - void RendererSceneRenderRD::environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) { ssil_quality = p_quality; ssil_half_size = p_half_size; @@ -450,56 +212,16 @@ void RendererSceneRenderRD::environment_set_ssil_quality(RS::EnvironmentSSILQual ssil_fadeout_to = p_fadeout_to; } -bool RendererSceneRenderRD::environment_is_ssao_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, false); - return env->ssao_enabled; -} - -float RendererSceneRenderRD::environment_get_ssao_ao_affect(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0.0); - return env->ssao_ao_channel_affect; -} - -float RendererSceneRenderRD::environment_get_ssao_light_affect(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0.0); - return env->ssao_direct_light_affect; -} - -bool RendererSceneRenderRD::environment_is_ssil_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, false); - return env->ssil_enabled; -} - -bool RendererSceneRenderRD::environment_is_ssr_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, false); - return env->ssr_enabled; -} -bool RendererSceneRenderRD::environment_is_sdfgi_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, false); - return env->sdfgi_enabled; -} - -bool RendererSceneRenderRD::is_environment(RID p_env) const { - return environment_owner.owns(p_env); -} - Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Ref<Image>()); + ERR_FAIL_COND_V(p_env.is_null(), Ref<Image>()); - RS::EnvironmentBG environment_background = env->background; + RS::EnvironmentBG environment_background = environment_get_background(p_env); if (environment_background == RS::ENV_BG_CAMERA_FEED || environment_background == RS::ENV_BG_CANVAS || environment_background == RS::ENV_BG_KEEP) { return Ref<Image>(); //nothing to bake } - RS::EnvironmentAmbientSource ambient_source = env->ambient_source; + RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(p_env); bool use_ambient_light = false; bool use_cube_map = false; @@ -509,14 +231,14 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba use_cube_map = (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && environment_background == RS::ENV_BG_SKY) || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY; use_ambient_light = use_cube_map || ambient_source == RS::ENV_AMBIENT_SOURCE_COLOR; } - use_cube_map = use_cube_map || (environment_background == RS::ENV_BG_SKY && env->sky.is_valid()); + use_cube_map = use_cube_map || (environment_background == RS::ENV_BG_SKY && environment_get_sky(p_env).is_valid()); Color ambient_color; - float ambient_color_sky_mix; + float ambient_color_sky_mix = 0.0; if (use_ambient_light) { - ambient_color_sky_mix = env->ambient_sky_contribution; - const float ambient_energy = env->ambient_light_energy; - ambient_color = env->ambient_light; + ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_env); + const float ambient_energy = environment_get_ambient_light_energy(p_env); + ambient_color = environment_get_ambient_light(p_env); ambient_color = ambient_color.srgb_to_linear(); ambient_color.r *= ambient_energy; ambient_color.g *= ambient_energy; @@ -524,7 +246,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba } if (use_cube_map) { - Ref<Image> panorama = sky_bake_panorama(env->sky, env->bg_energy, p_bake_irradiance, p_size); + Ref<Image> panorama = sky_bake_panorama(environment_get_sky(p_env), environment_get_bg_energy(p_env), p_bake_irradiance, p_size); if (use_ambient_light) { for (int x = 0; x < p_size.width; x++) { for (int y = 0; y < p_size.height; y++) { @@ -534,8 +256,8 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba } return panorama; } else { - const float bg_energy = env->bg_energy; - Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? RSG::texture_storage->get_default_clear_color() : env->bg_color); + const float bg_energy = environment_get_bg_energy(p_env); + Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? RSG::texture_storage->get_default_clear_color() : environment_get_bg_color(p_env)); panorama_color = panorama_color.srgb_to_linear(); panorama_color.r *= bg_energy; panorama_color.g *= bg_energy; @@ -1525,7 +1247,7 @@ bool RendererSceneRenderRD::voxel_gi_needs_update(RID p_probe) const { return gi.voxel_gi_needs_update(p_probe); } -void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) { +void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) { if (!is_dynamic_gi_supported()) { return; } @@ -1944,10 +1666,9 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb return; } - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); - ERR_FAIL_COND(!env); + ERR_FAIL_COND(p_environment.is_null()); - ERR_FAIL_COND(!env->ssr_enabled); + ERR_FAIL_COND(!environment_get_ssr_enabled(p_environment)); Size2i half_size = Size2i(rb->internal_width / 2, rb->internal_height / 2); if (rb->ssr.output.is_null()) { @@ -1959,7 +1680,7 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb texture_slices[v] = rb->views[v].view_texture; depth_slices[v] = rb->views[v].view_depth; } - ss_effects->screen_space_reflection(rb->ssr, texture_slices, p_normal_slices, ssr_roughness_quality, p_metallic_slices, p_metallic_mask, depth_slices, half_size, env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, rb->view_count, p_projections, p_eye_offsets); + ss_effects->screen_space_reflection(rb->ssr, texture_slices, p_normal_slices, ssr_roughness_quality, p_metallic_slices, p_metallic_mask, depth_slices, half_size, environment_get_ssr_max_steps(p_environment), environment_get_ssr_fade_in(p_environment), environment_get_ssr_fade_out(p_environment), environment_get_ssr_depth_tolerance(p_environment), rb->view_count, p_projections, p_eye_offsets); copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->ssr.output, rb->view_count); } @@ -1969,18 +1690,17 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); - ERR_FAIL_COND(!env); + ERR_FAIL_COND(p_environment.is_null()); RENDER_TIMESTAMP("Process SSAO"); RendererRD::SSEffects::SSAOSettings settings; - settings.radius = env->ssao_radius; - settings.intensity = env->ssao_intensity; - settings.power = env->ssao_power; - settings.detail = env->ssao_detail; - settings.horizon = env->ssao_horizon; - settings.sharpness = env->ssao_sharpness; + settings.radius = environment_get_ssao_radius(p_environment); + settings.intensity = environment_get_ssao_intensity(p_environment); + settings.power = environment_get_ssao_power(p_environment); + settings.detail = environment_get_ssao_detail(p_environment); + settings.horizon = environment_get_ssao_horizon(p_environment); + settings.sharpness = environment_get_ssao_sharpness(p_environment); settings.quality = ssao_quality; settings.half_size = ssao_half_size; @@ -2000,16 +1720,15 @@ void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environmen RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); - ERR_FAIL_COND(!env); + ERR_FAIL_COND(p_environment.is_null()); RENDER_TIMESTAMP("Process SSIL"); RendererRD::SSEffects::SSILSettings settings; - settings.radius = env->ssil_radius; - settings.intensity = env->ssil_intensity; - settings.sharpness = env->ssil_sharpness; - settings.normal_rejection = env->ssil_normal_rejection; + settings.radius = environment_get_ssil_radius(p_environment); + settings.intensity = environment_get_ssil_intensity(p_environment); + settings.sharpness = environment_get_ssil_sharpness(p_environment); + settings.normal_rejection = environment_get_ssil_normal_rejection(p_environment); settings.quality = ssil_quality; settings.half_size = ssil_half_size; @@ -2141,7 +1860,6 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); // Glow and override exposure (if enabled). CameraEffects *camfx = camera_effects_owner.get_or_null(p_render_data->camera_effects); @@ -2201,21 +1919,21 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende RD::get_singleton()->draw_command_end_label(); } - if (can_use_effects && env && env->auto_exposure) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_auto_exposure(p_render_data->environment)) { RENDER_TIMESTAMP("Auto exposure"); RD::get_singleton()->draw_command_begin_label("Auto exposure"); if (rb->luminance.current.is_null()) { _allocate_luminance_textures(rb); } - bool set_immediate = env->auto_exposure_version != rb->auto_exposure_version; - rb->auto_exposure_version = env->auto_exposure_version; + bool set_immediate = environment_get_auto_exposure_version(p_render_data->environment) != rb->auto_exposure_version; + rb->auto_exposure_version = environment_get_auto_exposure_version(p_render_data->environment); - double step = env->auto_exp_speed * time_step; + double step = environment_get_auto_exp_speed(p_render_data->environment) * time_step; if (can_use_storage) { - RendererCompositorRD::singleton->get_effects()->luminance_reduction(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); + RendererCompositorRD::singleton->get_effects()->luminance_reduction(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.current, environment_get_min_luminance(p_render_data->environment), environment_get_max_luminance(p_render_data->environment), step, set_immediate); } else { - RendererCompositorRD::singleton->get_effects()->luminance_reduction_raster(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); + RendererCompositorRD::singleton->get_effects()->luminance_reduction_raster(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, environment_get_min_luminance(p_render_data->environment), environment_get_max_luminance(p_render_data->environment), step, set_immediate); } // Swap final reduce with prev luminance. SWAP(rb->luminance.current, rb->luminance.reduce.write[rb->luminance.reduce.size() - 1]); @@ -2229,7 +1947,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende int max_glow_level = -1; - if (can_use_effects && env && env->glow_enabled) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_glow_enabled(p_render_data->environment)) { RENDER_TIMESTAMP("Glow"); RD::get_singleton()->draw_command_begin_label("Gaussian Glow"); @@ -2240,7 +1958,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende } for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { - if (env->glow_levels[i] > 0.0) { + if (environment_get_glow_levels(p_render_data->environment)[i] > 0.0) { if (i >= rb->blur[1].layers[0].mipmaps.size()) { max_glow_level = rb->blur[1].layers[0].mipmaps.size() - 1; } else { @@ -2257,19 +1975,19 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende if (i == 0) { RID luminance_texture; - if (env->auto_exposure && rb->luminance.current.is_valid()) { + if (environment_get_auto_exposure(p_render_data->environment) && rb->luminance.current.is_valid()) { luminance_texture = rb->luminance.current; } if (can_use_storage) { - copy_effects->gaussian_glow(rb->views[l].view_texture, rb->blur[1].layers[l].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + copy_effects->gaussian_glow(rb->views[l].view_texture, rb->blur[1].layers[l].mipmaps[i].texture, Size2i(vp_w, vp_h), environment_get_glow_strength(p_render_data->environment), glow_high_quality, true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, environment_get_auto_exp_scale(p_render_data->environment)); } else { - copy_effects->gaussian_glow_raster(rb->views[l].view_texture, luminance_multiplier, rb->blur[1].layers[l].mipmaps[i].half_fb, rb->blur[1].layers[l].mipmaps[i].half_texture, rb->blur[1].layers[l].mipmaps[i].fb, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + copy_effects->gaussian_glow_raster(rb->views[l].view_texture, luminance_multiplier, rb->blur[1].layers[l].mipmaps[i].half_fb, rb->blur[1].layers[l].mipmaps[i].half_texture, rb->blur[1].layers[l].mipmaps[i].fb, Size2i(vp_w, vp_h), environment_get_glow_strength(p_render_data->environment), glow_high_quality, true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, environment_get_auto_exp_scale(p_render_data->environment)); } } else { if (can_use_storage) { - copy_effects->gaussian_glow(rb->blur[1].layers[l].mipmaps[i - 1].texture, rb->blur[1].layers[l].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); + copy_effects->gaussian_glow(rb->blur[1].layers[l].mipmaps[i - 1].texture, rb->blur[1].layers[l].mipmaps[i].texture, Size2i(vp_w, vp_h), environment_get_glow_strength(p_render_data->environment), glow_high_quality); } else { - copy_effects->gaussian_glow_raster(rb->blur[1].layers[l].mipmaps[i - 1].texture, luminance_multiplier, rb->blur[1].layers[l].mipmaps[i].half_fb, rb->blur[1].layers[l].mipmaps[i].half_texture, rb->blur[1].layers[l].mipmaps[i].fb, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); + copy_effects->gaussian_glow_raster(rb->blur[1].layers[l].mipmaps[i - 1].texture, luminance_multiplier, rb->blur[1].layers[l].mipmaps[i].half_fb, rb->blur[1].layers[l].mipmaps[i].half_texture, rb->blur[1].layers[l].mipmaps[i].fb, Size2i(vp_w, vp_h), environment_get_glow_strength(p_render_data->environment), glow_high_quality); } } } @@ -2284,36 +2002,36 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende RendererRD::ToneMapper::TonemapSettings tonemap; - if (can_use_effects && env && env->auto_exposure && rb->luminance.current.is_valid()) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_auto_exposure(p_render_data->environment) && rb->luminance.current.is_valid()) { tonemap.use_auto_exposure = true; tonemap.exposure_texture = rb->luminance.current; - tonemap.auto_exposure_grey = env->auto_exp_scale; + tonemap.auto_exposure_grey = environment_get_auto_exp_scale(p_render_data->environment); } else { - tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); } - if (can_use_effects && env && env->glow_enabled) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_glow_enabled(p_render_data->environment)) { tonemap.use_glow = true; - tonemap.glow_mode = RendererRD::ToneMapper::TonemapSettings::GlowMode(env->glow_blend_mode); - tonemap.glow_intensity = env->glow_blend_mode == RS::ENV_GLOW_BLEND_MODE_MIX ? env->glow_mix : env->glow_intensity; + tonemap.glow_mode = RendererRD::ToneMapper::TonemapSettings::GlowMode(environment_get_glow_blend_mode(p_render_data->environment)); + tonemap.glow_intensity = environment_get_glow_blend_mode(p_render_data->environment) == RS::ENV_GLOW_BLEND_MODE_MIX ? environment_get_glow_mix(p_render_data->environment) : environment_get_glow_intensity(p_render_data->environment); for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { - tonemap.glow_levels[i] = env->glow_levels[i]; + tonemap.glow_levels[i] = environment_get_glow_levels(p_render_data->environment)[i]; } tonemap.glow_texture_size.x = rb->blur[1].layers[0].mipmaps[0].width; tonemap.glow_texture_size.y = rb->blur[1].layers[0].mipmaps[0].height; tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale; tonemap.glow_texture = rb->blur[1].texture; - if (env->glow_map.is_valid()) { - tonemap.glow_map_strength = env->glow_map_strength; - tonemap.glow_map = texture_storage->texture_get_rd_texture(env->glow_map); + if (environment_get_glow_map(p_render_data->environment).is_valid()) { + tonemap.glow_map_strength = environment_get_glow_map_strength(p_render_data->environment); + tonemap.glow_map = texture_storage->texture_get_rd_texture(environment_get_glow_map(p_render_data->environment)); } else { tonemap.glow_map_strength = 0.0f; - tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); } } else { - tonemap.glow_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); - tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.glow_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); + tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); } if (rb->screen_space_aa == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) { @@ -2323,10 +2041,10 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende tonemap.use_debanding = rb->use_debanding; tonemap.texture_size = Vector2i(rb->internal_width, rb->internal_height); - if (env) { - tonemap.tonemap_mode = env->tone_mapper; - tonemap.white = env->white; - tonemap.exposure = env->exposure; + if (p_render_data->environment.is_valid()) { + tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment); + tonemap.white = environment_get_white(p_render_data->environment); + tonemap.exposure = environment_get_exposure(p_render_data->environment); } if (camfx && camfx->override_exposure_enabled) { @@ -2335,17 +2053,17 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende tonemap.use_color_correction = false; tonemap.use_1d_color_correction = false; - tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); - - if (can_use_effects && env) { - tonemap.use_bcs = env->adjustments_enabled; - tonemap.brightness = env->adjustments_brightness; - tonemap.contrast = env->adjustments_contrast; - tonemap.saturation = env->adjustments_saturation; - if (env->adjustments_enabled && env->color_correction.is_valid()) { + tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); + + if (can_use_effects && p_render_data->environment.is_valid()) { + tonemap.use_bcs = environment_get_adjustments_enabled(p_render_data->environment); + tonemap.brightness = environment_get_adjustments_brightness(p_render_data->environment); + tonemap.contrast = environment_get_adjustments_contrast(p_render_data->environment); + tonemap.saturation = environment_get_adjustments_saturation(p_render_data->environment); + if (environment_get_adjustments_enabled(p_render_data->environment) && environment_get_color_correction(p_render_data->environment).is_valid()) { tonemap.use_color_correction = true; - tonemap.use_1d_color_correction = env->use_1d_color_correction; - tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(env->color_correction); + tonemap.use_1d_color_correction = environment_get_use_1d_color_correction(p_render_data->environment); + tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(environment_get_color_correction(p_render_data->environment)); } } @@ -2375,7 +2093,6 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); // Override exposure (if enabled). CameraEffects *camfx = camera_effects_owner.get_or_null(p_render_data->camera_effects); @@ -2385,10 +2102,10 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr RendererRD::ToneMapper::TonemapSettings tonemap; - if (env) { - tonemap.tonemap_mode = env->tone_mapper; - tonemap.exposure = env->exposure; - tonemap.white = env->white; + if (p_render_data->environment.is_valid()) { + tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment); + tonemap.exposure = environment_get_exposure(p_render_data->environment); + tonemap.white = environment_get_white(p_render_data->environment); } if (camfx && camfx->override_exposure_enabled) { @@ -2398,32 +2115,32 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr // We don't support glow or auto exposure here, if they are needed, don't use subpasses! // The problem is that we need to use the result so far and process them before we can // apply this to our results. - if (can_use_effects && env && env->glow_enabled) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_glow_enabled(p_render_data->environment)) { ERR_FAIL_MSG("Glow is not supported when using subpasses."); } - if (can_use_effects && env && env->auto_exposure) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_auto_exposure(p_render_data->environment)) { ERR_FAIL_MSG("Glow is not supported when using subpasses."); } tonemap.use_glow = false; - tonemap.glow_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); - tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.glow_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); + tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); tonemap.use_auto_exposure = false; - tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); tonemap.use_color_correction = false; tonemap.use_1d_color_correction = false; - tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); - - if (can_use_effects && env) { - tonemap.use_bcs = env->adjustments_enabled; - tonemap.brightness = env->adjustments_brightness; - tonemap.contrast = env->adjustments_contrast; - tonemap.saturation = env->adjustments_saturation; - if (env->adjustments_enabled && env->color_correction.is_valid()) { + tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); + + if (can_use_effects && p_render_data->environment.is_valid()) { + tonemap.use_bcs = environment_get_adjustments_enabled(p_render_data->environment); + tonemap.brightness = environment_get_adjustments_brightness(p_render_data->environment); + tonemap.contrast = environment_get_adjustments_contrast(p_render_data->environment); + tonemap.saturation = environment_get_adjustments_saturation(p_render_data->environment); + if (environment_get_adjustments_enabled(p_render_data->environment) && environment_get_color_correction(p_render_data->environment).is_valid()) { tonemap.use_color_correction = true; - tonemap.use_1d_color_correction = env->use_1d_color_correction; - tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(env->color_correction); + tonemap.use_1d_color_correction = environment_get_use_1d_color_correction(p_render_data->environment); + tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(environment_get_color_correction(p_render_data->environment)); } } @@ -2457,7 +2174,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID RID shadow_atlas_texture = shadow_atlas_get_texture(p_shadow_atlas); if (shadow_atlas_texture.is_null()) { - shadow_atlas_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + shadow_atlas_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); } Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); @@ -2527,18 +2244,6 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID } } -void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - env->adjustments_enabled = p_enable; - env->adjustments_brightness = p_brightness; - env->adjustments_contrast = p_contrast; - env->adjustments_saturation = p_saturation; - env->use_1d_color_correction = p_use_1d_color_correction; - env->color_correction = p_color_correction; -} - RID RendererSceneRenderRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); @@ -2743,7 +2448,7 @@ bool RendererSceneRenderRD::_render_buffers_can_be_storage() { return true; } -void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { +void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -2754,11 +2459,9 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p p_internal_width = p_width; } - if (p_width != p_internal_width) { - float fsr_mipmap_bias = -log2f(p_width / p_internal_width) + p_fsr_mipmap_bias; - material_storage->sampler_rd_configure_custom(fsr_mipmap_bias); - update_uniform_sets(); - } + const float texture_mipmap_bias = -log2f(p_width / p_internal_width) + p_texture_mipmap_bias; + material_storage->sampler_rd_configure_custom(texture_mipmap_bias); + update_uniform_sets(); RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); @@ -3166,7 +2869,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const WARN_PRINT_ONCE("The DirectionalLight3D PSSM splits debug draw mode is not reimplemented yet."); } - light_data.shadow_enabled = p_using_shadows && light_storage->light_has_shadow(base); + light_data.shadow_opacity = p_using_shadows && light_storage->light_has_shadow(base) ? light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_OPACITY) : 0.0; float angular_diameter = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); if (angular_diameter > 0.0) { @@ -3183,7 +2886,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const angular_diameter = 0.0; } - if (light_data.shadow_enabled) { + if (light_data.shadow_opacity > 0.001) { RS::LightDirectionalShadowMode smode = light_storage->light_directional_get_shadow_mode(base); int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3); @@ -3337,19 +3040,26 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const // Reuse fade begin, fade length and distance for shadow LOD determination later. float fade_begin = 0.0; + float fade_shadow = 0.0; float fade_length = 0.0; real_t distance = 0.0; float fade = 1.0; + float shadow_opacity_fade = 1.0; if (light_storage->light_is_distance_fade_enabled(li->light)) { fade_begin = light_storage->light_get_distance_fade_begin(li->light); + fade_shadow = light_storage->light_get_distance_fade_shadow(li->light); fade_length = light_storage->light_get_distance_fade_length(li->light); distance = camera_plane.distance_to(li->transform.origin); + // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player. if (distance > fade_begin) { - // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player. fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length); } + + if (distance > fade_shadow) { + shadow_opacity_fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_shadow) / fade_length); + } } float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI * fade; @@ -3417,7 +3127,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const bool in_shadow_range = true; if (needs_shadow && light_storage->light_is_distance_fade_enabled(li->light)) { - if (distance > light_storage->light_get_distance_fade_shadow(li->light)) { + if (distance > light_storage->light_get_distance_fade_shadow(li->light) + light_storage->light_get_distance_fade_length(li->light)) { // Out of range, don't draw shadows to improve performance. in_shadow_range = false; } @@ -3426,7 +3136,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const if (needs_shadow && in_shadow_range) { // fill in the shadow information - light_data.shadow_enabled = true; + light_data.shadow_opacity = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_OPACITY) * shadow_opacity_fade; float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas); light_data.shadow_normal_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0; @@ -3486,7 +3196,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const } } } else { - light_data.shadow_enabled = false; + light_data.shadow_opacity = 0.0; } li->cull_mask = light_storage->light_get_cull_mask(base); @@ -3692,7 +3402,6 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e ERR_FAIL_COND(!is_clustered_enabled()); // can't use volumetric fog without clustered RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); float ratio = float(rb->width) / float((rb->width + rb->height) / 2); uint32_t target_width = uint32_t(float(volumetric_fog_size) * ratio); @@ -3700,18 +3409,18 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e if (rb->volumetric_fog) { //validate - if (!env || !env->volumetric_fog_enabled || rb->volumetric_fog->width != target_width || rb->volumetric_fog->height != target_height || rb->volumetric_fog->depth != volumetric_fog_depth) { + if (p_environment.is_null() || !environment_get_volumetric_fog_enabled(p_environment) || rb->volumetric_fog->width != target_width || rb->volumetric_fog->height != target_height || rb->volumetric_fog->depth != volumetric_fog_depth) { memdelete(rb->volumetric_fog); rb->volumetric_fog = nullptr; } } - if (!env || !env->volumetric_fog_enabled) { + if (p_environment.is_null() || !environment_get_volumetric_fog_enabled(p_environment)) { //no reason to enable or update, bye return; } - if (env && env->volumetric_fog_enabled && !rb->volumetric_fog) { + if (p_environment.is_valid() && environment_get_volumetric_fog_enabled(p_environment) && !rb->volumetric_fog) { //required volumetric fog but not existing, create rb->volumetric_fog = memnew(RendererRD::Fog::VolumetricFog(Vector3i(target_width, target_height, volumetric_fog_depth), sky.sky_shader.default_shader_rd)); } @@ -3737,7 +3446,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e settings.cluster_builder = rb->cluster_builder; settings.rbgi = &rb->rbgi; settings.sdfgi = rb->sdfgi; - settings.env = env; + settings.env = p_environment; settings.sky = &sky; settings.gi = &gi; @@ -3764,8 +3473,7 @@ void RendererSceneRenderRD::_post_prepass_render(RenderDataRD *p_render_data, bo return; } - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); - rb->sdfgi->update_probes(env, sky.sky_owner.get_or_null(env->sky)); + rb->sdfgi->update_probes(p_render_data->environment, sky.sky_owner.get_or_null(environment_get_sky(p_render_data->environment))); } } } @@ -3936,7 +3644,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool if (p_render_data->render_buffers.is_valid()) { bool directional_shadows = false; for (uint32_t i = 0; i < directional_light_count; i++) { - if (cluster.directional_lights[i].shadow_enabled) { + if (cluster.directional_lights[i].shadow_opacity > 0.001) { directional_shadows = true; break; } @@ -3947,7 +3655,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool } } -void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { +void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); // getting this here now so we can direct call a bunch of things more easily @@ -4142,7 +3850,7 @@ void RendererSceneRenderRD::_debug_draw_cluster(RID p_render_buffers) { } } -void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) { +void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) { LightInstance *light_instance = light_instance_owner.get_or_null(p_light); ERR_FAIL_COND(!light_instance); @@ -4314,11 +4022,11 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } } -void RendererSceneRenderRD::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RendererSceneRenderRD::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { _render_material(p_cam_transform, p_cam_projection, p_cam_orthogonal, p_instances, p_framebuffer, p_region); } -void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) { +void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) { RendererRD::ParticlesStorage *particles_storage = RendererRD::ParticlesStorage::get_singleton(); ERR_FAIL_COND(!particles_storage->particles_collision_is_heightfield(p_collider)); @@ -4355,9 +4063,8 @@ bool RendererSceneRenderRD::free(RID p_rid) { memdelete(rb->cluster_builder); } render_buffers_owner.free(p_rid); - } else if (environment_owner.owns(p_rid)) { - //not much to delete, just free it - environment_owner.free(p_rid); + } else if (is_environment(p_rid)) { + environment_free(p_rid); } else if (camera_effects_owner.owns(p_rid)) { //not much to delete, just free it camera_effects_owner.free(p_rid); @@ -4497,7 +4204,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto //RID sampled_light; - GeometryInstance *gi = geometry_instance_create(p_base); + RenderGeometryInstance *gi = geometry_instance_create(p_base); uint32_t sc = RSG::mesh_storage->mesh_get_surface_count(p_base); Vector<RID> materials; @@ -4509,7 +4216,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto } } - geometry_instance_set_surface_materials(gi, materials); + gi->set_surface_materials(materials); if (cull_argument.size() == 0) { cull_argument.push_back(nullptr); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index cd56b8efb3..22e9ead243 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -43,7 +43,6 @@ #include "servers/rendering/renderer_rd/environment/fog.h" #include "servers/rendering/renderer_rd/environment/gi.h" #include "servers/rendering/renderer_rd/environment/sky.h" -#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" #include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" @@ -69,7 +68,7 @@ struct RenderDataRD { float z_near = 0.0; float z_far = 0.0; - const PagedArray<RendererSceneRender::GeometryInstance *> *instances = nullptr; + const PagedArray<RenderGeometryInstance *> *instances = nullptr; const PagedArray<RID> *lights = nullptr; const PagedArray<RID> *reflection_probes = nullptr; const PagedArray<RID> *voxel_gi_instances = nullptr; @@ -122,14 +121,14 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 0; virtual void _render_shadow_begin() = 0; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) = 0; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) = 0; virtual void _render_shadow_process() = 0; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0; - virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) = 0; void _debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void _debug_draw_cluster(RID p_render_buffers); @@ -161,21 +160,13 @@ protected: void _disable_clear_request(const RenderDataRD *p_render_data); // needed for a single argument calls (material and uv2) - PagedArrayPool<GeometryInstance *> cull_argument_pool; - PagedArray<GeometryInstance *> cull_argument; //need this to exist + PagedArrayPool<RenderGeometryInstance *> cull_argument_pool; + PagedArray<RenderGeometryInstance *> cull_argument; //need this to exist RendererRD::SSEffects *ss_effects = nullptr; RendererRD::GI gi; RendererRD::SkyRD sky; - RendererSceneEnvironmentRD *get_environment(RID p_environment) { - if (p_environment.is_valid()) { - return environment_owner.get_or_null(p_environment); - } else { - return nullptr; - } - }; - //used for mobile renderer mostly typedef int32_t ForwardID; @@ -427,8 +418,6 @@ private: bool glow_high_quality = false; RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGHNESS_QUALITY_LOW; - mutable RID_Owner<RendererSceneEnvironmentRD, true> environment_owner; - /* CAMERA EFFECTS */ struct CameraEffects { @@ -619,7 +608,7 @@ private: float inv_spot_attenuation; float cos_spot_angle; float specular_amount; - uint32_t shadow_enabled; + float shadow_opacity; float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv float shadow_matrix[16]; @@ -644,7 +633,7 @@ private: float softshadow_angle; float soft_shadow_scale; uint32_t blend_splits; - uint32_t shadow_enabled; + float shadow_opacity; float fade_from; float fade_to; uint32_t pad[2]; @@ -750,7 +739,7 @@ private: uint32_t max_cluster_elements = 512; - void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr); + void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr); /* Volumetric Fog */ @@ -761,8 +750,7 @@ private: void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); public: - virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) = 0; - virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0; + static RendererSceneRenderRD *get_singleton() { return singleton; } /* GI */ @@ -824,65 +812,16 @@ public: /* ENVIRONMENT API */ - virtual RID environment_allocate() override; - virtual void environment_initialize(RID p_rid) override; - - virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override; - virtual void environment_set_sky(RID p_env, RID p_sky) override; - virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) override; - virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override; - virtual void environment_set_bg_color(RID p_env, const Color &p_color) override; - virtual void environment_set_bg_energy(RID p_env, float p_energy) override; - virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override; - virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override; - - virtual RS::EnvironmentBG environment_get_background(RID p_env) const override; - RID environment_get_sky(RID p_env) const; - float environment_get_sky_custom_fov(RID p_env) const; - Basis environment_get_sky_orientation(RID p_env) const; - Color environment_get_bg_color(RID p_env) const; - float environment_get_bg_energy(RID p_env) const; - virtual int environment_get_canvas_max_layer(RID p_env) const override; - Color environment_get_ambient_light_color(RID p_env) const; - RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const; - float environment_get_ambient_light_energy(RID p_env) const; - float environment_get_ambient_sky_contribution(RID p_env) const; - RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const; - - virtual bool is_environment(RID p_env) const override; - - virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override; virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) override; virtual void environment_glow_set_use_high_quality(bool p_enable) override; - virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override; - bool environment_is_fog_enabled(RID p_env) const; - Color environment_get_fog_light_color(RID p_env) const; - float environment_get_fog_light_energy(RID p_env) const; - float environment_get_fog_sun_scatter(RID p_env) const; - float environment_get_fog_density(RID p_env) const; - float environment_get_fog_height(RID p_env) const; - float environment_get_fog_height_density(RID p_env) const; - float environment_get_fog_aerial_perspective(RID p_env) const; - - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) override; - virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) override; - virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) override; - virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) override; virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override; - virtual void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override; + virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override; - bool environment_is_ssao_enabled(RID p_env) const; - float environment_get_ssao_ao_affect(RID p_env) const; - float environment_get_ssao_light_affect(RID p_env) const; - bool environment_is_ssil_enabled(RID p_env) const; - bool environment_is_ssr_enabled(RID p_env) const; - bool environment_is_sdfgi_enabled(RID p_env) const; - - virtual void environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override; + virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override; virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override; virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override; @@ -890,9 +829,6 @@ public: virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override; RS::EnvironmentSSRRoughnessQuality environment_get_ssr_roughness_quality() const; - virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override; - virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override; - virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override; /* CAMERA EFFECTS */ @@ -1160,7 +1096,7 @@ public: virtual RID voxel_gi_instance_create(RID p_base) override; virtual void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override; virtual bool voxel_gi_needs_update(RID p_probe) const override; - virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override; + virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) override; virtual void voxel_gi_set_quality(RS::VoxelGIQuality p_quality) override { gi.voxel_gi_quality = p_quality; } /* render buffers */ @@ -1169,7 +1105,7 @@ public: virtual RD::DataFormat _render_buffers_get_color_format(); virtual bool _render_buffers_can_be_storage(); virtual RID render_buffers_create() override; - virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; virtual void gi_set_use_half_resolution(bool p_enable) override; RID render_buffers_get_depth_texture(RID p_render_buffers); @@ -1203,11 +1139,11 @@ public: virtual void update_uniform_sets(){}; - virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; + virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; - virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override; virtual void set_scene_pass(uint64_t p_pass) override { scene_pass = p_pass; diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl index 12f57b0178..2ea6965c09 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl @@ -138,10 +138,10 @@ layout(set = 0, binding = 7) uniform texture2D sdf_texture; layout(set = 0, binding = 8) uniform sampler material_samplers[12]; -layout(set = 0, binding = 9, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 9, std430) restrict readonly buffer GlobalShaderUniformData { vec4 data[]; } -global_variables; +global_shader_uniforms; /* SET1: Is reserved for the material */ diff --git a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl index d85ab3af2e..246ef81cb2 100644 --- a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl @@ -182,17 +182,18 @@ void main() { if (found) { float margin_blend = 1.0; - vec2 margin = vec2((params.screen_size.x + params.screen_size.y) * 0.5 * 0.05); // make a uniform margin - if (any(bvec4(lessThan(pos, -margin), greaterThan(pos, params.screen_size + margin)))) { - // clip outside screen + margin + vec2 margin = vec2((params.screen_size.x + params.screen_size.y) * 0.05); // make a uniform margin + if (any(bvec4(lessThan(pos, vec2(0.0, 0.0)), greaterThan(pos, params.screen_size)))) { + // clip at the screen edges imageStore(ssr_image, ssC, vec4(0.0)); return; } { - //blend fading out towards external margin - vec2 margin_grad = mix(pos - params.screen_size, -pos, lessThan(pos, vec2(0.0))); - margin_blend = 1.0 - smoothstep(0.0, margin.x, max(margin_grad.x, margin_grad.y)); + //blend fading out towards inner margin + // 0.5 = midpoint of reflection + vec2 margin_grad = mix(params.screen_size - pos, pos, lessThan(pos, params.screen_size * 0.5)); + margin_blend = smoothstep(0.0, margin.x * margin.y, margin_grad.x * margin_grad.y); //margin_blend = 1.0; } diff --git a/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl index af5f7d0a58..9640d30e78 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl @@ -37,16 +37,14 @@ layout(push_constant, std430) uniform Params { uint max_cascades; ivec2 screen_size; - bool use_occlusion; float y_mult; - int probe_axis_size; float z_near; - float reserved1; - float reserved2; - mat4 cam_transform; - mat4 inv_projection; + mat3x4 inv_projection; + // We pack these more tightly than mat3 and vec3, which will require some reconstruction trickery. + float cam_basis[3][3]; + float cam_origin[3]; } params; @@ -82,13 +80,21 @@ void main() { vec3 ray_pos; vec3 ray_dir; { - ray_pos = params.cam_transform[3].xyz; + ray_pos = vec3(params.cam_origin[0], params.cam_origin[1], params.cam_origin[2]); ray_dir.xy = ((vec2(screen_pos) / vec2(params.screen_size)) * 2.0 - 1.0); ray_dir.z = params.z_near; - ray_dir = (params.inv_projection * vec4(ray_dir, 1.0)).xyz; - ray_dir = normalize(mat3(params.cam_transform) * ray_dir); + ray_dir = (vec4(ray_dir, 1.0) * mat4(params.inv_projection)).xyz; + + mat3 cam_basis; + { + vec3 c0 = vec3(params.cam_basis[0][0], params.cam_basis[0][1], params.cam_basis[0][2]); + vec3 c1 = vec3(params.cam_basis[1][0], params.cam_basis[1][1], params.cam_basis[1][2]); + vec3 c2 = vec3(params.cam_basis[2][0], params.cam_basis[2][1], params.cam_basis[2][2]); + cam_basis = mat3(c0, c1, c2); + } + ray_dir = normalize(cam_basis * ray_dir); } ray_pos.y *= params.y_mult; diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index 5b4594da99..e825020a4e 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl @@ -77,10 +77,10 @@ params; layout(set = 0, binding = 0) uniform sampler material_samplers[12]; -layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalShaderUniformData { vec4 data[]; } -global_variables; +global_shader_uniforms; layout(set = 0, binding = 2, std140) uniform SceneData { bool volumetric_fog_enabled; diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl index fb3c725b1f..4658afd02d 100644 --- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl @@ -28,10 +28,10 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; layout(set = 0, binding = 1) uniform sampler material_samplers[12]; -layout(set = 0, binding = 2, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 2, std430) restrict readonly buffer GlobalShaderUniformData { vec4 data[]; } -global_variables; +global_shader_uniforms; layout(push_constant, std430) uniform Params { vec3 position; diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index e74cfad65c..6f79b9e771 100644 --- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -377,7 +377,7 @@ void main() { for (uint i = 0; i < params.directional_light_count; i++) { vec3 shadow_attenuation = vec3(1.0); - if (directional_lights.data[i].shadow_enabled) { + if (directional_lights.data[i].shadow_opacity > 0.001) { float depth_z = -view_pos.z; vec4 pssm_coord; @@ -486,7 +486,7 @@ void main() { vec3 light = omni_lights.data[light_index].color; - if (omni_lights.data[light_index].shadow_enabled) { + if (omni_lights.data[light_index].shadow_opacity > 0.001) { //has shadow vec4 uv_rect = omni_lights.data[light_index].atlas_rect; vec2 flip_offset = omni_lights.data[light_index].direction.xy; @@ -572,7 +572,7 @@ void main() { vec3 light = spot_lights.data[light_index].color; - if (spot_lights.data[light_index].shadow_enabled) { + if (spot_lights.data[light_index].shadow_opacity > 0.001) { //has shadow vec4 uv_rect = spot_lights.data[light_index].atlas_rect; vec2 flip_offset = spot_lights.data[light_index].direction.xy; diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl index 61c8488a05..799f7087b6 100644 --- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl @@ -15,7 +15,7 @@ struct LightData { //this structure needs to be as packed as possible mediump float cone_attenuation; mediump float cone_angle; mediump float specular_amount; - bool shadow_enabled; + mediump float shadow_opacity; highp vec4 atlas_rect; // rect in the shadow atlas highp mat4 shadow_matrix; @@ -60,7 +60,7 @@ struct DirectionalLightData { highp float softshadow_angle; highp float soft_shadow_scale; bool blend_splits; - bool shadow_enabled; + mediump float shadow_opacity; highp float fade_from; highp float fade_to; uvec2 pad; diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index acb62b812e..fb5759bc17 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -25,10 +25,10 @@ layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; layout(set = 0, binding = 1) uniform sampler material_samplers[12]; -layout(set = 0, binding = 2, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 2, std430) restrict readonly buffer GlobalShaderUniformData { vec4 data[]; } -global_variables; +global_shader_uniforms; /* Set 1: FRAME AND PARTICLE DATA */ @@ -458,11 +458,11 @@ void main() { } break; case ATTRACTOR_TYPE_VECTOR_FIELD: { - vec3 uvw_pos = (local_pos / FRAME.attractors[i].extents) * 2.0 - 1.0; + vec3 uvw_pos = (local_pos / FRAME.attractors[i].extents + 1.0) * 0.5; if (any(lessThan(uvw_pos, vec3(0.0))) || any(greaterThan(uvw_pos, vec3(1.0)))) { continue; } - vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz; + vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz * 2.0 - 1.0; dir = mat3(FRAME.attractors[i].transform) * safe_normalize(s); //revert direction amount = length(s); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 5947fc5351..e9515c7670 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -947,9 +947,9 @@ void fragment_shader(in SceneData scene_data) { if (decals.data[decal_index].emission_rect != vec4(0.0)) { //emission is additive, so its independent from albedo if (sc_decal_use_mipmaps) { - emission += textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade; + emission += textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].modulate.rgb * decals.data[decal_index].emission_energy * fade; } else { - emission += textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, 0.0).xyz * decals.data[decal_index].emission_energy * fade; + emission += textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, 0.0).xyz * decals.data[decal_index].modulate.rgb * decals.data[decal_index].emission_energy * fade; } } } @@ -988,8 +988,10 @@ void fragment_shader(in SceneData scene_data) { vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); vec3 ref_vec = reflect(-view, bent_normal); + ref_vec = mix(ref_vec, bent_normal, roughness * roughness); #else vec3 ref_vec = reflect(-view, normal); + ref_vec = mix(ref_vec, normal, roughness * roughness); #endif float horizon = min(1.0 + dot(ref_vec, normal), 1.0); @@ -1046,6 +1048,7 @@ void fragment_shader(in SceneData scene_data) { ambient_light *= attenuation; specular_light *= attenuation; + ref_vec = mix(ref_vec, n, clearcoat_roughness * clearcoat_roughness); float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD; @@ -1203,6 +1206,7 @@ void fragment_shader(in SceneData scene_data) { uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; vec3 ref_vec = normalize(reflect(-view, normal)); + ref_vec = mix(ref_vec, normal, roughness * roughness); //find arbitrary tangent and bitangent, then build a matrix 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)); @@ -1302,6 +1306,18 @@ void fragment_shader(in SceneData scene_data) { item_to = subgroupBroadcastFirst(subgroupMax(item_to)); #endif +#ifdef LIGHT_ANISOTROPY_USED + // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy + vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; + vec3 anisotropic_tangent = cross(anisotropic_direction, view); + vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); + vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); +#else + vec3 bent_normal = normal; +#endif + vec3 ref_vec = normalize(reflect(-view, bent_normal)); + ref_vec = mix(ref_vec, bent_normal, roughness * roughness); + for (uint i = item_from; i < item_to; i++) { uint mask = cluster_buffer.data[cluster_reflection_offset + i]; mask &= cluster_get_range_clip_mask(i, item_min, item_max); @@ -1324,16 +1340,8 @@ void fragment_shader(in SceneData scene_data) { if (!bool(reflections.data[reflection_index].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } -#ifdef LIGHT_ANISOTROPY_USED - // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy - vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; - vec3 anisotropic_tangent = cross(anisotropic_direction, view); - vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); - vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); -#else - vec3 bent_normal = normal; -#endif - reflection_process(reflection_index, view, vertex, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); + + reflection_process(reflection_index, vertex, ref_vec, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); } } @@ -1381,7 +1389,7 @@ void fragment_shader(in SceneData scene_data) { float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; - specular_light *= env.x * f0 + env.y; + specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, 0.0, 1.0); #endif } @@ -1417,7 +1425,7 @@ void fragment_shader(in SceneData scene_data) { float shadow = 1.0; - if (directional_lights.data[i].shadow_enabled) { + if (directional_lights.data[i].shadow_opacity > 0.001) { float depth_z = -vertex.z; vec3 light_dir = directional_lights.data[i].direction; vec3 base_normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))); @@ -1626,7 +1634,7 @@ void fragment_shader(in SceneData scene_data) { #ifdef LIGHT_TRANSMITTANCE_USED float transmittance_z = transmittance_depth; - if (directional_lights.data[i].shadow_enabled) { + if (directional_lights.data[i].shadow_opacity > 0.001) { float depth_z = -vertex.z; if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { @@ -1681,6 +1689,8 @@ void fragment_shader(in SceneData scene_data) { } else { shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0; } + + shadow = shadow * directional_lights.data[i].shadow_opacity + 1.0 - directional_lights.data[i].shadow_opacity; #endif blur_shadow(shadow); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl index 0c23de96c3..f0717294ef 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl @@ -129,10 +129,10 @@ layout(set = 0, binding = 13, std430) restrict readonly buffer Decals { } decals; -layout(set = 0, binding = 14, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 14, std430) restrict readonly buffer GlobalShaderUniformData { vec4 data[]; } -global_variables; +global_shader_uniforms; struct SDFVoxelGICascadeData { vec3 position; 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 c92b29b14a..7299bb0576 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -199,7 +199,10 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte #endif // LIGHT_ANISOTROPY_USED // F float cLdotH5 = SchlickFresnel(cLdotH); - vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0); + // Calculate Fresnel using specular occlusion term from Filament: + // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion + float f90 = clamp(dot(f0, vec3(50.0 * 0.33)), 0.0, 1.0); + vec3 F = f0 + (f90 - f0) * cLdotH5; vec3 specular_brdf_NL = cNdotL * D * F * G; @@ -392,7 +395,7 @@ float get_omni_attenuation(float distance, float inv_range, float decay) { float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { #ifndef SHADOWS_DISABLED - if (omni_lights.data[idx].shadow_enabled) { + if (omni_lights.data[idx].shadow_opacity > 0.001) { // there is a shadowmap vec2 texel_size = scene_data_block.data.shadow_atlas_pixel_size; vec4 base_uv_rect = omni_lights.data[idx].atlas_rect; @@ -495,6 +498,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { } shadow /= float(sc_penumbra_shadow_samples); + shadow = mix(1.0, shadow, omni_lights.data[idx].shadow_opacity); } else { //no blockers found, so no shadow @@ -513,7 +517,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { 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); + shadow = mix(1.0, sample_omni_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale / shadow_sample.z, pos, uv_rect, flip_offset, depth), omni_lights.data[idx].shadow_opacity); } return shadow; @@ -671,7 +675,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { #ifndef SHADOWS_DISABLED - if (spot_lights.data[idx].shadow_enabled) { + if (spot_lights.data[idx].shadow_opacity > 0.001) { 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; @@ -732,6 +736,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { } shadow /= float(sc_penumbra_shadow_samples); + shadow = mix(1.0, shadow, spot_lights.data[idx].shadow_opacity); } else { //no blockers found, so no shadow @@ -740,7 +745,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { } else { //hard shadow 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_block.data.shadow_atlas_pixel_size, shadow_uv); + shadow = mix(1.0, sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data_block.data.shadow_atlas_pixel_size, shadow_uv), spot_lights.data[idx].shadow_opacity); } return shadow; @@ -869,7 +874,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v diffuse_light, specular_light); } -void reflection_process(uint ref_index, vec3 view, vec3 vertex, vec3 normal, float roughness, vec3 ambient_light, vec3 specular_light, inout vec4 ambient_accum, inout vec4 reflection_accum) { +void reflection_process(uint ref_index, vec3 vertex, vec3 ref_vec, vec3 normal, float roughness, vec3 ambient_light, vec3 specular_light, inout vec4 ambient_accum, inout vec4 reflection_accum) { vec3 box_extents = reflections.data[ref_index].box_extents; vec3 local_pos = (reflections.data[ref_index].local_matrix * vec4(vertex, 1.0)).xyz; @@ -877,8 +882,6 @@ void reflection_process(uint ref_index, vec3 view, vec3 vertex, vec3 normal, flo return; } - vec3 ref_vec = normalize(reflect(-view, normal)); - vec3 inner_pos = abs(local_pos / box_extents); float blend = max(inner_pos.x, max(inner_pos.y, inner_pos.z)); //make blend more rounded diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 26d0de46c2..6548793bee 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -889,8 +889,10 @@ void main() { vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); vec3 ref_vec = reflect(-view, bent_normal); + ref_vec = mix(ref_vec, bent_normal, roughness * roughness); #else vec3 ref_vec = reflect(-view, normal); + ref_vec = mix(ref_vec, normal, roughness * roughness); #endif float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; @@ -940,6 +942,7 @@ void main() { vec3 n = normalize(normal_interp); // We want to use geometric normal, not normal_map float NoV = max(dot(n, view), 0.0001); vec3 ref_vec = reflect(-view, n); + ref_vec = mix(ref_vec, n, clearcoat_roughness * clearcoat_roughness); // The clear coat layer assumes an IOR of 1.5 (4% reflectance) float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV)); float attenuation = 1.0 - Fc; @@ -1036,6 +1039,19 @@ void main() { vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0); uint reflection_indices = draw_call.reflection_probes.x; + +#ifdef LIGHT_ANISOTROPY_USED + // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy + vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; + vec3 anisotropic_tangent = cross(anisotropic_direction, view); + vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); + vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); +#else + vec3 bent_normal = normal; +#endif + vec3 ref_vec = normalize(reflect(-view, bent_normal)); + ref_vec = mix(ref_vec, bent_normal, roughness * roughness); + for (uint i = 0; i < 8; i++) { uint reflection_index = reflection_indices & 0xFF; if (i == 4) { @@ -1047,16 +1063,8 @@ void main() { if (reflection_index == 0xFF) { break; } -#ifdef LIGHT_ANISOTROPY_USED - // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy - vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; - vec3 anisotropic_tangent = cross(anisotropic_direction, view); - vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); - vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); -#else - vec3 bent_normal = normal; -#endif - reflection_process(reflection_index, view, vertex, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); + + reflection_process(reflection_index, vertex, ref_vec, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); } if (reflection_accum.a > 0.0) { @@ -1134,7 +1142,7 @@ void main() { #ifdef USE_SOFT_SHADOWS //version with soft shadows, more expensive - if (directional_lights.data[i].shadow_enabled) { + if (directional_lights.data[i].shadow_opacity > 0.001) { float depth_z = -vertex.z; vec4 pssm_coord; @@ -1286,7 +1294,7 @@ void main() { #else // Soft shadow disabled version - if (directional_lights.data[i].shadow_enabled) { + if (directional_lights.data[i].shadow_opacity > 0.001) { float depth_z = -vertex.z; vec4 pssm_coord; 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 7413d8730a..98ad674ce0 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl @@ -118,10 +118,10 @@ layout(set = 0, binding = 13, std430) restrict readonly buffer Decals { } decals; -layout(set = 0, binding = 14, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 14, std430) restrict readonly buffer GlobalShaderUniformData { highp vec4 data[]; } -global_variables; +global_shader_uniforms; /* Set 1: Render Pass (changes per render pass) */ diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index e65f676785..882afdfa54 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -56,7 +56,7 @@ LightStorage::LightStorage() { } for (int i = 0; i < lightmap_textures.size(); i++) { - lightmap_textures.write[i] = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + lightmap_textures.write[i] = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); } } @@ -88,6 +88,7 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8; light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0; light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02; + light.param[RS::LIGHT_PARAM_SHADOW_OPACITY] = 1.0; light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0; light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1; @@ -366,6 +367,13 @@ AABB LightStorage::light_get_aabb(RID p_light) const { ERR_FAIL_V(AABB()); } +Dependency *LightStorage::light_get_dependency(RID p_light) const { + Light *light = light_owner.get_or_null(p_light); + ERR_FAIL_NULL_V(light, nullptr); + + return &light->dependency; +} + /* REFLECTION PROBE */ RID LightStorage::reflection_probe_allocate() { @@ -601,6 +609,13 @@ float LightStorage::reflection_probe_get_ambient_color_energy(RID p_probe) const return reflection_probe->ambient_color_energy; } +Dependency *LightStorage::reflection_probe_get_dependency(RID p_probe) const { + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); + ERR_FAIL_NULL_V(reflection_probe, nullptr); + + return &reflection_probe->dependency; +} + /* LIGHTMAP API */ RID LightStorage::lightmap_allocate() { @@ -628,17 +643,17 @@ void LightStorage::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_use //erase lightmap users if (lm->light_texture.is_valid()) { - RendererRD::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(lm->light_texture); + RendererRD::TextureStorage::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(lm->light_texture); if (t) { t->lightmap_users.erase(p_lightmap); } } - RendererRD::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(p_light); + RendererRD::TextureStorage::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(p_light); lm->light_texture = p_light; lm->uses_spherical_harmonics = p_uses_spherical_haromics; - RID default_2d_array = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + RID default_2d_array = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); if (!t) { if (using_lightmap_array) { if (lm->array_index >= 0) { @@ -725,6 +740,13 @@ void LightStorage::lightmap_set_probe_capture_update_speed(float p_speed) { lightmap_probe_capture_update_speed = p_speed; } +Dependency *LightStorage::lightmap_get_dependency(RID p_lightmap) const { + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); + ERR_FAIL_NULL_V(lm, nullptr); + + return &lm->dependency; +} + void LightStorage::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) { Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND(!lm); diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index 2fb8f92fff..3e3246e8e9 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -39,87 +39,81 @@ namespace RendererRD { -/* LIGHT */ - -struct Light { - RS::LightType type; - float param[RS::LIGHT_PARAM_MAX]; - Color color = Color(1, 1, 1, 1); - RID projector; - bool shadow = false; - bool negative = false; - bool reverse_cull = false; - RS::LightBakeMode bake_mode = RS::LIGHT_BAKE_DYNAMIC; - uint32_t max_sdfgi_cascade = 2; - uint32_t cull_mask = 0xFFFFFFFF; - bool distance_fade = false; - real_t distance_fade_begin = 40.0; - real_t distance_fade_shadow = 50.0; - real_t distance_fade_length = 10.0; - RS::LightOmniShadowMode omni_shadow_mode = RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; - RS::LightDirectionalShadowMode directional_shadow_mode = RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; - bool directional_blend_splits = false; - RS::LightDirectionalSkyMode directional_sky_mode = RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY; - uint64_t version = 0; - - Dependency dependency; -}; - -/* REFLECTION PROBE */ - -struct ReflectionProbe { - RS::ReflectionProbeUpdateMode update_mode = RS::REFLECTION_PROBE_UPDATE_ONCE; - int resolution = 256; - float intensity = 1.0; - RS::ReflectionProbeAmbientMode ambient_mode = RS::REFLECTION_PROBE_AMBIENT_ENVIRONMENT; - Color ambient_color; - float ambient_color_energy = 1.0; - float max_distance = 0; - Vector3 extents = Vector3(1, 1, 1); - Vector3 origin_offset; - bool interior = false; - bool box_projection = false; - bool enable_shadows = false; - uint32_t cull_mask = (1 << 20) - 1; - float mesh_lod_threshold = 0.01; - - Dependency dependency; -}; - -/* LIGHTMAP */ - -struct Lightmap { - RID light_texture; - bool uses_spherical_harmonics = false; - bool interior = false; - AABB bounds = AABB(Vector3(), Vector3(1, 1, 1)); - int32_t array_index = -1; //unassigned - PackedVector3Array points; - PackedColorArray point_sh; - PackedInt32Array tetrahedra; - PackedInt32Array bsp_tree; - - struct BSP { - static const int32_t EMPTY_LEAF = INT32_MIN; - float plane[4]; - int32_t over = EMPTY_LEAF, under = EMPTY_LEAF; - }; - - Dependency dependency; -}; - class LightStorage : public RendererLightStorage { private: static LightStorage *singleton; /* LIGHT */ + struct Light { + RS::LightType type; + float param[RS::LIGHT_PARAM_MAX]; + Color color = Color(1, 1, 1, 1); + RID projector; + bool shadow = false; + bool negative = false; + bool reverse_cull = false; + RS::LightBakeMode bake_mode = RS::LIGHT_BAKE_DYNAMIC; + uint32_t max_sdfgi_cascade = 2; + uint32_t cull_mask = 0xFFFFFFFF; + bool distance_fade = false; + real_t distance_fade_begin = 40.0; + real_t distance_fade_shadow = 50.0; + real_t distance_fade_length = 10.0; + RS::LightOmniShadowMode omni_shadow_mode = RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; + RS::LightDirectionalShadowMode directional_shadow_mode = RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; + bool directional_blend_splits = false; + RS::LightDirectionalSkyMode directional_sky_mode = RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY; + uint64_t version = 0; + + Dependency dependency; + }; + mutable RID_Owner<Light, true> light_owner; /* REFLECTION PROBE */ + + struct ReflectionProbe { + RS::ReflectionProbeUpdateMode update_mode = RS::REFLECTION_PROBE_UPDATE_ONCE; + int resolution = 256; + float intensity = 1.0; + RS::ReflectionProbeAmbientMode ambient_mode = RS::REFLECTION_PROBE_AMBIENT_ENVIRONMENT; + Color ambient_color; + float ambient_color_energy = 1.0; + float max_distance = 0; + Vector3 extents = Vector3(1, 1, 1); + Vector3 origin_offset; + bool interior = false; + bool box_projection = false; + bool enable_shadows = false; + uint32_t cull_mask = (1 << 20) - 1; + float mesh_lod_threshold = 0.01; + + Dependency dependency; + }; mutable RID_Owner<ReflectionProbe, true> reflection_probe_owner; /* LIGHTMAP */ + struct Lightmap { + RID light_texture; + bool uses_spherical_harmonics = false; + bool interior = false; + AABB bounds = AABB(Vector3(), Vector3(1, 1, 1)); + int32_t array_index = -1; //unassigned + PackedVector3Array points; + PackedColorArray point_sh; + PackedInt32Array tetrahedra; + PackedInt32Array bsp_tree; + + struct BSP { + static const int32_t EMPTY_LEAF = INT32_MIN; + float plane[4]; + int32_t over = EMPTY_LEAF, under = EMPTY_LEAF; + }; + + Dependency dependency; + }; + bool using_lightmap_array; Vector<RID> lightmap_textures; uint64_t lightmap_array_version = 0; @@ -135,7 +129,6 @@ public: /* LIGHT */ - Light *get_light(RID p_rid) { return light_owner.get_or_null(p_rid); }; bool owns_light(RID p_rid) { return light_owner.owns(p_rid); }; void _light_initialize(RID p_rid, RS::LightType p_type); @@ -268,9 +261,10 @@ public: virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override; virtual uint64_t light_get_version(RID p_light) const override; + Dependency *light_get_dependency(RID p_light) const; + /* REFLECTION PROBE */ - ReflectionProbe *get_reflection_probe(RID p_rid) { return reflection_probe_owner.get_or_null(p_rid); }; bool owns_reflection_probe(RID p_rid) { return reflection_probe_owner.owns(p_rid); }; virtual RID reflection_probe_allocate() override; @@ -310,9 +304,10 @@ public: Color reflection_probe_get_ambient_color(RID p_probe) const; float reflection_probe_get_ambient_color_energy(RID p_probe) const; + Dependency *reflection_probe_get_dependency(RID p_probe) const; + /* LIGHTMAP */ - Lightmap *get_lightmap(RID p_rid) { return lightmap_owner.get_or_null(p_rid); }; bool owns_lightmap(RID p_rid) { return lightmap_owner.owns(p_rid); }; virtual RID lightmap_allocate() override; @@ -332,6 +327,8 @@ public: virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) override; virtual void lightmap_set_probe_capture_update_speed(float p_speed) override; + Dependency *lightmap_get_dependency(RID p_lightmap) const; + virtual float lightmap_get_probe_capture_update_speed() const override { return lightmap_probe_capture_update_speed; } diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index 23d05de942..41dd1ccc40 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -176,10 +176,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 2 * p_array_size; const int *r = iv.ptr(); @@ -205,10 +201,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 3 * p_array_size; const int *r = iv.ptr(); @@ -236,10 +228,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 4 * p_array_size; const int *r = iv.ptr(); @@ -292,10 +280,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 2 * p_array_size; const int *r = iv.ptr(); @@ -321,10 +305,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 3 * p_array_size; const int *r = iv.ptr(); @@ -352,10 +332,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (p_array_size > 0) { Vector<int> iv = value; int s = iv.size(); - - if (p_array_size <= 0) { - p_array_size = 1; - } int count = 4 * p_array_size; const int *r = iv.ptr(); @@ -950,9 +926,9 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, } /////////////////////////////////////////////////////////////////////////// -// MaterialData +// MaterialStorage::MaterialData -void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { +void MaterialStorage::MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { MaterialStorage *material_storage = MaterialStorage::get_singleton(); bool uses_global_buffer = false; @@ -967,7 +943,7 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { //this is a global variable, get the index to it - GlobalVariables::Variable *gv = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *gv = material_storage->global_shader_uniforms.variables.getptr(E.key); uint32_t index = 0; if (gv) { index = gv->buffer_index; @@ -1023,33 +999,33 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag if (uses_global_buffer != (global_buffer_E != nullptr)) { if (uses_global_buffer) { - global_buffer_E = material_storage->global_variables.materials_using_buffer.push_back(self); + global_buffer_E = material_storage->global_shader_uniforms.materials_using_buffer.push_back(self); } else { - material_storage->global_variables.materials_using_buffer.erase(global_buffer_E); + material_storage->global_shader_uniforms.materials_using_buffer.erase(global_buffer_E); global_buffer_E = nullptr; } } } -MaterialData::~MaterialData() { +MaterialStorage::MaterialData::~MaterialData() { MaterialStorage *material_storage = MaterialStorage::get_singleton(); if (global_buffer_E) { //unregister global buffers - material_storage->global_variables.materials_using_buffer.erase(global_buffer_E); + material_storage->global_shader_uniforms.materials_using_buffer.erase(global_buffer_E); } if (global_texture_E) { //unregister global textures for (const KeyValue<StringName, uint64_t> &E : used_global_textures) { - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(E.key); if (v) { v->texture_materials.erase(self); } } //unregister material from those using global textures - material_storage->global_variables.materials_using_texture.erase(global_texture_E); + material_storage->global_shader_uniforms.materials_using_texture.erase(global_texture_E); } if (uniform_buffer.is_valid()) { @@ -1057,14 +1033,14 @@ MaterialData::~MaterialData() { } } -void MaterialData::update_textures(const HashMap<StringName, Variant> &p_parameters, const HashMap<StringName, HashMap<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { +void MaterialStorage::MaterialData::update_textures(const HashMap<StringName, Variant> &p_parameters, const HashMap<StringName, HashMap<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { TextureStorage *texture_storage = TextureStorage::get_singleton(); MaterialStorage *material_storage = MaterialStorage::get_singleton(); #ifdef TOOLS_ENABLED - Texture *roughness_detect_texture = nullptr; + TextureStorage::Texture *roughness_detect_texture = nullptr; RS::TextureDetectRoughnessChannel roughness_channel = RS::TEXTURE_DETECT_ROUGHNESS_R; - Texture *normal_detect_texture = nullptr; + TextureStorage::Texture *normal_detect_texture = nullptr; #endif bool uses_global_textures = false; @@ -1079,7 +1055,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet if (p_texture_uniforms[i].global) { uses_global_textures = true; - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(uniform_name); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(uniform_name); if (v) { if (v->buffer_index >= 0) { WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); @@ -1147,19 +1123,22 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet case ShaderLanguage::TYPE_SAMPLER2D: { switch (p_texture_uniforms[i].hint) { case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_BLACK: { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_BLACK); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_BLACK); + } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT: { + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_TRANSPARENT); } break; case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_ANISO); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_ANISO); } break; case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_NORMAL); } break; case ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL: { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_NORMAL); } break; default: { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_WHITE); } break; } } break; @@ -1167,27 +1146,27 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet case ShaderLanguage::TYPE_SAMPLERCUBE: { switch (p_texture_uniforms[i].hint) { case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_BLACK: { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); } break; default: { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_CUBEMAP_WHITE); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE); } break; } } break; case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); } break; case ShaderLanguage::TYPE_ISAMPLER3D: case ShaderLanguage::TYPE_USAMPLER3D: case ShaderLanguage::TYPE_SAMPLER3D: { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_3D_WHITE); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); } break; case ShaderLanguage::TYPE_ISAMPLER2DARRAY: case ShaderLanguage::TYPE_USAMPLER2DARRAY: case ShaderLanguage::TYPE_SAMPLER2DARRAY: { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); } break; default: { @@ -1209,7 +1188,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet bool srgb = p_use_linear_color && p_texture_uniforms[i].use_color; for (int j = 0; j < textures.size(); j++) { - Texture *tex = TextureStorage::get_singleton()->get_texture(textures[j]); + TextureStorage::Texture *tex = TextureStorage::get_singleton()->get_texture(textures[j]); if (tex) { rd_texture = (srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture; @@ -1231,7 +1210,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet #endif } if (rd_texture.is_null()) { - rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE); + rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_WHITE); } #ifdef TOOLS_ENABLED if (roughness_detect_texture && normal_detect_texture && !normal_detect_texture->path.is_empty()) { @@ -1249,7 +1228,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet if (E.value != global_textures_pass) { to_delete.push_back(E.key); - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(E.key); if (v) { v->texture_materials.erase(self); } @@ -1263,23 +1242,23 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet //handle registering/unregistering global textures if (uses_global_textures != (global_texture_E != nullptr)) { if (uses_global_textures) { - global_texture_E = material_storage->global_variables.materials_using_texture.push_back(self); + global_texture_E = material_storage->global_shader_uniforms.materials_using_texture.push_back(self); } else { - material_storage->global_variables.materials_using_texture.erase(global_texture_E); + material_storage->global_shader_uniforms.materials_using_texture.erase(global_texture_E); global_texture_E = nullptr; } } } } -void MaterialData::free_parameters_uniform_set(RID p_uniform_set) { +void MaterialStorage::MaterialData::free_parameters_uniform_set(RID p_uniform_set) { if (p_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(p_uniform_set)) { RD::get_singleton()->uniform_set_set_invalidation_callback(p_uniform_set, nullptr, nullptr); RD::get_singleton()->free(p_uniform_set); } } -bool MaterialData::update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) { +bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) { if ((uint32_t)ubo_data.size() != p_ubo_size) { p_uniform_dirty = true; if (uniform_buffer.is_valid()) { @@ -1497,22 +1476,22 @@ MaterialStorage::MaterialStorage() { shader_data_request_func[i] = nullptr; } - static_assert(sizeof(GlobalVariables::Value) == 16); + static_assert(sizeof(GlobalShaderUniforms::Value) == 16); - global_variables.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); - global_variables.buffer_values = memnew_arr(GlobalVariables::Value, global_variables.buffer_size); - memset(global_variables.buffer_values, 0, sizeof(GlobalVariables::Value) * global_variables.buffer_size); - global_variables.buffer_usage = memnew_arr(GlobalVariables::ValueUsage, global_variables.buffer_size); - global_variables.buffer_dirty_regions = memnew_arr(bool, global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); - memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); - global_variables.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalVariables::Value) * global_variables.buffer_size); + global_shader_uniforms.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); + global_shader_uniforms.buffer_values = memnew_arr(GlobalShaderUniforms::Value, global_shader_uniforms.buffer_size); + memset(global_shader_uniforms.buffer_values, 0, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size); + global_shader_uniforms.buffer_usage = memnew_arr(GlobalShaderUniforms::ValueUsage, global_shader_uniforms.buffer_size); + global_shader_uniforms.buffer_dirty_regions = memnew_arr(bool, global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE); + memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE); + global_shader_uniforms.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size); } MaterialStorage::~MaterialStorage() { - memdelete_arr(global_variables.buffer_values); - memdelete_arr(global_variables.buffer_usage); - memdelete_arr(global_variables.buffer_dirty_regions); - RD::get_singleton()->free(global_variables.buffer); + memdelete_arr(global_shader_uniforms.buffer_values); + memdelete_arr(global_shader_uniforms.buffer_usage); + memdelete_arr(global_shader_uniforms.buffer_dirty_regions); + RD::get_singleton()->free(global_shader_uniforms.buffer); // buffers @@ -1633,17 +1612,17 @@ void MaterialStorage::sampler_rd_configure_custom(float p_mipmap_bias) { } } -/* GLOBAL VARIABLE API */ +/* GLOBAL SHADER UNIFORM API */ -int32_t MaterialStorage::_global_variable_allocate(uint32_t p_elements) { +int32_t MaterialStorage::_global_shader_uniform_allocate(uint32_t p_elements) { int32_t idx = 0; - while (idx + p_elements <= global_variables.buffer_size) { - if (global_variables.buffer_usage[idx].elements == 0) { + while (idx + p_elements <= global_shader_uniforms.buffer_size) { + if (global_shader_uniforms.buffer_usage[idx].elements == 0) { bool valid = true; for (uint32_t i = 1; i < p_elements; i++) { - if (global_variables.buffer_usage[idx + i].elements > 0) { + if (global_shader_uniforms.buffer_usage[idx + i].elements > 0) { valid = false; - idx += i + global_variables.buffer_usage[idx + i].elements; + idx += i + global_shader_uniforms.buffer_usage[idx + i].elements; break; } } @@ -1654,17 +1633,17 @@ int32_t MaterialStorage::_global_variable_allocate(uint32_t p_elements) { return idx; } else { - idx += global_variables.buffer_usage[idx].elements; + idx += global_shader_uniforms.buffer_usage[idx].elements; } } return -1; } -void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) { +void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; bool b = p_value; bv.x = b ? 1.0 : 0.0; bv.y = 0.0; @@ -1673,7 +1652,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_BVEC2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1681,7 +1660,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0.0; } break; case RS::GLOBAL_VAR_TYPE_BVEC3: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1689,7 +1668,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0.0; } break; case RS::GLOBAL_VAR_TYPE_BVEC4: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1697,7 +1676,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = (bvec & 8) ? 1.0 : 0.0; } break; case RS::GLOBAL_VAR_TYPE_INT: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; int32_t v = p_value; bv.x = v; bv.y = 0; @@ -1705,7 +1684,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC2: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector2i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1713,7 +1692,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC3: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector3i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1721,7 +1700,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC4: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector<int32_t> v = p_value; bv.x = v.size() >= 1 ? v[0] : 0; bv.y = v.size() >= 2 ? v[1] : 0; @@ -1729,7 +1708,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size() >= 4 ? v[3] : 0; } break; case RS::GLOBAL_VAR_TYPE_RECT2I: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Rect2i v = p_value; bv.x = v.position.x; bv.y = v.position.y; @@ -1737,7 +1716,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size.y; } break; case RS::GLOBAL_VAR_TYPE_UINT: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; uint32_t v = p_value; bv.x = v; bv.y = 0; @@ -1745,7 +1724,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC2: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector2i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1753,7 +1732,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC3: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector3i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1761,7 +1740,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC4: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector<int32_t> v = p_value; bv.x = v.size() >= 1 ? v[0] : 0; bv.y = v.size() >= 2 ? v[1] : 0; @@ -1769,7 +1748,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size() >= 4 ? v[3] : 0; } break; case RS::GLOBAL_VAR_TYPE_FLOAT: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; float v = p_value; bv.x = v; bv.y = 0; @@ -1777,7 +1756,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Vector2 v = p_value; bv.x = v.x; bv.y = v.y; @@ -1785,7 +1764,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC3: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Vector3 v = p_value; bv.x = v.x; bv.y = v.y; @@ -1793,7 +1772,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC4: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Plane v = p_value; bv.x = v.normal.x; bv.y = v.normal.y; @@ -1801,14 +1780,14 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.d; } break; case RS::GLOBAL_VAR_TYPE_COLOR: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Color v = p_value; bv.x = v.r; bv.y = v.g; bv.z = v.b; bv.w = v.a; - GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1]; + GlobalShaderUniforms::Value &bv_linear = global_shader_uniforms.buffer_values[p_index + 1]; v = v.srgb_to_linear(); bv_linear.x = v.r; bv_linear.y = v.g; @@ -1817,7 +1796,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_RECT2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Rect2 v = p_value; bv.x = v.position.x; bv.y = v.position.y; @@ -1825,7 +1804,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size.y; } break; case RS::GLOBAL_VAR_TYPE_MAT2: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Vector<float> m2 = p_value; if (m2.size() < 4) { m2.resize(4); @@ -1842,7 +1821,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_MAT3: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Basis v = p_value; bv[0].x = v.rows[0][0]; bv[0].y = v.rows[1][0]; @@ -1861,7 +1840,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_MAT4: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Vector<float> m2 = p_value; if (m2.size() < 16) { @@ -1890,7 +1869,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Transform2D v = p_value; bv[0].x = v.columns[0][0]; bv[0].y = v.columns[0][1]; @@ -1909,7 +1888,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Transform3D v = p_value; bv[0].x = v.basis.rows[0][0]; bv[0].y = v.basis.rows[1][0]; @@ -1938,15 +1917,15 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } } -void MaterialStorage::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { +void MaterialStorage::_global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { int32_t prev_chunk = -1; for (int32_t i = 0; i < p_elements; i++) { - int32_t chunk = (p_index + i) / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; + int32_t chunk = (p_index + i) / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; if (chunk != prev_chunk) { - if (!global_variables.buffer_dirty_regions[chunk]) { - global_variables.buffer_dirty_regions[chunk] = true; - global_variables.buffer_dirty_region_count++; + if (!global_shader_uniforms.buffer_dirty_regions[chunk]) { + global_shader_uniforms.buffer_dirty_regions[chunk] = true; + global_shader_uniforms.buffer_dirty_region_count++; } } @@ -1954,16 +1933,16 @@ void MaterialStorage::_global_variable_mark_buffer_dirty(int32_t p_index, int32_ } } -void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { - ERR_FAIL_COND(global_variables.variables.has(p_name)); - GlobalVariables::Variable gv; +void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) { + ERR_FAIL_COND(global_shader_uniforms.variables.has(p_name)); + GlobalShaderUniforms::Variable gv; gv.type = p_type; gv.value = p_value; gv.buffer_index = -1; if (p_type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { //is texture - global_variables.must_update_texture_materials = true; //normally there are none + global_shader_uniforms.must_update_texture_materials = true; //normally there are none } else { gv.buffer_elements = 1; if (p_type == RS::GLOBAL_VAR_TYPE_COLOR || p_type == RS::GLOBAL_VAR_TYPE_MAT2) { @@ -1980,56 +1959,56 @@ void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVa } //is vector, allocate in buffer and update index - gv.buffer_index = _global_variable_allocate(gv.buffer_elements); + gv.buffer_index = _global_shader_uniform_allocate(gv.buffer_elements); ERR_FAIL_COND_MSG(gv.buffer_index < 0, vformat("Failed allocating global variable '%s' out of buffer memory. Consider increasing it in the Project Settings.", String(p_name))); - global_variables.buffer_usage[gv.buffer_index].elements = gv.buffer_elements; - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + global_shader_uniforms.buffer_usage[gv.buffer_index].elements = gv.buffer_elements; + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); - global_variables.must_update_buffer_materials = true; //normally there are none + global_shader_uniforms.must_update_buffer_materials = true; //normally there are none } - global_variables.variables[p_name] = gv; + global_shader_uniforms.variables[p_name] = gv; } -void MaterialStorage::global_variable_remove(const StringName &p_name) { - if (!global_variables.variables.has(p_name)) { +void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) { + if (!global_shader_uniforms.variables.has(p_name)) { return; } - const GlobalVariables::Variable &gv = global_variables.variables[p_name]; + const GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; if (gv.buffer_index >= 0) { - global_variables.buffer_usage[gv.buffer_index].elements = 0; - global_variables.must_update_buffer_materials = true; + global_shader_uniforms.buffer_usage[gv.buffer_index].elements = 0; + global_shader_uniforms.must_update_buffer_materials = true; } else { - global_variables.must_update_texture_materials = true; + global_shader_uniforms.must_update_texture_materials = true; } - global_variables.variables.erase(p_name); + global_shader_uniforms.variables.erase(p_name); } -Vector<StringName> MaterialStorage::global_variable_get_list() const { +Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } Vector<StringName> names; - for (const KeyValue<StringName, GlobalVariables::Variable> &E : global_variables.variables) { + for (const KeyValue<StringName, GlobalShaderUniforms::Variable> &E : global_shader_uniforms.variables) { names.push_back(E.key); } names.sort_custom<StringName::AlphCompare>(); return names; } -void MaterialStorage::global_variable_set(const StringName &p_name, const Variant &p_value) { - ERR_FAIL_COND(!global_variables.variables.has(p_name)); - GlobalVariables::Variable &gv = global_variables.variables[p_name]; +void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const Variant &p_value) { + ERR_FAIL_COND(!global_shader_uniforms.variables.has(p_name)); + GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.value = p_value; if (gv.override.get_type() == Variant::NIL) { if (gv.buffer_index >= 0) { //buffer - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); } else { //texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -2042,26 +2021,26 @@ void MaterialStorage::global_variable_set(const StringName &p_name, const Varian } } -void MaterialStorage::global_variable_set_override(const StringName &p_name, const Variant &p_value) { - if (!global_variables.variables.has(p_name)) { +void MaterialStorage::global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) { + if (!global_shader_uniforms.variables.has(p_name)) { return; //variable may not exist } ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT); - GlobalVariables::Variable &gv = global_variables.variables[p_name]; + GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.override = p_value; if (gv.buffer_index >= 0) { //buffer if (gv.override.get_type() == Variant::NIL) { - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); } else { - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.override); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.override); } - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); } else { //texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -2073,35 +2052,35 @@ void MaterialStorage::global_variable_set_override(const StringName &p_name, con } } -Variant MaterialStorage::global_variable_get(const StringName &p_name) const { +Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); } - if (!global_variables.variables.has(p_name)) { + if (!global_shader_uniforms.variables.has(p_name)) { return Variant(); } - return global_variables.variables[p_name].value; + return global_shader_uniforms.variables[p_name].value; } -RS::GlobalVariableType MaterialStorage::global_variable_get_type_internal(const StringName &p_name) const { - if (!global_variables.variables.has(p_name)) { +RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_internal(const StringName &p_name) const { + if (!global_shader_uniforms.variables.has(p_name)) { return RS::GLOBAL_VAR_TYPE_MAX; } - return global_variables.variables[p_name].type; + return global_shader_uniforms.variables[p_name].type; } -RS::GlobalVariableType MaterialStorage::global_variable_get_type(const StringName &p_name) const { +RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance."); } - return global_variable_get_type_internal(p_name); + return global_shader_uniform_get_type_internal(p_name); } -void MaterialStorage::global_variables_load_settings(bool p_load_textures) { +void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) { List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); @@ -2146,11 +2125,11 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) { "samplerCube", }; - RS::GlobalVariableType gvtype = RS::GLOBAL_VAR_TYPE_MAX; + RS::GlobalShaderUniformType gvtype = RS::GLOBAL_VAR_TYPE_MAX; for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { if (global_var_type_names[i] == type) { - gvtype = RS::GlobalVariableType(i); + gvtype = RS::GlobalShaderUniformType(i); break; } } @@ -2172,47 +2151,47 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) { value = resource; } - if (global_variables.variables.has(name)) { + if (global_shader_uniforms.variables.has(name)) { //has it, update it - global_variable_set(name, value); + global_shader_uniform_set(name, value); } else { - global_variable_add(name, gvtype, value); + global_shader_uniform_add(name, gvtype, value); } } } } -void MaterialStorage::global_variables_clear() { - global_variables.variables.clear(); //not right but for now enough +void MaterialStorage::global_shader_uniforms_clear() { + global_shader_uniforms.variables.clear(); //not right but for now enough } -RID MaterialStorage::global_variables_get_storage_buffer() const { - return global_variables.buffer; +RID MaterialStorage::global_shader_uniforms_get_storage_buffer() const { + return global_shader_uniforms.buffer; } -int32_t MaterialStorage::global_variables_instance_allocate(RID p_instance) { - ERR_FAIL_COND_V(global_variables.instance_buffer_pos.has(p_instance), -1); - int32_t pos = _global_variable_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); - global_variables.instance_buffer_pos[p_instance] = pos; //save anyway +int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance) { + ERR_FAIL_COND_V(global_shader_uniforms.instance_buffer_pos.has(p_instance), -1); + int32_t pos = _global_shader_uniform_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); + global_shader_uniforms.instance_buffer_pos[p_instance] = pos; //save anyway ERR_FAIL_COND_V_MSG(pos < 0, -1, "Too many instances using shader instance variables. Increase buffer size in Project Settings."); - global_variables.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES; + global_shader_uniforms.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES; return pos; } -void MaterialStorage::global_variables_instance_free(RID p_instance) { - ERR_FAIL_COND(!global_variables.instance_buffer_pos.has(p_instance)); - int32_t pos = global_variables.instance_buffer_pos[p_instance]; +void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) { + ERR_FAIL_COND(!global_shader_uniforms.instance_buffer_pos.has(p_instance)); + int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos >= 0) { - global_variables.buffer_usage[pos].elements = 0; + global_shader_uniforms.buffer_usage[pos].elements = 0; } - global_variables.instance_buffer_pos.erase(p_instance); + global_shader_uniforms.instance_buffer_pos.erase(p_instance); } -void MaterialStorage::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { - if (!global_variables.instance_buffer_pos.has(p_instance)) { +void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) { + if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } - int32_t pos = global_variables.instance_buffer_pos[p_instance]; + int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos < 0) { return; //again, not allocated, ignore @@ -2233,11 +2212,14 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind ShaderLanguage::TYPE_VEC3, // vec3 ShaderLanguage::TYPE_IVEC3, //vec3i ShaderLanguage::TYPE_MAX, //xform2d not supported here + ShaderLanguage::TYPE_VEC4, //vec4 + ShaderLanguage::TYPE_IVEC4, //vec4i ShaderLanguage::TYPE_VEC4, //plane ShaderLanguage::TYPE_VEC4, //quat ShaderLanguage::TYPE_MAX, //aabb not supported here ShaderLanguage::TYPE_MAX, //basis not supported here ShaderLanguage::TYPE_MAX, //xform not supported here + ShaderLanguage::TYPE_MAX, //projection not supported here ShaderLanguage::TYPE_VEC4 //color }; @@ -2247,57 +2229,57 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind pos += p_index; - _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos], true); //instances always use linear color in this renderer - _global_variable_mark_buffer_dirty(pos, 1); + _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_shader_uniforms.buffer_values[pos], true); //instances always use linear color in this renderer + _global_shader_uniform_mark_buffer_dirty(pos, 1); } -void MaterialStorage::_update_global_variables() { +void MaterialStorage::_update_global_shader_uniforms() { MaterialStorage *material_storage = MaterialStorage::get_singleton(); - if (global_variables.buffer_dirty_region_count > 0) { - uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; - if (total_regions / global_variables.buffer_dirty_region_count <= 4) { + if (global_shader_uniforms.buffer_dirty_region_count > 0) { + uint32_t total_regions = global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; + if (total_regions / global_shader_uniforms.buffer_dirty_region_count <= 4) { // 25% of regions dirty, just update all buffer - RD::get_singleton()->buffer_update(global_variables.buffer, 0, sizeof(GlobalVariables::Value) * global_variables.buffer_size, global_variables.buffer_values); - memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * total_regions); + RD::get_singleton()->buffer_update(global_shader_uniforms.buffer, 0, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size, global_shader_uniforms.buffer_values); + memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * total_regions); } else { - uint32_t region_byte_size = sizeof(GlobalVariables::Value) * GlobalVariables::BUFFER_DIRTY_REGION_SIZE; + uint32_t region_byte_size = sizeof(GlobalShaderUniforms::Value) * GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; for (uint32_t i = 0; i < total_regions; i++) { - if (global_variables.buffer_dirty_regions[i]) { - RD::get_singleton()->buffer_update(global_variables.buffer, i * region_byte_size, region_byte_size, &global_variables.buffer_values[i * GlobalVariables::BUFFER_DIRTY_REGION_SIZE]); + if (global_shader_uniforms.buffer_dirty_regions[i]) { + RD::get_singleton()->buffer_update(global_shader_uniforms.buffer, i * region_byte_size, region_byte_size, &global_shader_uniforms.buffer_values[i * GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE]); - global_variables.buffer_dirty_regions[i] = false; + global_shader_uniforms.buffer_dirty_regions[i] = false; } } } - global_variables.buffer_dirty_region_count = 0; + global_shader_uniforms.buffer_dirty_region_count = 0; } - if (global_variables.must_update_buffer_materials) { + if (global_shader_uniforms.must_update_buffer_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (const RID &E : global_variables.materials_using_buffer) { + for (const RID &E : global_shader_uniforms.materials_using_buffer) { Material *material = material_storage->get_material(E); ERR_CONTINUE(!material); //wtf material_storage->_material_queue_update(material, true, false); } - global_variables.must_update_buffer_materials = false; + global_shader_uniforms.must_update_buffer_materials = false; } - if (global_variables.must_update_texture_materials) { + if (global_shader_uniforms.must_update_texture_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (const RID &E : global_variables.materials_using_texture) { + for (const RID &E : global_shader_uniforms.materials_using_texture) { Material *material = material_storage->get_material(E); ERR_CONTINUE(!material); //wtf material_storage->_material_queue_update(material, false, true); } - global_variables.must_update_texture_materials = false; + global_shader_uniforms.must_update_texture_materials = false; } } @@ -2424,11 +2406,11 @@ String MaterialStorage::shader_get_code(RID p_shader) const { return shader->code; } -void MaterialStorage::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { +void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const { Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); if (shader->data) { - return shader->data->get_param_list(p_param_list); + return shader->data->get_shader_uniform_list(p_param_list); } } @@ -2601,6 +2583,15 @@ void MaterialStorage::material_set_shader(RID p_material, RID p_shader) { _material_queue_update(material, true, true); } +MaterialStorage::ShaderData *MaterialStorage::material_get_shader_data(RID p_material) { + const MaterialStorage::Material *material = MaterialStorage::get_singleton()->get_material(p_material); + if (material && material->shader && material->shader->data) { + return material->shader->data; + } + + return nullptr; +} + void MaterialStorage::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) { Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); @@ -2681,14 +2672,14 @@ bool MaterialStorage::material_casts_shadows(RID p_material) { return true; //by default everything casts shadows } -void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { +void MaterialStorage::material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) { Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); if (material->shader && material->shader->data) { material->shader->data->get_instance_param_list(r_parameters); if (material->next_pass.is_valid()) { - material_get_instance_shader_parameters(material->next_pass, r_parameters); + material_get_instance_shader_uniforms(material->next_pass, r_parameters); } } } @@ -2702,12 +2693,12 @@ void MaterialStorage::material_update_dependency(RID p_material, DependencyTrack } } -void MaterialStorage::material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function) { +void MaterialStorage::material_set_data_request_function(ShaderType p_shader_type, MaterialStorage::MaterialDataRequestFunction p_function) { ERR_FAIL_INDEX(p_shader_type, SHADER_TYPE_MAX); material_data_request_func[p_shader_type] = p_function; } -MaterialDataRequestFunction MaterialStorage::material_get_data_request_function(ShaderType p_shader_type) { +MaterialStorage::MaterialDataRequestFunction MaterialStorage::material_get_data_request_function(ShaderType p_shader_type) { ERR_FAIL_INDEX_V(p_shader_type, SHADER_TYPE_MAX, nullptr); return material_data_request_func[p_shader_type]; } diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h index d5c9980150..dbf7a92e23 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h @@ -42,161 +42,62 @@ namespace RendererRD { -class MaterialStorage; - -/* SHADER Structs */ - -enum ShaderType { - SHADER_TYPE_2D, - SHADER_TYPE_3D, - SHADER_TYPE_PARTICLES, - SHADER_TYPE_SKY, - SHADER_TYPE_FOG, - SHADER_TYPE_MAX -}; - -struct ShaderData { - virtual void set_code(const String &p_Code) = 0; - virtual void set_path_hint(const String &p_hint) = 0; - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) = 0; - virtual void get_param_list(List<PropertyInfo> *p_param_list) const = 0; - - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0; - virtual bool is_param_texture(const StringName &p_param) const = 0; - virtual bool is_animated() const = 0; - virtual bool casts_shadows() const = 0; - virtual Variant get_default_parameter(const StringName &p_parameter) const = 0; - virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); } - - virtual ~ShaderData() {} -}; - -typedef ShaderData *(*ShaderDataRequestFunction)(); - -struct Material; - -struct Shader { - ShaderData *data = nullptr; - String code; - String path_hint; - ShaderType type; - HashMap<StringName, HashMap<int, RID>> default_texture_parameter; - HashSet<Material *> owners; -}; - -/* Material structs */ - -struct MaterialData { - void update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color); - void update_textures(const HashMap<StringName, Variant> &p_parameters, const HashMap<StringName, HashMap<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color); - - virtual void set_render_priority(int p_priority) = 0; - virtual void set_next_pass(RID p_pass) = 0; - virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0; - virtual ~MaterialData(); - - //to be used internally by update_parameters, in the most common configuration of material parameters - bool update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL); - void free_parameters_uniform_set(RID p_uniform_set); - -private: - friend class MaterialStorage; - RID self; - List<RID>::Element *global_buffer_E = nullptr; - List<RID>::Element *global_texture_E = nullptr; - uint64_t global_textures_pass = 0; - HashMap<StringName, uint64_t> used_global_textures; - - //internally by update_parameters_uniform_set - Vector<uint8_t> ubo_data; - RID uniform_buffer; - Vector<RID> texture_cache; -}; - -typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *); - -struct Material { - RID self; - MaterialData *data = nullptr; - Shader *shader = nullptr; - //shortcut to shader data and type - ShaderType shader_type = SHADER_TYPE_MAX; - uint32_t shader_id = 0; - bool uniform_dirty = false; - bool texture_dirty = false; - HashMap<StringName, Variant> params; - int32_t priority = 0; - RID next_pass; - SelfList<Material> update_element; - - Dependency dependency; - - Material() : - update_element(this) {} -}; - -/* Global variable structs */ -struct GlobalVariables { - enum { - BUFFER_DIRTY_REGION_SIZE = 1024 - }; - struct Variable { - HashSet<RID> texture_materials; // materials using this - - RS::GlobalVariableType type; - Variant value; - Variant override; - int32_t buffer_index; //for vectors - int32_t buffer_elements; //for vectors +class MaterialStorage : public RendererMaterialStorage { +public: + enum ShaderType { + SHADER_TYPE_2D, + SHADER_TYPE_3D, + SHADER_TYPE_PARTICLES, + SHADER_TYPE_SKY, + SHADER_TYPE_FOG, + SHADER_TYPE_MAX }; - HashMap<StringName, Variable> variables; - - struct Value { - float x; - float y; - float z; - float w; - }; + struct ShaderData { + virtual void set_code(const String &p_Code) = 0; + virtual void set_path_hint(const String &p_hint) = 0; + virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) = 0; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const = 0; - struct ValueInt { - int32_t x; - int32_t y; - int32_t z; - int32_t w; - }; + virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0; + virtual bool is_param_texture(const StringName &p_param) const = 0; + virtual bool is_animated() const = 0; + virtual bool casts_shadows() const = 0; + virtual Variant get_default_parameter(const StringName &p_parameter) const = 0; + virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); } - struct ValueUInt { - uint32_t x; - uint32_t y; - uint32_t z; - uint32_t w; + virtual ~ShaderData() {} }; - struct ValueUsage { - uint32_t elements = 0; - }; + struct MaterialData { + void update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color); + void update_textures(const HashMap<StringName, Variant> &p_parameters, const HashMap<StringName, HashMap<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color); - List<RID> materials_using_buffer; - List<RID> materials_using_texture; + virtual void set_render_priority(int p_priority) = 0; + virtual void set_next_pass(RID p_pass) = 0; + virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0; + virtual ~MaterialData(); - RID buffer; - Value *buffer_values = nullptr; - ValueUsage *buffer_usage = nullptr; - bool *buffer_dirty_regions = nullptr; - uint32_t buffer_dirty_region_count = 0; + //to be used internally by update_parameters, in the most common configuration of material parameters + bool update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL); + void free_parameters_uniform_set(RID p_uniform_set); - uint32_t buffer_size; + private: + friend class MaterialStorage; - bool must_update_texture_materials = false; - bool must_update_buffer_materials = false; + RID self; + List<RID>::Element *global_buffer_E = nullptr; + List<RID>::Element *global_texture_E = nullptr; + uint64_t global_textures_pass = 0; + HashMap<StringName, uint64_t> used_global_textures; - HashMap<RID, int32_t> instance_buffer_pos; -}; + //internally by update_parameters_uniform_set + Vector<uint8_t> ubo_data; + RID uniform_buffer; + Vector<RID> texture_cache; + }; -class MaterialStorage : public RendererMaterialStorage { private: - friend struct MaterialData; static MaterialStorage *singleton; /* Samplers */ @@ -209,22 +110,116 @@ private: RID quad_index_buffer; RID quad_index_array; - /* GLOBAL VARIABLE API */ + /* GLOBAL SHADER UNIFORM API */ + + struct GlobalShaderUniforms { + enum { + BUFFER_DIRTY_REGION_SIZE = 1024 + }; + struct Variable { + HashSet<RID> texture_materials; // materials using this + + RS::GlobalShaderUniformType type; + Variant value; + Variant override; + int32_t buffer_index; //for vectors + int32_t buffer_elements; //for vectors + }; + + HashMap<StringName, Variable> variables; + + struct Value { + float x; + float y; + float z; + float w; + }; + + struct ValueInt { + int32_t x; + int32_t y; + int32_t z; + int32_t w; + }; + + struct ValueUInt { + uint32_t x; + uint32_t y; + uint32_t z; + uint32_t w; + }; + + struct ValueUsage { + uint32_t elements = 0; + }; + + List<RID> materials_using_buffer; + List<RID> materials_using_texture; + + RID buffer; + Value *buffer_values = nullptr; + ValueUsage *buffer_usage = nullptr; + bool *buffer_dirty_regions = nullptr; + uint32_t buffer_dirty_region_count = 0; + + uint32_t buffer_size; + + bool must_update_texture_materials = false; + bool must_update_buffer_materials = false; + + HashMap<RID, int32_t> instance_buffer_pos; + } global_shader_uniforms; + + int32_t _global_shader_uniform_allocate(uint32_t p_elements); + void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value); + void _global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements); - GlobalVariables global_variables; + /* SHADER API */ - int32_t _global_variable_allocate(uint32_t p_elements); - void _global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value); - void _global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements); + struct Material; - /* SHADER API */ + struct Shader { + ShaderData *data = nullptr; + String code; + String path_hint; + ShaderType type; + HashMap<StringName, HashMap<int, RID>> default_texture_parameter; + HashSet<Material *> owners; + }; + typedef ShaderData *(*ShaderDataRequestFunction)(); ShaderDataRequestFunction shader_data_request_func[SHADER_TYPE_MAX]; + mutable RID_Owner<Shader, true> shader_owner; + Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); } /* MATERIAL API */ + + typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *); + + struct Material { + RID self; + MaterialData *data = nullptr; + Shader *shader = nullptr; + //shortcut to shader data and type + ShaderType shader_type = SHADER_TYPE_MAX; + uint32_t shader_id = 0; + bool uniform_dirty = false; + bool texture_dirty = false; + HashMap<StringName, Variant> params; + int32_t priority = 0; + RID next_pass; + SelfList<Material> update_element; + + Dependency dependency; + + Material() : + update_element(this) {} + }; + MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX]; mutable RID_Owner<Material, true> material_owner; + Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); }; SelfList<Material>::List material_update_list; @@ -333,32 +328,31 @@ public: RID get_quad_index_array() { return quad_index_array; } - /* GLOBAL VARIABLE API */ + /* GLOBAL SHADER UNIFORM API */ - void _update_global_variables(); + void _update_global_shader_uniforms(); - virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override; - virtual void global_variable_remove(const StringName &p_name) override; - virtual Vector<StringName> global_variable_get_list() const override; + virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override; + virtual void global_shader_uniform_remove(const StringName &p_name) override; + virtual Vector<StringName> global_shader_uniform_get_list() const override; - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) override; - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) override; - virtual Variant global_variable_get(const StringName &p_name) const override; - virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override; - RS::GlobalVariableType global_variable_get_type_internal(const StringName &p_name) const; + virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override; + virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override; + virtual Variant global_shader_uniform_get(const StringName &p_name) const override; + virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override; + RS::GlobalShaderUniformType global_shader_uniform_get_type_internal(const StringName &p_name) const; - virtual void global_variables_load_settings(bool p_load_textures = true) override; - virtual void global_variables_clear() override; + virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override; + virtual void global_shader_uniforms_clear() override; - virtual int32_t global_variables_instance_allocate(RID p_instance) override; - virtual void global_variables_instance_free(RID p_instance) override; - virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override; + virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override; + virtual void global_shader_uniforms_instance_free(RID p_instance) override; + virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override; - RID global_variables_get_storage_buffer() const; + RID global_shader_uniforms_get_storage_buffer() const; /* SHADER API */ - Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); }; bool owns_shader(RID p_rid) { return shader_owner.owns(p_rid); }; virtual RID shader_allocate() override; @@ -368,7 +362,7 @@ public: virtual void shader_set_code(RID p_shader, const String &p_code) override; virtual void shader_set_path_hint(RID p_shader, const String &p_path) override; virtual String shader_get_code(RID p_shader) const override; - virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; + virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override; virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override; @@ -379,7 +373,6 @@ public: /* MATERIAL API */ - Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); }; bool owns_material(RID p_rid) { return material_owner.owns(p_rid); }; void _material_queue_update(Material *material, bool p_uniform, bool p_texture); @@ -390,6 +383,7 @@ public: virtual void material_free(RID p_rid) override; virtual void material_set_shader(RID p_material, RID p_shader) override; + ShaderData *material_get_shader_data(RID p_material); virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override; virtual Variant material_get_param(RID p_material, const StringName &p_param) const override; @@ -400,7 +394,7 @@ public: virtual bool material_is_animated(RID p_material) override; virtual bool material_casts_shadows(RID p_material) override; - virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override; + virtual void material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) override; virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override; diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index 3875eb6615..dc3f35f942 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -758,6 +758,13 @@ bool MeshStorage::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) { return mesh->blend_shape_count > 0 || (mesh->has_bone_weights && p_has_skeleton); } +Dependency *MeshStorage::mesh_get_dependency(RID p_mesh) const { + Mesh *mesh = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_COND_V(!mesh, nullptr); + + return &mesh->dependency; +} + /* MESH INSTANCE */ RID MeshStorage::mesh_instance_create(RID p_base) { @@ -1473,6 +1480,13 @@ RID MeshStorage::multimesh_get_mesh(RID p_multimesh) const { return multimesh->mesh; } +Dependency *MeshStorage::multimesh_get_dependency(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + ERR_FAIL_COND_V(!multimesh, nullptr); + + return &multimesh->dependency; +} + Transform3D MeshStorage::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, Transform3D()); diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index 396fe9b6a6..5c0d019c15 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -40,240 +40,151 @@ namespace RendererRD { -/* Mesh */ - -enum DefaultRDBuffer { - DEFAULT_RD_BUFFER_VERTEX, - DEFAULT_RD_BUFFER_NORMAL, - DEFAULT_RD_BUFFER_TANGENT, - DEFAULT_RD_BUFFER_COLOR, - DEFAULT_RD_BUFFER_TEX_UV, - DEFAULT_RD_BUFFER_TEX_UV2, - DEFAULT_RD_BUFFER_CUSTOM0, - DEFAULT_RD_BUFFER_CUSTOM1, - DEFAULT_RD_BUFFER_CUSTOM2, - DEFAULT_RD_BUFFER_CUSTOM3, - DEFAULT_RD_BUFFER_BONES, - DEFAULT_RD_BUFFER_WEIGHTS, - DEFAULT_RD_BUFFER_MAX, -}; +class MeshStorage : public RendererMeshStorage { +public: + enum DefaultRDBuffer { + DEFAULT_RD_BUFFER_VERTEX, + DEFAULT_RD_BUFFER_NORMAL, + DEFAULT_RD_BUFFER_TANGENT, + DEFAULT_RD_BUFFER_COLOR, + DEFAULT_RD_BUFFER_TEX_UV, + DEFAULT_RD_BUFFER_TEX_UV2, + DEFAULT_RD_BUFFER_CUSTOM0, + DEFAULT_RD_BUFFER_CUSTOM1, + DEFAULT_RD_BUFFER_CUSTOM2, + DEFAULT_RD_BUFFER_CUSTOM3, + DEFAULT_RD_BUFFER_BONES, + DEFAULT_RD_BUFFER_WEIGHTS, + DEFAULT_RD_BUFFER_MAX, + }; -struct MeshInstance; - -struct Mesh { - struct Surface { - RS::PrimitiveType primitive = RS::PRIMITIVE_POINTS; - uint32_t format = 0; - - RID vertex_buffer; - RID attribute_buffer; - RID skin_buffer; - uint32_t vertex_count = 0; - uint32_t vertex_buffer_size = 0; - uint32_t skin_buffer_size = 0; - - // A different pipeline needs to be allocated - // depending on the inputs available in the - // material. - // There are never that many geometry/material - // combinations, so a simple array is the most - // cache-efficient structure. - - struct Version { - uint32_t input_mask = 0; - RD::VertexFormatID vertex_format = 0; - RID vertex_array; - }; +private: + static MeshStorage *singleton; - SpinLock version_lock; //needed to access versions - Version *versions = nullptr; //allocated on demand - uint32_t version_count = 0; + RID default_rd_storage_buffer; - RID index_buffer; - RID index_array; - uint32_t index_count = 0; + /* Mesh */ - struct LOD { - float edge_length = 0.0; - uint32_t index_count = 0; - RID index_buffer; - RID index_array; - }; + RID mesh_default_rd_buffers[DEFAULT_RD_BUFFER_MAX]; - LOD *lods = nullptr; - uint32_t lod_count = 0; + struct MeshInstance; + + struct Mesh { + struct Surface { + RS::PrimitiveType primitive = RS::PRIMITIVE_POINTS; + uint32_t format = 0; + + RID vertex_buffer; + RID attribute_buffer; + RID skin_buffer; + uint32_t vertex_count = 0; + uint32_t vertex_buffer_size = 0; + uint32_t skin_buffer_size = 0; + + // A different pipeline needs to be allocated + // depending on the inputs available in the + // material. + // There are never that many geometry/material + // combinations, so a simple array is the most + // cache-efficient structure. + + struct Version { + uint32_t input_mask = 0; + RD::VertexFormatID vertex_format = 0; + RID vertex_array; + }; + + SpinLock version_lock; //needed to access versions + Version *versions = nullptr; //allocated on demand + uint32_t version_count = 0; - AABB aabb; + RID index_buffer; + RID index_array; + uint32_t index_count = 0; - Vector<AABB> bone_aabbs; + struct LOD { + float edge_length = 0.0; + uint32_t index_count = 0; + RID index_buffer; + RID index_array; + }; - RID blend_shape_buffer; + LOD *lods = nullptr; + uint32_t lod_count = 0; - RID material; + AABB aabb; - uint32_t render_index = 0; - uint64_t render_pass = 0; + Vector<AABB> bone_aabbs; - uint32_t multimesh_render_index = 0; - uint64_t multimesh_render_pass = 0; + RID blend_shape_buffer; - uint32_t particles_render_index = 0; - uint64_t particles_render_pass = 0; + RID material; - RID uniform_set; - }; + uint32_t render_index = 0; + uint64_t render_pass = 0; - uint32_t blend_shape_count = 0; - RS::BlendShapeMode blend_shape_mode = RS::BLEND_SHAPE_MODE_NORMALIZED; + uint32_t multimesh_render_index = 0; + uint64_t multimesh_render_pass = 0; - Surface **surfaces = nullptr; - uint32_t surface_count = 0; + uint32_t particles_render_index = 0; + uint64_t particles_render_pass = 0; - Vector<AABB> bone_aabbs; + RID uniform_set; + }; - bool has_bone_weights = false; + uint32_t blend_shape_count = 0; + RS::BlendShapeMode blend_shape_mode = RS::BLEND_SHAPE_MODE_NORMALIZED; - AABB aabb; - AABB custom_aabb; + Surface **surfaces = nullptr; + uint32_t surface_count = 0; - Vector<RID> material_cache; + Vector<AABB> bone_aabbs; - List<MeshInstance *> instances; + bool has_bone_weights = false; - RID shadow_mesh; - HashSet<Mesh *> shadow_owners; + AABB aabb; + AABB custom_aabb; - Dependency dependency; -}; + Vector<RID> material_cache; -/* Mesh Instance */ + List<MeshInstance *> instances; -struct MeshInstance { - Mesh *mesh = nullptr; - RID skeleton; - struct Surface { - RID vertex_buffer; - RID uniform_set; + RID shadow_mesh; + HashSet<Mesh *> shadow_owners; - Mesh::Surface::Version *versions = nullptr; //allocated on demand - uint32_t version_count = 0; + Dependency dependency; }; - LocalVector<Surface> surfaces; - LocalVector<float> blend_weights; - - RID blend_weights_buffer; - List<MeshInstance *>::Element *I = nullptr; //used to erase itself - uint64_t skeleton_version = 0; - bool dirty = false; - bool weights_dirty = false; - SelfList<MeshInstance> weight_update_list; - SelfList<MeshInstance> array_update_list; - MeshInstance() : - weight_update_list(this), array_update_list(this) {} -}; - -/* MultiMesh */ - -struct MultiMesh { - RID mesh; - int instances = 0; - RS::MultimeshTransformFormat xform_format = RS::MULTIMESH_TRANSFORM_3D; - bool uses_colors = false; - bool uses_custom_data = false; - int visible_instances = -1; - AABB aabb; - bool aabb_dirty = false; - bool buffer_set = false; - uint32_t stride_cache = 0; - uint32_t color_offset_cache = 0; - uint32_t custom_data_offset_cache = 0; - - Vector<float> data_cache; //used if individual setting is used - bool *data_cache_dirty_regions = nullptr; - uint32_t data_cache_used_dirty_regions = 0; - - RID buffer; //storage buffer - RID uniform_set_3d; - RID uniform_set_2d; - - bool dirty = false; - MultiMesh *dirty_list = nullptr; - - Dependency dependency; -}; -/* Skeleton */ - -struct SkeletonShader { - struct PushConstant { - uint32_t has_normal; - uint32_t has_tangent; - uint32_t has_skeleton; - uint32_t has_blend_shape; + mutable RID_Owner<Mesh, true> mesh_owner; - uint32_t vertex_count; - uint32_t vertex_stride; - uint32_t skin_stride; - uint32_t skin_weight_offset; + /* Mesh Instance API */ - uint32_t blend_shape_count; - uint32_t normalized_blend_shapes; - uint32_t pad0; - uint32_t pad1; - }; + struct MeshInstance { + Mesh *mesh = nullptr; + RID skeleton; + struct Surface { + RID vertex_buffer; + RID uniform_set; - enum { - UNIFORM_SET_INSTANCE = 0, - UNIFORM_SET_SURFACE = 1, - UNIFORM_SET_SKELETON = 2, - }; - enum { - SHADER_MODE_2D, - SHADER_MODE_3D, - SHADER_MODE_MAX + Mesh::Surface::Version *versions = nullptr; //allocated on demand + uint32_t version_count = 0; + }; + LocalVector<Surface> surfaces; + LocalVector<float> blend_weights; + + RID blend_weights_buffer; + List<MeshInstance *>::Element *I = nullptr; //used to erase itself + uint64_t skeleton_version = 0; + bool dirty = false; + bool weights_dirty = false; + SelfList<MeshInstance> weight_update_list; + SelfList<MeshInstance> array_update_list; + MeshInstance() : + weight_update_list(this), array_update_list(this) {} }; - SkeletonShaderRD shader; - RID version; - RID version_shader[SHADER_MODE_MAX]; - RID pipeline[SHADER_MODE_MAX]; - - RID default_skeleton_uniform_set; -}; - -struct Skeleton { - bool use_2d = false; - int size = 0; - Vector<float> data; - RID buffer; - - bool dirty = false; - Skeleton *dirty_list = nullptr; - Transform2D base_transform_2d; - - RID uniform_set_3d; - RID uniform_set_mi; - - uint64_t version = 1; - - Dependency dependency; -}; - -class MeshStorage : public RendererMeshStorage { -private: - static MeshStorage *singleton; - - RID mesh_default_rd_buffers[DEFAULT_RD_BUFFER_MAX]; - RID default_rd_storage_buffer; - - /* Mesh */ - - mutable RID_Owner<Mesh, true> mesh_owner; - void _mesh_surface_generate_version_for_input_mask(Mesh::Surface::Version &v, Mesh::Surface *s, uint32_t p_input_mask, MeshInstance::Surface *mis = nullptr); - /* Mesh Instance API */ - void _mesh_instance_clear(MeshInstance *mi); void _mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint32_t p_surface); @@ -284,6 +195,34 @@ private: /* MultiMesh */ + struct MultiMesh { + RID mesh; + int instances = 0; + RS::MultimeshTransformFormat xform_format = RS::MULTIMESH_TRANSFORM_3D; + bool uses_colors = false; + bool uses_custom_data = false; + int visible_instances = -1; + AABB aabb; + bool aabb_dirty = false; + bool buffer_set = false; + uint32_t stride_cache = 0; + uint32_t color_offset_cache = 0; + uint32_t custom_data_offset_cache = 0; + + Vector<float> data_cache; //used if individual setting is used + bool *data_cache_dirty_regions = nullptr; + uint32_t data_cache_used_dirty_regions = 0; + + RID buffer; //storage buffer + RID uniform_set_3d; + RID uniform_set_2d; + + bool dirty = false; + MultiMesh *dirty_list = nullptr; + + Dependency dependency; + }; + mutable RID_Owner<MultiMesh, true> multimesh_owner; MultiMesh *multimesh_dirty_list = nullptr; @@ -295,7 +234,60 @@ private: /* Skeleton */ - SkeletonShader skeleton_shader; + struct SkeletonShader { + struct PushConstant { + uint32_t has_normal; + uint32_t has_tangent; + uint32_t has_skeleton; + uint32_t has_blend_shape; + + uint32_t vertex_count; + uint32_t vertex_stride; + uint32_t skin_stride; + uint32_t skin_weight_offset; + + uint32_t blend_shape_count; + uint32_t normalized_blend_shapes; + uint32_t pad0; + uint32_t pad1; + }; + + enum { + UNIFORM_SET_INSTANCE = 0, + UNIFORM_SET_SURFACE = 1, + UNIFORM_SET_SKELETON = 2, + }; + enum { + SHADER_MODE_2D, + SHADER_MODE_3D, + SHADER_MODE_MAX + }; + + SkeletonShaderRD shader; + RID version; + RID version_shader[SHADER_MODE_MAX]; + RID pipeline[SHADER_MODE_MAX]; + + RID default_skeleton_uniform_set; + } skeleton_shader; + + struct Skeleton { + bool use_2d = false; + int size = 0; + Vector<float> data; + RID buffer; + + bool dirty = false; + Skeleton *dirty_list = nullptr; + Transform2D base_transform_2d; + + RID uniform_set_3d; + RID uniform_set_mi; + + uint64_t version = 1; + + Dependency dependency; + }; mutable RID_Owner<Skeleton, true> skeleton_owner; @@ -309,11 +301,10 @@ public: MeshStorage(); virtual ~MeshStorage(); - RID get_default_rd_storage_buffer() { return default_rd_storage_buffer; } + RID get_default_rd_storage_buffer() const { return default_rd_storage_buffer; } /* MESH API */ - Mesh *get_mesh(RID p_rid) { return mesh_owner.get_or_null(p_rid); }; bool owns_mesh(RID p_rid) { return mesh_owner.owns(p_rid); }; virtual RID mesh_allocate() override; @@ -542,10 +533,11 @@ public: return s->particles_render_index; } + Dependency *mesh_get_dependency(RID p_mesh) const; + /* MESH INSTANCE API */ - MeshInstance *get_mesh_instance(RID p_rid) { return mesh_instance_owner.get_or_null(p_rid); }; - bool owns_mesh_instance(RID p_rid) { return mesh_instance_owner.owns(p_rid); }; + bool owns_mesh_instance(RID p_rid) const { return mesh_instance_owner.owns(p_rid); }; virtual RID mesh_instance_create(RID p_base) override; virtual void mesh_instance_free(RID p_rid) override; @@ -556,7 +548,6 @@ public: /* MULTIMESH API */ - MultiMesh *get_multimesh(RID p_rid) { return multimesh_owner.get_or_null(p_rid); }; bool owns_multimesh(RID p_rid) { return multimesh_owner.owns(p_rid); }; virtual RID multimesh_allocate() override; @@ -654,10 +645,11 @@ public: return multimesh->uniform_set_2d; } + Dependency *multimesh_get_dependency(RID p_multimesh) const; + /* SKELETON API */ - Skeleton *get_skeleton(RID p_rid) { return skeleton_owner.get_or_null(p_rid); }; - bool owns_skeleton(RID p_rid) { return skeleton_owner.owns(p_rid); }; + bool owns_skeleton(RID p_rid) const { return skeleton_owner.owns(p_rid); }; virtual RID skeleton_allocate() override; virtual void skeleton_initialize(RID p_skeleton) override; diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 75977c5bc9..ba644e7eb9 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -54,8 +54,8 @@ ParticlesStorage::ParticlesStorage() { particles_modes.push_back(""); particles_shader.shader.initialize(particles_modes, String()); } - MaterialStorage::get_singleton()->shader_set_data_request_function(SHADER_TYPE_PARTICLES, _create_particles_shader_funcs); - MaterialStorage::get_singleton()->material_set_data_request_function(SHADER_TYPE_PARTICLES, _create_particles_material_funcs); + MaterialStorage::get_singleton()->shader_set_data_request_function(MaterialStorage::SHADER_TYPE_PARTICLES, _create_particles_shader_funcs); + MaterialStorage::get_singleton()->material_set_data_request_function(MaterialStorage::SHADER_TYPE_PARTICLES, _create_particles_material_funcs); { ShaderCompiler::DefaultIdentifierActions actions; @@ -112,7 +112,7 @@ ParticlesStorage::ParticlesStorage() { actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; particles_shader.compiler.initialize(actions); } @@ -134,7 +134,7 @@ void process() { material_storage->material_initialize(particles_shader.default_material); material_storage->material_set_shader(particles_shader.default_material, particles_shader.default_shader); - ParticlesMaterialData *md = static_cast<ParticlesMaterialData *>(material_storage->material_get_data(particles_shader.default_material, SHADER_TYPE_PARTICLES)); + ParticlesMaterialData *md = static_cast<ParticlesMaterialData *>(material_storage->material_get_data(particles_shader.default_material, MaterialStorage::SHADER_TYPE_PARTICLES)); particles_shader.default_shader_rd = particles_shader.shader.version_get_shader(md->shader_data->version, 0); Vector<RD::Uniform> uniforms; @@ -164,7 +164,7 @@ void process() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.append_id(material_storage->global_variables_get_storage_buffer()); + u.append_id(material_storage->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -987,14 +987,13 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta for (uint32_t i = 0; i < ParticlesFrameParams::MAX_3D_TEXTURES; i++) { RID rd_tex; if (i < collision_3d_textures_used) { - Texture *t = TextureStorage::get_singleton()->get_texture(collision_3d_textures[i]); - if (t && t->type == Texture::TYPE_3D) { - rd_tex = t->rd_texture; + if (TextureStorage::get_singleton()->texture_get_type(collision_3d_textures[i]) == TextureStorage::TYPE_3D) { + rd_tex = TextureStorage::get_singleton()->texture_get_rd_texture(collision_3d_textures[i]); } } if (rd_tex == RID()) { - rd_tex = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_3D_WHITE); + rd_tex = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); } u.append_id(rd_tex); } @@ -1007,7 +1006,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta if (collision_heightmap_texture.is_valid()) { u.append_id(collision_heightmap_texture); } else { - u.append_id(texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_BLACK)); } uniforms.push_back(u); } @@ -1073,9 +1072,9 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta RD::get_singleton()->buffer_update(p_particles->frame_params_buffer, 0, sizeof(ParticlesFrameParams) * p_particles->trail_params.size(), p_particles->trail_params.ptr()); - ParticlesMaterialData *m = static_cast<ParticlesMaterialData *>(material_storage->material_get_data(p_particles->process_material, SHADER_TYPE_PARTICLES)); + ParticlesMaterialData *m = static_cast<ParticlesMaterialData *>(material_storage->material_get_data(p_particles->process_material, MaterialStorage::SHADER_TYPE_PARTICLES)); if (!m) { - m = static_cast<ParticlesMaterialData *>(material_storage->material_get_data(particles_shader.default_material, SHADER_TYPE_PARTICLES)); + m = static_cast<ParticlesMaterialData *>(material_storage->material_get_data(particles_shader.default_material, MaterialStorage::SHADER_TYPE_PARTICLES)); } ERR_FAIL_COND(!m); @@ -1228,10 +1227,10 @@ void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p void ParticlesStorage::_particles_update_buffers(Particles *particles) { uint32_t userdata_count = 0; - const Material *material = MaterialStorage::get_singleton()->get_material(particles->process_material); - if (material && material->shader && material->shader->data) { - const ParticlesShaderData *shader_data = static_cast<const ParticlesShaderData *>(material->shader->data); - userdata_count = shader_data->userdata_count; + MaterialStorage::ShaderData *shader_data = MaterialStorage::get_singleton()->material_get_shader_data(particles->process_material); + if (shader_data) { + const ParticlesShaderData *particle_shader_data = static_cast<const ParticlesShaderData *>(shader_data); + userdata_count = particle_shader_data->userdata_count; } if (userdata_count != particles->userdata_count) { @@ -1503,6 +1502,13 @@ void ParticlesStorage::update_particles() { } } +Dependency *ParticlesStorage::particles_get_dependency(RID p_particles) const { + Particles *particles = particles_owner.get_or_null(p_particles); + ERR_FAIL_NULL_V(particles, nullptr); + + return &particles->dependency; +} + bool ParticlesStorage::particles_is_inactive(RID p_particles) const { ERR_FAIL_COND_V_MSG(RSG::threaded, false, "This function should never be used with threaded rendering, as it stalls the renderer."); const Particles *particles = particles_owner.get_or_null(p_particles); @@ -1597,7 +1603,7 @@ void ParticlesStorage::ParticlesShaderData::set_default_texture_param(const Stri } } -void ParticlesStorage::ParticlesShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void ParticlesStorage::ParticlesShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { @@ -1685,7 +1691,7 @@ ParticlesStorage::ParticlesShaderData::~ParticlesShaderData() { } } -ShaderData *ParticlesStorage::_create_particles_shader_func() { +MaterialStorage::ShaderData *ParticlesStorage::_create_particles_shader_func() { ParticlesShaderData *shader_data = memnew(ParticlesShaderData); return shader_data; } @@ -1698,7 +1704,7 @@ ParticlesStorage::ParticlesMaterialData::~ParticlesMaterialData() { free_parameters_uniform_set(uniform_set); } -MaterialData *ParticlesStorage::_create_particles_material_func(ParticlesShaderData *p_shader) { +MaterialStorage::MaterialData *ParticlesStorage::_create_particles_material_func(ParticlesShaderData *p_shader) { ParticlesMaterialData *material_data = memnew(ParticlesMaterialData); material_data->shader_data = p_shader; //update will happen later anyway so do nothing. @@ -1884,6 +1890,15 @@ bool ParticlesStorage::particles_collision_is_heightfield(RID p_particles_collis return particles_collision->type == RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE; } +Dependency *ParticlesStorage::particles_collision_get_dependency(RID p_particles_collision) const { + ParticlesCollision *pc = particles_collision_owner.get_or_null(p_particles_collision); + ERR_FAIL_NULL_V(pc, nullptr); + + return &pc->dependency; +} + +/* Particles collision instance */ + RID ParticlesStorage::particles_collision_instance_create(RID p_collision) { ParticlesCollisionInstance pci; pci.collision = p_collision; diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index 75f995deeb..97d100e2da 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -43,231 +43,203 @@ namespace RendererRD { -/* PARTICLES */ - -struct ParticleData { - float xform[16]; - float velocity[3]; - uint32_t active; - float color[4]; - float custom[3]; - float lifetime; -}; +class ParticlesStorage : public RendererParticlesStorage { +private: + static ParticlesStorage *singleton; -struct ParticlesFrameParams { - enum { - MAX_ATTRACTORS = 32, - MAX_COLLIDERS = 32, - MAX_3D_TEXTURES = 7 - }; + /* PARTICLES */ - enum AttractorType { - ATTRACTOR_TYPE_SPHERE, - ATTRACTOR_TYPE_BOX, - ATTRACTOR_TYPE_VECTOR_FIELD, + struct ParticleData { + float xform[16]; + float velocity[3]; + uint32_t active; + float color[4]; + float custom[3]; + float lifetime; }; - struct Attractor { - float transform[16]; - float extents[3]; //exents or radius - uint32_t type; + struct ParticlesFrameParams { + enum { + MAX_ATTRACTORS = 32, + MAX_COLLIDERS = 32, + MAX_3D_TEXTURES = 7 + }; - uint32_t texture_index; //texture index for vector field - float strength; - float attenuation; - float directionality; - }; + enum AttractorType { + ATTRACTOR_TYPE_SPHERE, + ATTRACTOR_TYPE_BOX, + ATTRACTOR_TYPE_VECTOR_FIELD, + }; - enum CollisionType { - COLLISION_TYPE_SPHERE, - COLLISION_TYPE_BOX, - COLLISION_TYPE_SDF, - COLLISION_TYPE_HEIGHT_FIELD, - COLLISION_TYPE_2D_SDF, + struct Attractor { + float transform[16]; + float extents[3]; //exents or radius + uint32_t type; - }; + uint32_t texture_index; //texture index for vector field + float strength; + float attenuation; + float directionality; + }; - struct Collider { - float transform[16]; - float extents[3]; //exents or radius - uint32_t type; + enum CollisionType { + COLLISION_TYPE_SPHERE, + COLLISION_TYPE_BOX, + COLLISION_TYPE_SDF, + COLLISION_TYPE_HEIGHT_FIELD, + COLLISION_TYPE_2D_SDF, - uint32_t texture_index; //texture index for vector field - real_t scale; - uint32_t pad[2]; - }; + }; - uint32_t emitting; - float system_phase; - float prev_system_phase; - uint32_t cycle; + struct Collider { + float transform[16]; + float extents[3]; //exents or radius + uint32_t type; - real_t explosiveness; - real_t randomness; - float time; - float delta; + uint32_t texture_index; //texture index for vector field + real_t scale; + uint32_t pad[2]; + }; - uint32_t frame; - uint32_t pad0; - uint32_t pad1; - uint32_t pad2; + uint32_t emitting; + float system_phase; + float prev_system_phase; + uint32_t cycle; - uint32_t random_seed; - uint32_t attractor_count; - uint32_t collider_count; - float particle_size; + real_t explosiveness; + real_t randomness; + float time; + float delta; - float emission_transform[16]; + uint32_t frame; + uint32_t pad0; + uint32_t pad1; + uint32_t pad2; - Attractor attractors[MAX_ATTRACTORS]; - Collider colliders[MAX_COLLIDERS]; -}; + uint32_t random_seed; + uint32_t attractor_count; + uint32_t collider_count; + float particle_size; -struct ParticleEmissionBufferData { -}; + float emission_transform[16]; -struct ParticleEmissionBuffer { - struct Data { - float xform[16]; - float velocity[3]; - uint32_t flags; - float color[4]; - float custom[4]; + Attractor attractors[MAX_ATTRACTORS]; + Collider colliders[MAX_COLLIDERS]; }; - int32_t particle_count; - int32_t particle_max; - uint32_t pad1; - uint32_t pad2; - Data data[1]; //its 2020 and empty arrays are still non standard in C++ -}; - -struct Particles { - RS::ParticlesMode mode = RS::PARTICLES_MODE_3D; - bool inactive = true; - double inactive_time = 0.0; - bool emitting = false; - bool one_shot = false; - int amount = 0; - double lifetime = 1.0; - double pre_process_time = 0.0; - real_t explosiveness = 0.0; - real_t randomness = 0.0; - bool restart_request = false; - AABB custom_aabb = AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8)); - bool use_local_coords = true; - bool has_collision_cache = false; - - bool has_sdf_collision = false; - Transform2D sdf_collision_transform; - Rect2 sdf_collision_to_screen; - RID sdf_collision_texture; - - RID process_material; - uint32_t frame_counter = 0; - RS::ParticlesTransformAlign transform_align = RS::PARTICLES_TRANSFORM_ALIGN_DISABLED; - - RS::ParticlesDrawOrder draw_order = RS::PARTICLES_DRAW_ORDER_INDEX; - - Vector<RID> draw_passes; - Vector<Transform3D> trail_bind_poses; - bool trail_bind_poses_dirty = false; - RID trail_bind_pose_buffer; - RID trail_bind_pose_uniform_set; - - RID particle_buffer; - RID particle_instance_buffer; - RID frame_params_buffer; - - uint32_t userdata_count = 0; - - RID particles_material_uniform_set; - RID particles_copy_uniform_set; - RID particles_transforms_buffer_uniform_set; - RID collision_textures_uniform_set; - - RID collision_3d_textures[ParticlesFrameParams::MAX_3D_TEXTURES]; - uint32_t collision_3d_textures_used = 0; - RID collision_heightmap_texture; + struct ParticleEmissionBufferData { + }; - RID particles_sort_buffer; - RID particles_sort_uniform_set; + struct ParticleEmissionBuffer { + struct Data { + float xform[16]; + float velocity[3]; + uint32_t flags; + float color[4]; + float custom[4]; + }; - bool dirty = false; - Particles *update_list = nullptr; + int32_t particle_count; + int32_t particle_max; + uint32_t pad1; + uint32_t pad2; + Data data[1]; //its 2020 and empty arrays are still non standard in C++ + }; - RID sub_emitter; + struct Particles { + RS::ParticlesMode mode = RS::PARTICLES_MODE_3D; + bool inactive = true; + double inactive_time = 0.0; + bool emitting = false; + bool one_shot = false; + int amount = 0; + double lifetime = 1.0; + double pre_process_time = 0.0; + real_t explosiveness = 0.0; + real_t randomness = 0.0; + bool restart_request = false; + AABB custom_aabb = AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8)); + bool use_local_coords = false; + bool has_collision_cache = false; + + bool has_sdf_collision = false; + Transform2D sdf_collision_transform; + Rect2 sdf_collision_to_screen; + RID sdf_collision_texture; + + RID process_material; + uint32_t frame_counter = 0; + RS::ParticlesTransformAlign transform_align = RS::PARTICLES_TRANSFORM_ALIGN_DISABLED; + + RS::ParticlesDrawOrder draw_order = RS::PARTICLES_DRAW_ORDER_INDEX; + + Vector<RID> draw_passes; + Vector<Transform3D> trail_bind_poses; + bool trail_bind_poses_dirty = false; + RID trail_bind_pose_buffer; + RID trail_bind_pose_uniform_set; + + RID particle_buffer; + RID particle_instance_buffer; + RID frame_params_buffer; - double phase = 0.0; - double prev_phase = 0.0; - uint64_t prev_ticks = 0; - uint32_t random_seed = 0; + uint32_t userdata_count = 0; - uint32_t cycle_number = 0; + RID particles_material_uniform_set; + RID particles_copy_uniform_set; + RID particles_transforms_buffer_uniform_set; + RID collision_textures_uniform_set; - double speed_scale = 1.0; + RID collision_3d_textures[ParticlesFrameParams::MAX_3D_TEXTURES]; + uint32_t collision_3d_textures_used = 0; + RID collision_heightmap_texture; - int fixed_fps = 30; - bool interpolate = true; - bool fractional_delta = false; - double frame_remainder = 0; - real_t collision_base_size = 0.01; + RID particles_sort_buffer; + RID particles_sort_uniform_set; - bool clear = true; + bool dirty = false; + Particles *update_list = nullptr; - bool force_sub_emit = false; + RID sub_emitter; - Transform3D emission_transform; + double phase = 0.0; + double prev_phase = 0.0; + uint64_t prev_ticks = 0; + uint32_t random_seed = 0; - Vector<uint8_t> emission_buffer_data; + uint32_t cycle_number = 0; - ParticleEmissionBuffer *emission_buffer = nullptr; - RID emission_storage_buffer; + double speed_scale = 1.0; - HashSet<RID> collisions; + int fixed_fps = 30; + bool interpolate = true; + bool fractional_delta = false; + double frame_remainder = 0; + real_t collision_base_size = 0.01; - Dependency dependency; + bool clear = true; - double trail_length = 1.0; - bool trails_enabled = false; - LocalVector<ParticlesFrameParams> frame_history; - LocalVector<ParticlesFrameParams> trail_params; + bool force_sub_emit = false; - Particles() { - } -}; + Transform3D emission_transform; -/* Particles Collision */ + Vector<uint8_t> emission_buffer_data; -struct ParticlesCollision { - RS::ParticlesCollisionType type = RS::PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT; - uint32_t cull_mask = 0xFFFFFFFF; - float radius = 1.0; - Vector3 extents = Vector3(1, 1, 1); - float attractor_strength = 1.0; - float attractor_attenuation = 1.0; - float attractor_directionality = 0.0; - RID field_texture; - RID heightfield_texture; - RID heightfield_fb; - Size2i heightfield_fb_size; + ParticleEmissionBuffer *emission_buffer = nullptr; + RID emission_storage_buffer; - RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024; + HashSet<RID> collisions; - Dependency dependency; -}; + Dependency dependency; -struct ParticlesCollisionInstance { - RID collision; - Transform3D transform; - bool active = false; -}; + double trail_length = 1.0; + bool trails_enabled = false; + LocalVector<ParticlesFrameParams> frame_history; + LocalVector<ParticlesFrameParams> trail_params; -class ParticlesStorage : public RendererParticlesStorage { -private: - static ParticlesStorage *singleton; - - /* PARTICLES */ + Particles() { + } + }; void _particles_process(Particles *p_particles, double p_delta); void _particles_allocate_emission_buffer(Particles *particles); @@ -340,7 +312,7 @@ private: /* Particle Shader */ - struct ParticlesShaderData : public ShaderData { + struct ParticlesShaderData : public MaterialStorage::ShaderData { bool valid = false; RID version; bool uses_collision = false; @@ -365,7 +337,7 @@ private: virtual void set_code(const String &p_Code); virtual void set_path_hint(const String &p_hint); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; @@ -377,12 +349,12 @@ private: virtual ~ParticlesShaderData(); }; - ShaderData *_create_particles_shader_func(); - static ShaderData *_create_particles_shader_funcs() { + MaterialStorage::ShaderData *_create_particles_shader_func(); + static MaterialStorage::ShaderData *_create_particles_shader_funcs() { return ParticlesStorage::get_singleton()->_create_particles_shader_func(); } - struct ParticlesMaterialData : public MaterialData { + struct ParticlesMaterialData : public MaterialStorage::MaterialData { ParticlesShaderData *shader_data = nullptr; RID uniform_set; @@ -392,13 +364,37 @@ private: virtual ~ParticlesMaterialData(); }; - MaterialData *_create_particles_material_func(ParticlesShaderData *p_shader); - static MaterialData *_create_particles_material_funcs(ShaderData *p_shader) { + MaterialStorage::MaterialData *_create_particles_material_func(ParticlesShaderData *p_shader); + static MaterialStorage::MaterialData *_create_particles_material_funcs(MaterialStorage::ShaderData *p_shader) { return ParticlesStorage::get_singleton()->_create_particles_material_func(static_cast<ParticlesShaderData *>(p_shader)); } /* Particles Collision */ + struct ParticlesCollision { + RS::ParticlesCollisionType type = RS::PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT; + uint32_t cull_mask = 0xFFFFFFFF; + float radius = 1.0; + Vector3 extents = Vector3(1, 1, 1); + float attractor_strength = 1.0; + float attractor_attenuation = 1.0; + float attractor_directionality = 0.0; + RID field_texture; + RID heightfield_texture; + RID heightfield_fb; + Size2i heightfield_fb_size; + + RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024; + + Dependency dependency; + }; + + struct ParticlesCollisionInstance { + RID collision; + Transform3D transform; + bool active = false; + }; + mutable RID_Owner<ParticlesCollision, true> particles_collision_owner; mutable RID_Owner<ParticlesCollisionInstance> particles_collision_instance_owner; @@ -411,7 +407,6 @@ public: /* PARTICLES */ - Particles *get_particles(RID p_rid) { return particles_owner.get_or_null(p_rid); } bool owns_particles(RID p_rid) { return particles_owner.owns(p_rid); } virtual RID particles_allocate() override; @@ -526,9 +521,10 @@ public: virtual void update_particles() override; + Dependency *particles_get_dependency(RID p_particles) const; + /* Particles Collision */ - ParticlesCollision *get_particles_collision(RID p_rid) { return particles_collision_owner.get_or_null(p_rid); } bool owns_particles_collision(RID p_rid) { return particles_collision_owner.owns(p_rid); } virtual RID particles_collision_allocate() override; @@ -550,8 +546,9 @@ public: virtual bool particles_collision_is_heightfield(RID p_particles_collision) const override; virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override; + Dependency *particles_collision_get_dependency(RID p_particles) const; + //used from 2D and 3D - ParticlesCollisionInstance *get_particles_collision_instance(RID p_rid) { return particles_collision_instance_owner.get_or_null(p_rid); } bool owns_particles_collision_instance(RID p_rid) { return particles_collision_instance_owner.owns(p_rid); } virtual RID particles_collision_instance_create(RID p_collision) override; diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index abf364b8b4..e20a04ff2a 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -35,9 +35,9 @@ using namespace RendererRD; /////////////////////////////////////////////////////////////////////////// -// CanvasTexture +// TextureStorage::CanvasTexture -void CanvasTexture::clear_sets() { +void TextureStorage::CanvasTexture::clear_sets() { if (cleared_cache) { return; } @@ -52,14 +52,14 @@ void CanvasTexture::clear_sets() { cleared_cache = true; } -CanvasTexture::~CanvasTexture() { +TextureStorage::CanvasTexture::~CanvasTexture() { clear_sets(); } /////////////////////////////////////////////////////////////////////////// -// Texture +// TextureStorage::Texture -void Texture::cleanup() { +void TextureStorage::Texture::cleanup() { if (RD::get_singleton()->texture_is_valid(rd_texture_srgb)) { //erase this first, as it's a dependency of the one below RD::get_singleton()->free(rd_texture_srgb); @@ -96,6 +96,7 @@ TextureStorage::TextureStorage() { Vector<uint8_t> pv; pv.resize(16 * 4); for (int i = 0; i < 16; i++) { + // Opaque white. pv.set(i * 4 + 0, 255); pv.set(i * 4 + 1, 255); pv.set(i * 4 + 2, 255); @@ -109,6 +110,7 @@ TextureStorage::TextureStorage() { } for (int i = 0; i < 16; i++) { + // Opaque black. pv.set(i * 4 + 0, 0); pv.set(i * 4 + 1, 0); pv.set(i * 4 + 2, 0); @@ -122,6 +124,21 @@ TextureStorage::TextureStorage() { } for (int i = 0; i < 16; i++) { + // Transparent black. + pv.set(i * 4 + 0, 0); + pv.set(i * 4 + 1, 0); + pv.set(i * 4 + 2, 0); + pv.set(i * 4 + 3, 0); + } + + { + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_TRANSPARENT] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + + for (int i = 0; i < 16; i++) { + // Opaque normal map "flat" color. pv.set(i * 4 + 0, 128); pv.set(i * 4 + 1, 128); pv.set(i * 4 + 2, 255); @@ -135,6 +152,7 @@ TextureStorage::TextureStorage() { } for (int i = 0; i < 16; i++) { + // Opaque flowmap "flat" color. pv.set(i * 4 + 0, 255); pv.set(i * 4 + 1, 128); pv.set(i * 4 + 2, 255); @@ -398,9 +416,8 @@ TextureStorage::TextureStorage() { tformat.format = RD::DATA_FORMAT_R8_UINT; tformat.width = 4; tformat.height = 4; - tformat.array_layers = 1; tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tformat.texture_type = RD::TEXTURE_TYPE_2D; Vector<uint8_t> pv; pv.resize(4 * 4); @@ -535,7 +552,7 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte ct = t->canvas_texture; } else { - ct = get_canvas_texture(p_texture); + ct = canvas_texture_owner.get_or_null(p_texture); } if (!ct) { @@ -658,7 +675,7 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im Texture texture; - texture.type = Texture::TYPE_2D; + texture.type = TextureStorage::TYPE_2D; texture.width = p_image->get_width(); texture.height = p_image->get_height(); @@ -754,7 +771,7 @@ void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<R Texture texture; - texture.type = Texture::TYPE_LAYERED; + texture.type = TextureStorage::TYPE_LAYERED; texture.layered_type = p_layered_type; texture.width = p_layers[0]->get_width(); @@ -884,7 +901,7 @@ void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format p_format Texture texture; - texture.type = Texture::TYPE_3D; + texture.type = TextureStorage::TYPE_3D; texture.width = p_width; texture.height = p_height; texture.depth = p_depth; @@ -976,7 +993,7 @@ void TextureStorage::_texture_2d_update(RID p_texture, const Ref<Image> &p_image ERR_FAIL_COND(p_image->get_width() != tex->width || p_image->get_height() != tex->height); ERR_FAIL_COND(p_image->get_format() != tex->format); - if (tex->type == Texture::TYPE_LAYERED) { + if (tex->type == TextureStorage::TYPE_LAYERED) { ERR_FAIL_INDEX(p_layer, tex->layers); } @@ -996,7 +1013,7 @@ void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, void TextureStorage::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) { Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); - ERR_FAIL_COND(tex->type != Texture::TYPE_3D); + ERR_FAIL_COND(tex->type != TextureStorage::TYPE_3D); Image::Image3DValidateError verr = Image::validate_3d_image(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps > 1, p_data); if (verr != Image::VALIDATE_3D_OK) { @@ -1168,7 +1185,7 @@ Ref<Image> TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) cons Vector<Ref<Image>> TextureStorage::texture_3d_get(RID p_texture) const { Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND_V(!tex, Vector<Ref<Image>>()); - ERR_FAIL_COND_V(tex->type != Texture::TYPE_3D, Vector<Ref<Image>>()); + ERR_FAIL_COND_V(tex->type != TextureStorage::TYPE_3D, Vector<Ref<Image>>()); Vector<uint8_t> all_data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0); @@ -1244,7 +1261,7 @@ void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) { void TextureStorage::texture_set_size_override(RID p_texture, int p_width, int p_height) { Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); - ERR_FAIL_COND(tex->type != Texture::TYPE_2D); + ERR_FAIL_COND(tex->type != TextureStorage::TYPE_2D); tex->width_2d = p_width; tex->height_2d = p_height; @@ -1856,6 +1873,13 @@ AABB TextureStorage::decal_get_aabb(RID p_decal) const { return AABB(-decal->extents, decal->extents * 2.0); } +Dependency *TextureStorage::decal_get_dependency(RID p_decal) { + Decal *decal = decal_owner.get_or_null(p_decal); + ERR_FAIL_COND_V(!decal, nullptr); + + return &decal->dependency; +} + void TextureStorage::update_decal_atlas() { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); ERR_FAIL_NULL(copy_effects); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 1a5a3dd023..682c951f63 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -38,248 +38,133 @@ namespace RendererRD { -enum DefaultRDTexture { - DEFAULT_RD_TEXTURE_WHITE, - DEFAULT_RD_TEXTURE_BLACK, - DEFAULT_RD_TEXTURE_NORMAL, - DEFAULT_RD_TEXTURE_ANISO, - DEFAULT_RD_TEXTURE_DEPTH, - DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER, - DEFAULT_RD_TEXTURE_CUBEMAP_BLACK, - DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK, - DEFAULT_RD_TEXTURE_CUBEMAP_WHITE, - DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_WHITE, - DEFAULT_RD_TEXTURE_3D_WHITE, - DEFAULT_RD_TEXTURE_3D_BLACK, - DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE, - DEFAULT_RD_TEXTURE_2D_UINT, - DEFAULT_RD_TEXTURE_VRS, - DEFAULT_RD_TEXTURE_MAX -}; +class LightStorage; +class MaterialStorage; -class CanvasTexture { +class TextureStorage : public RendererTextureStorage { public: - RID diffuse; - RID normal_map; - RID specular; - Color specular_color = Color(1, 1, 1, 1); - float shininess = 1.0; - - RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; - RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; - RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX]; - - Size2i size_cache = Size2i(1, 1); - bool use_normal_cache = false; - bool use_specular_cache = false; - bool cleared_cache = true; - - void clear_sets(); - ~CanvasTexture(); -}; + enum DefaultRDTexture { + DEFAULT_RD_TEXTURE_WHITE, + DEFAULT_RD_TEXTURE_BLACK, + DEFAULT_RD_TEXTURE_TRANSPARENT, + DEFAULT_RD_TEXTURE_NORMAL, + DEFAULT_RD_TEXTURE_ANISO, + DEFAULT_RD_TEXTURE_DEPTH, + DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER, + DEFAULT_RD_TEXTURE_CUBEMAP_BLACK, + DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK, + DEFAULT_RD_TEXTURE_CUBEMAP_WHITE, + DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_WHITE, + DEFAULT_RD_TEXTURE_3D_WHITE, + DEFAULT_RD_TEXTURE_3D_BLACK, + DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE, + DEFAULT_RD_TEXTURE_2D_UINT, + DEFAULT_RD_TEXTURE_VRS, + DEFAULT_RD_TEXTURE_MAX + }; -class Texture { -public: - enum Type { + enum TextureType { TYPE_2D, TYPE_LAYERED, TYPE_3D }; - Type type; - RS::TextureLayeredType layered_type = RS::TEXTURE_LAYERED_2D_ARRAY; - - RenderingDevice::TextureType rd_type; - RID rd_texture; - RID rd_texture_srgb; - RenderingDevice::DataFormat rd_format; - RenderingDevice::DataFormat rd_format_srgb; - - RD::TextureView rd_view; - - Image::Format format; - Image::Format validated_format; - - int width; - int height; - int depth; - int layers; - int mipmaps; - - int height_2d; - int width_2d; - - struct BufferSlice3D { - Size2i size; - uint32_t offset = 0; - uint32_t buffer_size = 0; - }; - Vector<BufferSlice3D> buffer_slices_3d; - uint32_t buffer_size_3d = 0; - - bool is_render_target; - bool is_proxy; - - Ref<Image> image_cache_2d; - String path; - - RID proxy_to; - Vector<RID> proxies; - - HashSet<RID> lightmap_users; - - RS::TextureDetectCallback detect_3d_callback = nullptr; - void *detect_3d_callback_ud = nullptr; - - RS::TextureDetectCallback detect_normal_callback = nullptr; - void *detect_normal_callback_ud = nullptr; +private: + friend class LightStorage; + friend class MaterialStorage; - RS::TextureDetectRoughnessCallback detect_roughness_callback = nullptr; - void *detect_roughness_callback_ud = nullptr; + static TextureStorage *singleton; - CanvasTexture *canvas_texture = nullptr; + RID default_rd_textures[DEFAULT_RD_TEXTURE_MAX]; - void cleanup(); -}; + /* Canvas Texture API */ -struct DecalAtlas { - struct Texture { - int panorama_to_dp_users; - int users; - Rect2 uv_rect; + class CanvasTexture { + public: + RID diffuse; + RID normal_map; + RID specular; + Color specular_color = Color(1, 1, 1, 1); + float shininess = 1.0; + + RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; + RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; + RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX]; + + Size2i size_cache = Size2i(1, 1); + bool use_normal_cache = false; + bool use_specular_cache = false; + bool cleared_cache = true; + + void clear_sets(); + ~CanvasTexture(); }; - struct SortItem { - RID texture; - Size2i pixel_size; - Size2i size; - Point2i pos; - - bool operator<(const SortItem &p_item) const { - //sort larger to smaller - if (size.height == p_item.size.height) { - return size.width > p_item.size.width; - } else { - return size.height > p_item.size.height; - } - } - }; + RID_Owner<CanvasTexture, true> canvas_texture_owner; - HashMap<RID, Texture> textures; - bool dirty = true; - int mipmaps = 5; + /* Texture API */ - RID texture; - RID texture_srgb; - struct MipMap { - RID fb; - RID texture; - Size2i size; - }; - Vector<MipMap> texture_mipmaps; + class Texture { + public: + TextureType type; + RS::TextureLayeredType layered_type = RS::TEXTURE_LAYERED_2D_ARRAY; - Size2i size; -}; + RenderingDevice::TextureType rd_type; + RID rd_texture; + RID rd_texture_srgb; + RenderingDevice::DataFormat rd_format; + RenderingDevice::DataFormat rd_format_srgb; -struct Decal { - Vector3 extents = Vector3(1, 1, 1); - RID textures[RS::DECAL_TEXTURE_MAX]; - float emission_energy = 1.0; - float albedo_mix = 1.0; - Color modulate = Color(1, 1, 1, 1); - uint32_t cull_mask = (1 << 20) - 1; - float upper_fade = 0.3; - float lower_fade = 0.3; - bool distance_fade = false; - float distance_fade_begin = 10; - float distance_fade_length = 1; - float normal_fade = 0.0; - - Dependency dependency; -}; + RD::TextureView rd_view; -struct RenderTarget { - Size2i size; - uint32_t view_count; - RID framebuffer; - RID color; + Image::Format format; + Image::Format validated_format; - //used for retrieving from CPU - RD::DataFormat color_format = RD::DATA_FORMAT_R4G4_UNORM_PACK8; - RD::DataFormat color_format_srgb = RD::DATA_FORMAT_R4G4_UNORM_PACK8; - Image::Format image_format = Image::FORMAT_L8; + int width; + int height; + int depth; + int layers; + int mipmaps; - bool is_transparent = false; + int height_2d; + int width_2d; - bool sdf_enabled = false; + struct BufferSlice3D { + Size2i size; + uint32_t offset = 0; + uint32_t buffer_size = 0; + }; + Vector<BufferSlice3D> buffer_slices_3d; + uint32_t buffer_size_3d = 0; - RID backbuffer; //used for effects - RID backbuffer_fb; - RID backbuffer_mipmap0; + bool is_render_target; + bool is_proxy; - Vector<RID> backbuffer_mipmaps; + Ref<Image> image_cache_2d; + String path; - RID framebuffer_uniform_set; - RID backbuffer_uniform_set; + RID proxy_to; + Vector<RID> proxies; - RID sdf_buffer_write; - RID sdf_buffer_write_fb; - RID sdf_buffer_process[2]; - RID sdf_buffer_read; - RID sdf_buffer_process_uniform_sets[2]; - RS::ViewportSDFOversize sdf_oversize = RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT; - RS::ViewportSDFScale sdf_scale = RS::VIEWPORT_SDF_SCALE_50_PERCENT; - Size2i process_size; + HashSet<RID> lightmap_users; - // VRS - RS::ViewportVRSMode vrs_mode = RS::VIEWPORT_VRS_DISABLED; - RID vrs_texture; + RS::TextureDetectCallback detect_3d_callback = nullptr; + void *detect_3d_callback_ud = nullptr; - //texture generated for this owner (nor RD). - RID texture; - bool was_used; + RS::TextureDetectCallback detect_normal_callback = nullptr; + void *detect_normal_callback_ud = nullptr; - //clear request - bool clear_requested; - Color clear_color; -}; + RS::TextureDetectRoughnessCallback detect_roughness_callback = nullptr; + void *detect_roughness_callback_ud = nullptr; -struct RenderTargetSDF { - enum { - SHADER_LOAD, - SHADER_LOAD_SHRINK, - SHADER_PROCESS, - SHADER_PROCESS_OPTIMIZED, - SHADER_STORE, - SHADER_STORE_SHRINK, - SHADER_MAX - }; + CanvasTexture *canvas_texture = nullptr; - struct PushConstant { - int32_t size[2]; - int32_t stride; - int32_t shift; - int32_t base_size[2]; - int32_t pad[2]; + void cleanup(); }; - CanvasSdfShaderRD shader; - RID shader_version; - RID pipelines[SHADER_MAX]; -}; - -class TextureStorage : public RendererTextureStorage { -private: - static TextureStorage *singleton; - - /* Canvas Texture API */ - - RID_Owner<RendererRD::CanvasTexture, true> canvas_texture_owner; - - /* Texture API */ - //textures can be created from threads, so this RID_Owner is thread safe mutable RID_Owner<Texture, true> texture_owner; + Texture *get_texture(RID p_rid) { return texture_owner.get_or_null(p_rid); }; struct TextureToRDFormat { RD::DataFormat format; @@ -303,13 +188,115 @@ private: /* DECAL API */ - DecalAtlas decal_atlas; + struct DecalAtlas { + struct Texture { + int panorama_to_dp_users; + int users; + Rect2 uv_rect; + }; + + struct SortItem { + RID texture; + Size2i pixel_size; + Size2i size; + Point2i pos; + + bool operator<(const SortItem &p_item) const { + //sort larger to smaller + if (size.height == p_item.size.height) { + return size.width > p_item.size.width; + } else { + return size.height > p_item.size.height; + } + } + }; + + HashMap<RID, Texture> textures; + bool dirty = true; + int mipmaps = 5; + + RID texture; + RID texture_srgb; + struct MipMap { + RID fb; + RID texture; + Size2i size; + }; + Vector<MipMap> texture_mipmaps; + + Size2i size; + } decal_atlas; + + struct Decal { + Vector3 extents = Vector3(1, 1, 1); + RID textures[RS::DECAL_TEXTURE_MAX]; + float emission_energy = 1.0; + float albedo_mix = 1.0; + Color modulate = Color(1, 1, 1, 1); + uint32_t cull_mask = (1 << 20) - 1; + float upper_fade = 0.3; + float lower_fade = 0.3; + bool distance_fade = false; + float distance_fade_begin = 40.0; + float distance_fade_length = 10.0; + float normal_fade = 0.0; + + Dependency dependency; + }; mutable RID_Owner<Decal, true> decal_owner; + Decal *get_decal(RID p_rid) const { return decal_owner.get_or_null(p_rid); }; /* RENDER TARGET API */ + struct RenderTarget { + Size2i size; + uint32_t view_count; + RID framebuffer; + RID color; + + //used for retrieving from CPU + RD::DataFormat color_format = RD::DATA_FORMAT_R4G4_UNORM_PACK8; + RD::DataFormat color_format_srgb = RD::DATA_FORMAT_R4G4_UNORM_PACK8; + Image::Format image_format = Image::FORMAT_L8; + + bool is_transparent = false; + + bool sdf_enabled = false; + + RID backbuffer; //used for effects + RID backbuffer_fb; + RID backbuffer_mipmap0; + + Vector<RID> backbuffer_mipmaps; + + RID framebuffer_uniform_set; + RID backbuffer_uniform_set; + + RID sdf_buffer_write; + RID sdf_buffer_write_fb; + RID sdf_buffer_process[2]; + RID sdf_buffer_read; + RID sdf_buffer_process_uniform_sets[2]; + RS::ViewportSDFOversize sdf_oversize = RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT; + RS::ViewportSDFScale sdf_scale = RS::VIEWPORT_SDF_SCALE_50_PERCENT; + Size2i process_size; + + // VRS + RS::ViewportVRSMode vrs_mode = RS::VIEWPORT_VRS_DISABLED; + RID vrs_texture; + + //texture generated for this owner (nor RD). + RID texture; + bool was_used; + + //clear request + bool clear_requested; + Color clear_color; + }; + mutable RID_Owner<RenderTarget> render_target_owner; + RenderTarget *get_render_target(RID p_rid) const { return render_target_owner.get_or_null(p_rid); }; void _clear_render_target(RenderTarget *rt); void _update_render_target(RenderTarget *rt); @@ -318,13 +305,33 @@ private: void _render_target_clear_sdf(RenderTarget *rt); Rect2i _render_target_get_sdf_rect(const RenderTarget *rt) const; - RenderTargetSDF rt_sdf; + struct RenderTargetSDF { + enum { + SHADER_LOAD, + SHADER_LOAD_SHRINK, + SHADER_PROCESS, + SHADER_PROCESS_OPTIMIZED, + SHADER_STORE, + SHADER_STORE_SHRINK, + SHADER_MAX + }; + + struct PushConstant { + int32_t size[2]; + int32_t stride; + int32_t shift; + int32_t base_size[2]; + int32_t pad[2]; + }; + + CanvasSdfShaderRD shader; + RID shader_version; + RID pipelines[SHADER_MAX]; + } rt_sdf; public: static TextureStorage *get_singleton(); - RID default_rd_textures[DEFAULT_RD_TEXTURE_MAX]; - _FORCE_INLINE_ RID texture_rd_get_default(DefaultRDTexture p_texture) { return default_rd_textures[p_texture]; } @@ -334,7 +341,6 @@ public: /* Canvas Texture API */ - CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); }; bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); }; virtual RID canvas_texture_allocate() override; @@ -351,8 +357,7 @@ public: /* Texture API */ - Texture *get_texture(RID p_rid) { return texture_owner.get_or_null(p_rid); }; - bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); }; + bool owns_texture(RID p_rid) const { return texture_owner.owns(p_rid); }; virtual bool can_create_resources_async() const override; @@ -394,12 +399,29 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) override; //internal usage + _FORCE_INLINE_ TextureType texture_get_type(RID p_texture) { + RendererRD::TextureStorage::Texture *tex = texture_owner.get_or_null(p_texture); + if (tex == nullptr) { + return TYPE_2D; + } + + return tex->type; + } + + _FORCE_INLINE_ int texture_get_layers(RID p_texture) { + RendererRD::TextureStorage::Texture *tex = texture_owner.get_or_null(p_texture); + if (tex == nullptr) { + return 1; + } + + return tex->layers; + } _FORCE_INLINE_ RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) { if (p_texture.is_null()) { return RID(); } - RendererRD::Texture *tex = texture_owner.get_or_null(p_texture); + RendererRD::TextureStorage::Texture *tex = texture_owner.get_or_null(p_texture); if (!tex) { return RID(); @@ -411,7 +433,7 @@ public: if (p_texture.is_null()) { return Size2i(); } - RendererRD::Texture *tex = texture_owner.get_or_null(p_texture); + RendererRD::TextureStorage::Texture *tex = texture_owner.get_or_null(p_texture); if (!tex) { return Size2i(); @@ -423,8 +445,7 @@ public: void update_decal_atlas(); - Decal *get_decal(RID p_rid) { return decal_owner.get_or_null(p_rid); }; - bool owns_decal(RID p_rid) { return decal_owner.owns(p_rid); }; + bool owns_decal(RID p_rid) const { return decal_owner.owns(p_rid); }; RID decal_atlas_get_texture() const; RID decal_atlas_get_texture_srgb() const; @@ -518,11 +539,11 @@ public: } virtual AABB decal_get_aabb(RID p_decal) const override; + Dependency *decal_get_dependency(RID p_decal); /* RENDER TARGET API */ - RenderTarget *get_render_target(RID p_rid) { return render_target_owner.get_or_null(p_rid); }; - bool owns_render_target(RID p_rid) { return render_target_owner.owns(p_rid); }; + bool owns_render_target(RID p_rid) const { return render_target_owner.owns(p_rid); }; virtual RID render_target_create() override; virtual void render_target_free(RID p_rid) override; diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.cpp b/servers/rendering/renderer_rd/storage_rd/utilities.cpp index a1f62c16c7..ae1f22be3b 100644 --- a/servers/rendering/renderer_rd/storage_rd/utilities.cpp +++ b/servers/rendering/renderer_rd/storage_rd/utilities.cpp @@ -138,35 +138,37 @@ bool Utilities::free(RID p_rid) { void Utilities::base_update_dependency(RID p_base, DependencyTracker *p_instance) { if (MeshStorage::get_singleton()->owns_mesh(p_base)) { - Mesh *mesh = MeshStorage::get_singleton()->get_mesh(p_base); - p_instance->update_dependency(&mesh->dependency); + Dependency *dependency = MeshStorage::get_singleton()->mesh_get_dependency(p_base); + p_instance->update_dependency(dependency); } else if (MeshStorage::get_singleton()->owns_multimesh(p_base)) { - MultiMesh *multimesh = MeshStorage::get_singleton()->get_multimesh(p_base); - p_instance->update_dependency(&multimesh->dependency); - if (multimesh->mesh.is_valid()) { - base_update_dependency(multimesh->mesh, p_instance); + Dependency *dependency = MeshStorage::get_singleton()->multimesh_get_dependency(p_base); + p_instance->update_dependency(dependency); + + RID mesh = MeshStorage::get_singleton()->multimesh_get_mesh(p_base); + if (mesh.is_valid()) { + base_update_dependency(mesh, p_instance); } } else if (LightStorage::get_singleton()->owns_reflection_probe(p_base)) { - ReflectionProbe *rp = LightStorage::get_singleton()->get_reflection_probe(p_base); - p_instance->update_dependency(&rp->dependency); + Dependency *dependency = LightStorage::get_singleton()->reflection_probe_get_dependency(p_base); + p_instance->update_dependency(dependency); } else if (TextureStorage::get_singleton()->owns_decal(p_base)) { - Decal *decal = TextureStorage::get_singleton()->get_decal(p_base); - p_instance->update_dependency(&decal->dependency); + Dependency *dependency = TextureStorage::get_singleton()->decal_get_dependency(p_base); + p_instance->update_dependency(dependency); } else if (GI::get_singleton()->owns_voxel_gi(p_base)) { GI::VoxelGI *gip = GI::get_singleton()->get_voxel_gi(p_base); p_instance->update_dependency(&gip->dependency); } else if (LightStorage::get_singleton()->owns_lightmap(p_base)) { - Lightmap *lm = LightStorage::get_singleton()->get_lightmap(p_base); - p_instance->update_dependency(&lm->dependency); + Dependency *dependency = LightStorage::get_singleton()->lightmap_get_dependency(p_base); + p_instance->update_dependency(dependency); } else if (LightStorage::get_singleton()->owns_light(p_base)) { - Light *l = LightStorage::get_singleton()->get_light(p_base); - p_instance->update_dependency(&l->dependency); + Dependency *dependency = LightStorage::get_singleton()->light_get_dependency(p_base); + p_instance->update_dependency(dependency); } else if (ParticlesStorage::get_singleton()->owns_particles(p_base)) { - Particles *p = ParticlesStorage::get_singleton()->get_particles(p_base); - p_instance->update_dependency(&p->dependency); + Dependency *dependency = ParticlesStorage::get_singleton()->particles_get_dependency(p_base); + p_instance->update_dependency(dependency); } else if (ParticlesStorage::get_singleton()->owns_particles_collision(p_base)) { - ParticlesCollision *pc = ParticlesStorage::get_singleton()->get_particles_collision(p_base); - p_instance->update_dependency(&pc->dependency); + Dependency *dependency = ParticlesStorage::get_singleton()->particles_collision_get_dependency(p_base); + p_instance->update_dependency(dependency); } else if (Fog::get_singleton()->owns_fog_volume(p_base)) { Fog::FogVolume *fv = Fog::get_singleton()->get_fog_volume(p_base); p_instance->update_dependency(&fv->dependency); @@ -219,21 +221,21 @@ void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_de if (p_enter) { if (!vn->enter_callback.is_null()) { if (p_deferred) { - vn->enter_callback.call_deferred(nullptr, 0); + vn->enter_callback.call_deferredp(nullptr, 0); } else { Variant r; Callable::CallError ce; - vn->enter_callback.call(nullptr, 0, r, ce); + vn->enter_callback.callp(nullptr, 0, r, ce); } } } else { if (!vn->exit_callback.is_null()) { if (p_deferred) { - vn->exit_callback.call_deferred(nullptr, 0); + vn->exit_callback.call_deferredp(nullptr, 0); } else { Variant r; Callable::CallError ce; - vn->exit_callback.call(nullptr, 0, r, ce); + vn->exit_callback.callp(nullptr, 0, r, ce); } } } @@ -272,7 +274,7 @@ String Utilities::get_captured_timestamp_name(uint32_t p_index) const { /* MISC */ void Utilities::update_dirty_resources() { - MaterialStorage::get_singleton()->_update_global_variables(); //must do before materials, so it can queue them for update + MaterialStorage::get_singleton()->_update_global_shader_uniforms(); //must do before materials, so it can queue them for update MaterialStorage::get_singleton()->_update_queued_materials(); MeshStorage::get_singleton()->_update_dirty_multimeshes(); MeshStorage::get_singleton()->_update_dirty_skeletons(); @@ -288,9 +290,14 @@ bool Utilities::has_os_feature(const String &p_feature) const { return true; } +#if !defined(ANDROID_ENABLED) && !defined(IPHONE_ENABLED) + // Some Android devices report support for S3TC but we don't expect that and don't export the textures. + // This could be fixed but so few devices support it that it doesn't seem useful (and makes bigger APKs). + // For good measure we do the same hack for iOS, just in case. if (p_feature == "s3tc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { return true; } +#endif if (p_feature == "bptc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { return true; diff --git a/servers/rendering/renderer_rd/uniform_set_cache_rd.h b/servers/rendering/renderer_rd/uniform_set_cache_rd.h index abf110730b..bca8b02178 100644 --- a/servers/rendering/renderer_rd/uniform_set_cache_rd.h +++ b/servers/rendering/renderer_rd/uniform_set_cache_rd.h @@ -163,7 +163,7 @@ public: const Cache *c = hash_table[table_idx]; while (c) { - if (c->hash == h && c->set == p_set && c->shader == p_shader && _compare_args(0, c->uniforms, args...)) { + if (c->hash == h && c->set == p_set && c->shader == p_shader && sizeof...(Args) == c->uniforms.size() && _compare_args(0, c->uniforms, args...)) { return c->cache; } c = c->next; @@ -193,7 +193,7 @@ public: const Cache *c = hash_table[table_idx]; while (c) { - if (c->hash == h && c->set == p_set && c->shader == p_shader) { + if (c->hash == h && c->set == p_set && c->shader == p_shader && (uint32_t)p_uniforms.size() == c->uniforms.size()) { bool all_ok = true; for (int i = 0; i < p_uniforms.size(); i++) { if (!_compare_uniform(p_uniforms[i], c->uniforms[i])) { diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index be57701017..ba6fb71e67 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -100,10 +100,10 @@ public: virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin, RS::VisibilityRangeFadeMode p_fade_mode) = 0; virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) = 0; virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0; - virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) = 0; - virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; - virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0; - virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0; + virtual void instance_geometry_set_shader_uniform(RID p_instance, const StringName &p_parameter, const Variant &p_value) = 0; + virtual void instance_geometry_get_shader_uniform_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; + virtual Variant instance_geometry_get_shader_uniform(RID p_instance, const StringName &p_parameter) const = 0; + virtual Variant instance_geometry_get_shader_uniform_default_value(RID p_instance, const StringName &p_parameter) const = 0; virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) = 0; @@ -122,6 +122,7 @@ public: virtual RID environment_allocate() = 0; virtual void environment_initialize(RID p_rid) = 0; + // Background virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0; virtual void environment_set_sky(RID p_env, RID p_sky) = 0; virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0; @@ -131,41 +132,152 @@ public: virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0; virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) = 0; - virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) = 0; - virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; - virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; + virtual RS::EnvironmentBG environment_get_background(RID p_Env) const = 0; + virtual RID environment_get_sky(RID p_env) const = 0; + virtual float environment_get_sky_custom_fov(RID p_env) const = 0; + virtual Basis environment_get_sky_orientation(RID p_env) const = 0; + virtual Color environment_get_bg_color(RID p_env) const = 0; + virtual float environment_get_bg_energy(RID p_env) const = 0; + virtual int environment_get_canvas_max_layer(RID p_env) const = 0; + virtual RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const = 0; + virtual Color environment_get_ambient_light(RID p_env) const = 0; + virtual float environment_get_ambient_light_energy(RID p_env) const = 0; + virtual float environment_get_ambient_sky_contribution(RID p_env) const = 0; + virtual RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const = 0; + + // Tonemap + virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; + + virtual RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const = 0; + virtual float environment_get_exposure(RID p_env) const = 0; + virtual float environment_get_white(RID p_env) const = 0; + virtual bool environment_get_auto_exposure(RID p_env) const = 0; + virtual float environment_get_min_luminance(RID p_env) const = 0; + virtual float environment_get_max_luminance(RID p_env) const = 0; + virtual float environment_get_auto_exp_speed(RID p_env) const = 0; + virtual float environment_get_auto_exp_scale(RID p_env) const = 0; + virtual uint64_t environment_get_auto_exposure_version(RID p_env) const = 0; + + // Fog + virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; + virtual bool environment_get_fog_enabled(RID p_env) const = 0; + virtual Color environment_get_fog_light_color(RID p_env) const = 0; + virtual float environment_get_fog_light_energy(RID p_env) const = 0; + virtual float environment_get_fog_sun_scatter(RID p_env) const = 0; + virtual float environment_get_fog_density(RID p_env) const = 0; + virtual float environment_get_fog_height(RID p_env) const = 0; + virtual float environment_get_fog_height_density(RID p_env) const = 0; + virtual float environment_get_fog_aerial_perspective(RID p_env) const = 0; + + // Volumetric Fog virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) = 0; + virtual bool environment_get_volumetric_fog_enabled(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_density(RID p_env) const = 0; + virtual Color environment_get_volumetric_fog_scattering(RID p_env) const = 0; + virtual Color environment_get_volumetric_fog_emission(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_emission_energy(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_anisotropy(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_length(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_detail_spread(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_gi_inject(RID p_env) const = 0; + virtual bool environment_get_volumetric_fog_temporal_reprojection(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_ambient_inject(RID p_env) const = 0; + virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; + // Glow + + virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) = 0; + + virtual bool environment_get_glow_enabled(RID p_env) const = 0; + virtual Vector<float> environment_get_glow_levels(RID p_env) const = 0; + virtual float environment_get_glow_intensity(RID p_env) const = 0; + virtual float environment_get_glow_strength(RID p_env) const = 0; + virtual float environment_get_glow_bloom(RID p_env) const = 0; + virtual float environment_get_glow_mix(RID p_env) const = 0; + virtual RS::EnvironmentGlowBlendMode environment_get_glow_blend_mode(RID p_env) const = 0; + virtual float environment_get_glow_hdr_bleed_threshold(RID p_env) const = 0; + virtual float environment_get_glow_hdr_luminance_cap(RID p_env) const = 0; + virtual float environment_get_glow_hdr_bleed_scale(RID p_env) const = 0; + virtual float environment_get_glow_map_strength(RID p_env) const = 0; + virtual RID environment_get_glow_map(RID p_env) const = 0; + + virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; + virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; + + // SSR + virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; + + virtual bool environment_get_ssr_enabled(RID p_env) const = 0; + virtual int environment_get_ssr_max_steps(RID p_env) const = 0; + virtual float environment_get_ssr_fade_in(RID p_env) const = 0; + virtual float environment_get_ssr_fade_out(RID p_env) const = 0; + virtual float environment_get_ssr_depth_tolerance(RID p_env) const = 0; + virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; + // SSAO virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) = 0; + + virtual bool environment_get_ssao_enabled(RID p_env) const = 0; + virtual float environment_get_ssao_radius(RID p_env) const = 0; + virtual float environment_get_ssao_intensity(RID p_env) const = 0; + virtual float environment_get_ssao_power(RID p_env) const = 0; + virtual float environment_get_ssao_detail(RID p_env) const = 0; + virtual float environment_get_ssao_horizon(RID p_env) const = 0; + virtual float environment_get_ssao_sharpness(RID p_env) const = 0; + virtual float environment_get_ssao_direct_light_affect(RID p_env) const = 0; + virtual float environment_get_ssao_ao_channel_affect(RID p_env) const = 0; + virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0; + // SSIL + virtual void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) = 0; + + virtual bool environment_get_ssil_enabled(RID p_env) const = 0; + virtual float environment_get_ssil_radius(RID p_env) const = 0; + virtual float environment_get_ssil_intensity(RID p_env) const = 0; + virtual float environment_get_ssil_sharpness(RID p_env) const = 0; + virtual float environment_get_ssil_normal_rejection(RID p_env) const = 0; + virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0; + // SDFGI virtual void environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + virtual bool environment_get_sdfgi_enabled(RID p_env) const = 0; + virtual int environment_get_sdfgi_cascades(RID p_env) const = 0; + virtual float environment_get_sdfgi_min_cell_size(RID p_env) const = 0; + virtual bool environment_get_sdfgi_use_occlusion(RID p_env) const = 0; + virtual float environment_get_sdfgi_bounce_feedback(RID p_env) const = 0; + virtual bool environment_get_sdfgi_read_sky_light(RID p_env) const = 0; + virtual float environment_get_sdfgi_energy(RID p_env) const = 0; + virtual float environment_get_sdfgi_normal_bias(RID p_env) const = 0; + virtual float environment_get_sdfgi_probe_bias(RID p_env) const = 0; + virtual RS::EnvironmentSDFGIYScale environment_get_sdfgi_y_scale(RID p_env) const = 0; + virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0; virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0; virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) = 0; - virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; - + // Adjustment virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) = 0; - virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; + virtual bool environment_get_adjustments_enabled(RID p_env) const = 0; + virtual float environment_get_adjustments_brightness(RID p_env) const = 0; + virtual float environment_get_adjustments_contrast(RID p_env) const = 0; + virtual float environment_get_adjustments_saturation(RID p_env) const = 0; + virtual bool environment_get_use_1d_color_correction(RID p_env) const = 0; + virtual RID environment_get_color_correction(RID p_env) const = 0; virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; - virtual RS::EnvironmentBG environment_get_background(RID p_Env) const = 0; - virtual int environment_get_canvas_max_layer(RID p_env) const = 0; - virtual bool is_environment(RID p_environment) const = 0; virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0; @@ -194,7 +306,7 @@ public: virtual RID render_buffers_create() = 0; - virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) = 0; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) = 0; virtual void gi_set_use_half_resolution(bool p_enable) = 0; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 7631be3669..0b20bb372a 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -475,7 +475,7 @@ void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) { } InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); - scene_render->geometry_instance_set_mesh_instance(geom->geometry_instance, p_instance->mesh_instance); + geom->geometry_instance->set_mesh_instance(p_instance->mesh_instance); if (p_instance->scenario && p_instance->array_index >= 0) { InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index]; @@ -637,20 +637,20 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { instance->base_data = geom; geom->geometry_instance = scene_render->geometry_instance_create(p_base); - scene_render->geometry_instance_set_skeleton(geom->geometry_instance, instance->skeleton); - scene_render->geometry_instance_set_material_override(geom->geometry_instance, instance->material_override); - scene_render->geometry_instance_set_material_overlay(geom->geometry_instance, instance->material_overlay); - scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, instance->materials); - scene_render->geometry_instance_set_transform(geom->geometry_instance, instance->transform, instance->aabb, instance->transformed_aabb); - scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, instance->layer_mask); - scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, instance->lod_bias); - scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, instance->baked_light); - scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, instance->dynamic_gi); - scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); - scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index); - scene_render->geometry_instance_set_transparency(geom->geometry_instance, instance->transparency); + geom->geometry_instance->set_skeleton(instance->skeleton); + geom->geometry_instance->set_material_override(instance->material_override); + geom->geometry_instance->set_material_overlay(instance->material_overlay); + geom->geometry_instance->set_surface_materials(instance->materials); + geom->geometry_instance->set_transform(instance->transform, instance->aabb, instance->transformed_aabb); + geom->geometry_instance->set_layer_mask(instance->layer_mask); + geom->geometry_instance->set_lod_bias(instance->lod_bias); + geom->geometry_instance->set_transparency(instance->transparency); + geom->geometry_instance->set_use_baked_light(instance->baked_light); + geom->geometry_instance->set_use_dynamic_gi(instance->dynamic_gi); + geom->geometry_instance->set_use_lightmap(RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index); + geom->geometry_instance->set_cast_double_sided_shadows(instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); if (instance->lightmap_sh.size() == 9) { - scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, instance->lightmap_sh.ptr()); + geom->geometry_instance->set_lightmap_capture(instance->lightmap_sh.ptr()); } for (Instance *E : instance->visibility_dependencies) { @@ -836,7 +836,7 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask) if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, p_mask); + geom->geometry_instance->set_layer_mask(p_mask); } } @@ -848,7 +848,7 @@ void RendererSceneCull::instance_geometry_set_transparency(RID p_instance, float if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_transparency(geom->geometry_instance, p_transparency); + geom->geometry_instance->set_transparency(p_transparency); } } @@ -1009,7 +1009,7 @@ void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton) _instance_update_mesh_instance(instance); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_skeleton(geom->geometry_instance, p_skeleton); + geom->geometry_instance->set_skeleton(p_skeleton); } } @@ -1129,7 +1129,7 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, p_enabled); + geom->geometry_instance->set_use_baked_light(p_enabled); } } break; @@ -1149,7 +1149,7 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, p_enabled); + geom->geometry_instance->set_use_dynamic_gi(p_enabled); } } break; @@ -1207,7 +1207,7 @@ void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instanc if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); + geom->geometry_instance->set_cast_double_sided_shadows(instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); } _instance_queue_update(instance, false, true); @@ -1222,7 +1222,7 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance, if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_material_override(geom->geometry_instance, p_material); + geom->geometry_instance->set_material_override(p_material); } } @@ -1235,7 +1235,7 @@ void RendererSceneCull::instance_geometry_set_material_overlay(RID p_instance, R if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_material_overlay(geom->geometry_instance, p_material); + geom->geometry_instance->set_material_overlay(p_material); } } @@ -1358,9 +1358,9 @@ void RendererSceneCull::_update_instance_visibility_dependencies(Instance *p_ins bool end_enabled = p_instance->visibility_range_end > 0.0f; float end_min = p_instance->visibility_range_end - p_instance->visibility_range_end_margin; float end_max = p_instance->visibility_range_end + p_instance->visibility_range_end_margin; - scene_render->geometry_instance_set_fade_range(idata.instance_geometry, begin_enabled, begin_min, begin_max, end_enabled, end_min, end_max); + idata.instance_geometry->set_fade_range(begin_enabled, begin_min, begin_max, end_enabled, end_min, end_max); } else { - scene_render->geometry_instance_set_fade_range(idata.instance_geometry, false, 0.0f, 0.0f, false, 0.0f, 0.0f); + idata.instance_geometry->set_fade_range(false, 0.0f, 0.0f, false, 0.0f, 0.0f); } } @@ -1375,7 +1375,7 @@ void RendererSceneCull::_update_instance_visibility_dependencies(Instance *p_ins } else { idata.parent_array_index = -1; if (is_geometry_instance) { - scene_render->geometry_instance_set_parent_fade_alpha(idata.instance_geometry, 1.0f); + idata.instance_geometry->set_parent_fade_alpha(1.0f); } } } @@ -1407,7 +1407,7 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index); + geom->geometry_instance->set_use_lightmap(lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index); } } @@ -1419,66 +1419,66 @@ void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_l if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, p_lod_bias); + geom->geometry_instance->set_lod_bias(p_lod_bias); } } -void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { +void RendererSceneCull::instance_geometry_set_shader_uniform(RID p_instance, const StringName &p_parameter, const Variant &p_value) { Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT); - HashMap<StringName, Instance::InstanceShaderParameter>::Iterator E = instance->instance_shader_parameters.find(p_parameter); + HashMap<StringName, Instance::InstanceShaderParameter>::Iterator E = instance->instance_shader_uniforms.find(p_parameter); if (!E) { Instance::InstanceShaderParameter isp; isp.index = -1; isp.info = PropertyInfo(); isp.value = p_value; - instance->instance_shader_parameters[p_parameter] = isp; + instance->instance_shader_uniforms[p_parameter] = isp; } else { E->value.value = p_value; - if (E->value.index >= 0 && instance->instance_allocated_shader_parameters) { + if (E->value.index >= 0 && instance->instance_allocated_shader_uniforms) { //update directly - RSG::material_storage->global_variables_instance_update(p_instance, E->value.index, p_value); + RSG::material_storage->global_shader_uniforms_instance_update(p_instance, E->value.index, p_value); } } } -Variant RendererSceneCull::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const { +Variant RendererSceneCull::instance_geometry_get_shader_uniform(RID p_instance, const StringName &p_parameter) const { const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!instance, Variant()); - if (instance->instance_shader_parameters.has(p_parameter)) { - return instance->instance_shader_parameters[p_parameter].value; + if (instance->instance_shader_uniforms.has(p_parameter)) { + return instance->instance_shader_uniforms[p_parameter].value; } return Variant(); } -Variant RendererSceneCull::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const { +Variant RendererSceneCull::instance_geometry_get_shader_uniform_default_value(RID p_instance, const StringName &p_parameter) const { const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!instance, Variant()); - if (instance->instance_shader_parameters.has(p_parameter)) { - return instance->instance_shader_parameters[p_parameter].default_value; + if (instance->instance_shader_uniforms.has(p_parameter)) { + return instance->instance_shader_uniforms[p_parameter].default_value; } return Variant(); } -void RendererSceneCull::instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const { +void RendererSceneCull::instance_geometry_get_shader_uniform_list(RID p_instance, List<PropertyInfo> *p_parameters) const { const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); const_cast<RendererSceneCull *>(this)->update_dirty_instances(); Vector<StringName> names; - for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : instance->instance_shader_parameters) { + for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : instance->instance_shader_uniforms) { names.push_back(E.key); } names.sort_custom<StringName::AlphCompare>(); for (int i = 0; i < names.size(); i++) { - PropertyInfo pinfo = instance->instance_shader_parameters[names[i]].info; + PropertyInfo pinfo = instance->instance_shader_uniforms[names[i]].info; p_parameters->push_back(pinfo); } } @@ -1587,11 +1587,11 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { if (!p_instance->lightmap_sh.is_empty()) { p_instance->lightmap_sh.clear(); //don't need SH p_instance->lightmap_target_sh.clear(); //don't need SH - scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, nullptr); + geom->geometry_instance->set_lightmap_capture(nullptr); } } - scene_render->geometry_instance_set_transform(geom->geometry_instance, p_instance->transform, p_instance->aabb, p_instance->transformed_aabb); + geom->geometry_instance->set_transform(p_instance->transform, p_instance->aabb, p_instance->transformed_aabb); } // note: we had to remove is equal approx check here, it meant that det == 0.000004 won't work, which is the case for some of our scenes. @@ -1818,10 +1818,10 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) { // Clear these now because the InstanceData containing the dirty flags is gone InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); - scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, nullptr, 0); - scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, nullptr, 0); - scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, nullptr, 0); - scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, nullptr, 0); + geom->geometry_instance->pair_light_instances(nullptr, 0); + geom->geometry_instance->pair_reflection_probe_instances(nullptr, 0); + geom->geometry_instance->pair_decal_instances(nullptr, 0); + geom->geometry_instance->pair_voxel_gi_instances(nullptr, 0); } for (Instance *E : p_instance->visibility_dependencies) { @@ -1829,7 +1829,7 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) { if (dep_instance->array_index != -1) { dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = -1; if ((1 << dep_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { - scene_render->geometry_instance_set_parent_fade_alpha(dep_instance->scenario->instance_data[dep_instance->array_index].instance_geometry, 1.0f); + dep_instance->scenario->instance_data[dep_instance->array_index].instance_geometry->set_parent_fade_alpha(1.0f); } } } @@ -1990,7 +1990,7 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) } } - scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, p_instance->lightmap_sh.ptr()); + geom->geometry_instance->set_lightmap_capture(p_instance->lightmap_sh.ptr()); } void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) { @@ -2742,7 +2742,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul const int32_t &parent_idx = cull_data.scenario->instance_data[idata.parent_array_index].visibility_index; fade = cull_data.scenario->instance_visibility[parent_idx].children_fade_alpha; } - scene_render->geometry_instance_set_parent_fade_alpha(idata.instance_geometry, fade); + idata.instance_geometry->set_parent_fade_alpha(fade); } if (geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT) && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) { @@ -2757,14 +2757,14 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } - scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, instance_pair_buffer, idx); + geom->geometry_instance->pair_light_instances(instance_pair_buffer, idx); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY); } if (idata.flags & InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); - scene_render->geometry_instance_set_softshadow_projector_pairing(geom->geometry_instance, geom->softshadow_count > 0, geom->projector_count > 0); + geom->geometry_instance->set_softshadow_projector_pairing(geom->softshadow_count > 0, geom->projector_count > 0); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY); } @@ -2781,7 +2781,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } - scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, instance_pair_buffer, idx); + geom->geometry_instance->pair_reflection_probe_instances(instance_pair_buffer, idx); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY); } @@ -2797,7 +2797,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul break; } } - scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, instance_pair_buffer, idx); + geom->geometry_instance->pair_decal_instances(instance_pair_buffer, idx); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY); } @@ -2813,7 +2813,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } - scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, instance_pair_buffer, idx); + geom->geometry_instance->pair_voxel_gi_instances(instance_pair_buffer, idx); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY); } @@ -2824,7 +2824,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul for (uint32_t j = 0; j < 9; j++) { sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed)); } - scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, sh); + geom->geometry_instance->set_lightmap_capture(sh); idata.instance->last_frame_pass = frame_number; } @@ -3245,7 +3245,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c render_sdfgi_data[i].instances.clear(); } - // virtual void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0; + // virtual void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0; } RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { @@ -3284,7 +3284,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, RendererSceneRender::CameraData camera_data; camera_data.set_camera(Transform3D(), Projection(), true, false); - scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); + scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); #endif } @@ -3588,7 +3588,7 @@ void RendererSceneCull::render_probes() { } } - scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, instance_pair_buffer, idx); + geom->geometry_instance->pair_voxel_gi_instances(instance_pair_buffer, idx); ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY); } @@ -3642,9 +3642,9 @@ void RendererSceneCull::render_particle_colliders() { } } -void RendererSceneCull::_update_instance_shader_parameters_from_material(HashMap<StringName, Instance::InstanceShaderParameter> &isparams, const HashMap<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) { +void RendererSceneCull::_update_instance_shader_uniforms_from_material(HashMap<StringName, Instance::InstanceShaderParameter> &isparams, const HashMap<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) { List<RendererMaterialStorage::InstanceShaderParam> plist; - RSG::material_storage->material_get_instance_shader_parameters(p_material, &plist); + RSG::material_storage->material_get_instance_shader_uniforms(p_material, &plist); for (const RendererMaterialStorage::InstanceShaderParam &E : plist) { StringName name = E.info.name; if (isparams.has(name)) { @@ -3724,7 +3724,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { can_cast_shadows = false; } is_animated = RSG::material_storage->material_is_animated(p_instance->material_override); - _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_override); + _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, p_instance->material_override); } else { if (p_instance->base_type == RS::INSTANCE_MESH) { RID mesh = p_instance->base; @@ -3746,7 +3746,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { is_animated = true; } - _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat); + _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, mat); RSG::material_storage->material_update_dependency(mat, &p_instance->dependency_tracker); } @@ -3777,7 +3777,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { is_animated = true; } - _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat); + _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, mat); RSG::material_storage->material_update_dependency(mat, &p_instance->dependency_tracker); } @@ -3815,7 +3815,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { is_animated = true; } - _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat); + _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, mat); RSG::material_storage->material_update_dependency(mat, &p_instance->dependency_tracker); } @@ -3831,7 +3831,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { if (p_instance->material_overlay.is_valid()) { can_cast_shadows = can_cast_shadows || RSG::material_storage->material_casts_shadows(p_instance->material_overlay); is_animated = is_animated || RSG::material_storage->material_is_animated(p_instance->material_overlay); - _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_overlay); + _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, p_instance->material_overlay); } if (can_cast_shadows != geom->can_cast_shadows) { @@ -3845,23 +3845,23 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { } geom->material_is_animated = is_animated; - p_instance->instance_shader_parameters = isparams; + p_instance->instance_shader_uniforms = isparams; - if (p_instance->instance_allocated_shader_parameters != (p_instance->instance_shader_parameters.size() > 0)) { - p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0); - if (p_instance->instance_allocated_shader_parameters) { - p_instance->instance_allocated_shader_parameters_offset = RSG::material_storage->global_variables_instance_allocate(p_instance->self); - scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, p_instance->instance_allocated_shader_parameters_offset); + if (p_instance->instance_allocated_shader_uniforms != (p_instance->instance_shader_uniforms.size() > 0)) { + p_instance->instance_allocated_shader_uniforms = (p_instance->instance_shader_uniforms.size() > 0); + if (p_instance->instance_allocated_shader_uniforms) { + p_instance->instance_allocated_shader_uniforms_offset = RSG::material_storage->global_shader_uniforms_instance_allocate(p_instance->self); + geom->geometry_instance->set_instance_shader_uniforms_offset(p_instance->instance_allocated_shader_uniforms_offset); - for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_parameters) { + for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_uniforms) { if (E.value.value.get_type() != Variant::NIL) { - RSG::material_storage->global_variables_instance_update(p_instance->self, E.value.index, E.value.value); + RSG::material_storage->global_shader_uniforms_instance_update(p_instance->self, E.value.index, E.value.value); } } } else { - RSG::material_storage->global_variables_instance_free(p_instance->self); - p_instance->instance_allocated_shader_parameters_offset = -1; - scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, -1); + RSG::material_storage->global_shader_uniforms_instance_free(p_instance->self); + p_instance->instance_allocated_shader_uniforms_offset = -1; + geom->geometry_instance->set_instance_shader_uniforms_offset(-1); } } } @@ -3874,7 +3874,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); - scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, p_instance->materials); + geom->geometry_instance->set_surface_materials(p_instance->materials); } } @@ -3953,9 +3953,9 @@ bool RendererSceneCull::free(RID p_rid) { instance_geometry_set_material_overlay(p_rid, RID()); instance_attach_skeleton(p_rid, RID()); - if (instance->instance_allocated_shader_parameters) { + if (instance->instance_allocated_shader_uniforms) { //free the used shader parameters - RSG::material_storage->global_variables_instance_free(instance->self); + RSG::material_storage->global_shader_uniforms_instance_free(instance->self); } update_dirty_instances(); //in case something changed this diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 9a46f6b873..540fb0e27a 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -272,7 +272,7 @@ public: RID base_rid; union { uint64_t instance_data_rid; - RendererSceneRender::GeometryInstance *instance_geometry; + RenderGeometryInstance *instance_geometry; InstanceVisibilityNotifierData *visibility_notifier = nullptr; }; Instance *instance = nullptr; @@ -426,9 +426,9 @@ public: PropertyInfo info; }; - HashMap<StringName, InstanceShaderParameter> instance_shader_parameters; - bool instance_allocated_shader_parameters = false; - int32_t instance_allocated_shader_parameters_offset = -1; + HashMap<StringName, InstanceShaderParameter> instance_shader_uniforms; + bool instance_allocated_shader_uniforms = false; + int32_t instance_allocated_shader_uniforms_offset = -1; // @@ -578,7 +578,7 @@ public: void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false); struct InstanceGeometryData : public InstanceBaseData { - RendererSceneRender::GeometryInstance *geometry_instance = nullptr; + RenderGeometryInstance *geometry_instance = nullptr; HashSet<Instance *> lights; bool can_cast_shadows; bool material_is_animated; @@ -782,14 +782,14 @@ public: HashSet<Instance *> heightfield_particle_colliders_update_list; PagedArrayPool<Instance *> instance_cull_page_pool; - PagedArrayPool<RendererSceneRender::GeometryInstance *> geometry_instance_cull_page_pool; + PagedArrayPool<RenderGeometryInstance *> geometry_instance_cull_page_pool; PagedArrayPool<RID> rid_cull_page_pool; PagedArray<Instance *> instance_cull_result; PagedArray<Instance *> instance_shadow_cull_result; struct InstanceCullResult { - PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances; + PagedArray<RenderGeometryInstance *> geometry_instances; PagedArray<Instance *> lights; PagedArray<RID> light_instances; PagedArray<RID> lightmaps; @@ -800,10 +800,10 @@ public: PagedArray<RID> fog_volumes; struct DirectionalShadow { - PagedArray<RendererSceneRender::GeometryInstance *> cascade_geometry_instances[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; + PagedArray<RenderGeometryInstance *> cascade_geometry_instances[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; } directional_shadows[RendererSceneRender::MAX_DIRECTIONAL_LIGHTS]; - PagedArray<RendererSceneRender::GeometryInstance *> sdfgi_region_geometry_instances[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; + PagedArray<RenderGeometryInstance *> sdfgi_region_geometry_instances[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; PagedArray<RID> sdfgi_cascade_lights[SDFGI_MAX_CASCADES]; void clear() { @@ -882,7 +882,7 @@ public: } } - void init(PagedArrayPool<RID> *p_rid_pool, PagedArrayPool<RendererSceneRender::GeometryInstance *> *p_geometry_instance_pool, PagedArrayPool<Instance *> *p_instance_pool) { + void init(PagedArrayPool<RID> *p_rid_pool, PagedArrayPool<RenderGeometryInstance *> *p_geometry_instance_pool, PagedArrayPool<Instance *> *p_instance_pool) { geometry_instances.set_page_pool(p_geometry_instance_pool); light_instances.set_page_pool(p_rid_pool); lights.set_page_pool(p_instance_pool); @@ -967,12 +967,12 @@ public: virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index); virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias); - void _update_instance_shader_parameters_from_material(HashMap<StringName, Instance::InstanceShaderParameter> &isparams, const HashMap<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material); + void _update_instance_shader_uniforms_from_material(HashMap<StringName, Instance::InstanceShaderParameter> &isparams, const HashMap<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material); - virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value); - virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const; - virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const; - virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const; + virtual void instance_geometry_set_shader_uniform(RID p_instance, const StringName &p_parameter, const Variant &p_value); + virtual void instance_geometry_get_shader_uniform_list(RID p_instance, List<PropertyInfo> *p_parameters) const; + virtual Variant instance_geometry_get_shader_uniform(RID p_instance, const StringName &p_parameter) const; + virtual Variant instance_geometry_get_shader_uniform_default_value(RID p_instance, const StringName &p_parameter) const; _FORCE_INLINE_ void _update_instance(Instance *p_instance); _FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance); @@ -1093,6 +1093,7 @@ public: PASS1RC(bool, is_environment, RID) + // Background PASS2(environment_set_background, RID, RS::EnvironmentBG) PASS2(environment_set_sky, RID, RID) PASS2(environment_set_sky_custom_fov, RID, float) @@ -1102,36 +1103,146 @@ public: PASS2(environment_set_canvas_max_layer, RID, int) PASS6(environment_set_ambient_light, RID, const Color &, RS::EnvironmentAmbientSource, float, float, RS::EnvironmentReflectionSource) + PASS1RC(RS::EnvironmentBG, environment_get_background, RID) + PASS1RC(RID, environment_get_sky, RID) + PASS1RC(float, environment_get_sky_custom_fov, RID) + PASS1RC(Basis, environment_get_sky_orientation, RID) + PASS1RC(Color, environment_get_bg_color, RID) + PASS1RC(float, environment_get_bg_energy, RID) + PASS1RC(int, environment_get_canvas_max_layer, RID) + PASS1RC(RS::EnvironmentAmbientSource, environment_get_ambient_source, RID) + PASS1RC(Color, environment_get_ambient_light, RID) + PASS1RC(float, environment_get_ambient_light_energy, RID) + PASS1RC(float, environment_get_ambient_sky_contribution, RID) + PASS1RC(RS::EnvironmentReflectionSource, environment_get_reflection_source, RID) + + // Tonemap + PASS9(environment_set_tonemap, RID, RS::EnvironmentToneMapper, float, float, bool, float, float, float, float) + PASS1RC(RS::EnvironmentToneMapper, environment_get_tone_mapper, RID) + PASS1RC(float, environment_get_exposure, RID) + PASS1RC(float, environment_get_white, RID) + PASS1RC(bool, environment_get_auto_exposure, RID) + PASS1RC(float, environment_get_min_luminance, RID) + PASS1RC(float, environment_get_max_luminance, RID) + PASS1RC(float, environment_get_auto_exp_speed, RID) + PASS1RC(float, environment_get_auto_exp_scale, RID) + PASS1RC(uint64_t, environment_get_auto_exposure_version, RID) + + // Fog + PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) + + PASS1RC(bool, environment_get_fog_enabled, RID) + PASS1RC(Color, environment_get_fog_light_color, RID) + PASS1RC(float, environment_get_fog_light_energy, RID) + PASS1RC(float, environment_get_fog_sun_scatter, RID) + PASS1RC(float, environment_get_fog_density, RID) + PASS1RC(float, environment_get_fog_height, RID) + PASS1RC(float, environment_get_fog_height_density, RID) + PASS1RC(float, environment_get_fog_aerial_perspective, RID) + + PASS2(environment_set_volumetric_fog_volume_size, int, int) + PASS1(environment_set_volumetric_fog_filter_active, bool) + + // Volumentric Fog + PASS13(environment_set_volumetric_fog, RID, bool, float, const Color &, const Color &, float, float, float, float, float, bool, float, float) + + PASS1RC(bool, environment_get_volumetric_fog_enabled, RID) + PASS1RC(float, environment_get_volumetric_fog_density, RID) + PASS1RC(Color, environment_get_volumetric_fog_scattering, RID) + PASS1RC(Color, environment_get_volumetric_fog_emission, RID) + PASS1RC(float, environment_get_volumetric_fog_emission_energy, RID) + PASS1RC(float, environment_get_volumetric_fog_anisotropy, RID) + PASS1RC(float, environment_get_volumetric_fog_length, RID) + PASS1RC(float, environment_get_volumetric_fog_detail_spread, RID) + PASS1RC(float, environment_get_volumetric_fog_gi_inject, RID) + PASS1RC(bool, environment_get_volumetric_fog_temporal_reprojection, RID) + PASS1RC(float, environment_get_volumetric_fog_temporal_reprojection_amount, RID) + PASS1RC(float, environment_get_volumetric_fog_ambient_inject, RID) + + // Glow + PASS13(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, RS::EnvironmentGlowBlendMode, float, float, float, float, RID) + + PASS1RC(bool, environment_get_glow_enabled, RID) + PASS1RC(Vector<float>, environment_get_glow_levels, RID) + PASS1RC(float, environment_get_glow_intensity, RID) + PASS1RC(float, environment_get_glow_strength, RID) + PASS1RC(float, environment_get_glow_bloom, RID) + PASS1RC(float, environment_get_glow_mix, RID) + PASS1RC(RS::EnvironmentGlowBlendMode, environment_get_glow_blend_mode, RID) + PASS1RC(float, environment_get_glow_hdr_bleed_threshold, RID) + PASS1RC(float, environment_get_glow_hdr_luminance_cap, RID) + PASS1RC(float, environment_get_glow_hdr_bleed_scale, RID) + PASS1RC(float, environment_get_glow_map_strength, RID) + PASS1RC(RID, environment_get_glow_map, RID) + + PASS1(environment_glow_set_use_bicubic_upscale, bool) + PASS1(environment_glow_set_use_high_quality, bool) + + // SSR PASS6(environment_set_ssr, RID, bool, int, float, float, float) + + PASS1RC(bool, environment_get_ssr_enabled, RID) + PASS1RC(int, environment_get_ssr_max_steps, RID) + PASS1RC(float, environment_get_ssr_fade_in, RID) + PASS1RC(float, environment_get_ssr_fade_out, RID) + PASS1RC(float, environment_get_ssr_depth_tolerance, RID) + PASS1(environment_set_ssr_roughness_quality, RS::EnvironmentSSRRoughnessQuality) + // SSAO PASS10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float) + + PASS1RC(bool, environment_get_ssao_enabled, RID) + PASS1RC(float, environment_get_ssao_radius, RID) + PASS1RC(float, environment_get_ssao_intensity, RID) + PASS1RC(float, environment_get_ssao_power, RID) + PASS1RC(float, environment_get_ssao_detail, RID) + PASS1RC(float, environment_get_ssao_horizon, RID) + PASS1RC(float, environment_get_ssao_sharpness, RID) + PASS1RC(float, environment_get_ssao_direct_light_affect, RID) + PASS1RC(float, environment_get_ssao_ao_channel_affect, RID) + PASS6(environment_set_ssao_quality, RS::EnvironmentSSAOQuality, bool, float, int, float, float) + // SSIL PASS6(environment_set_ssil, RID, bool, float, float, float, float) - PASS6(environment_set_ssil_quality, RS::EnvironmentSSILQuality, bool, float, int, float, float) - PASS13(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, RS::EnvironmentGlowBlendMode, float, float, float, float, RID) - PASS1(environment_glow_set_use_bicubic_upscale, bool) - PASS1(environment_glow_set_use_high_quality, bool) + PASS1RC(bool, environment_get_ssil_enabled, RID) + PASS1RC(float, environment_get_ssil_radius, RID) + PASS1RC(float, environment_get_ssil_intensity, RID) + PASS1RC(float, environment_get_ssil_sharpness, RID) + PASS1RC(float, environment_get_ssil_normal_rejection, RID) - PASS9(environment_set_tonemap, RID, RS::EnvironmentToneMapper, float, float, bool, float, float, float, float) + PASS6(environment_set_ssil_quality, RS::EnvironmentSSILQuality, bool, float, int, float, float) - PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) + // SDFGI - PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - PASS13(environment_set_volumetric_fog, RID, bool, float, const Color &, const Color &, float, float, float, float, float, bool, float, float) + PASS11(environment_set_sdfgi, RID, bool, int, float, RS::EnvironmentSDFGIYScale, bool, float, bool, float, float, float) - PASS2(environment_set_volumetric_fog_volume_size, int, int) - PASS1(environment_set_volumetric_fog_filter_active, bool) + PASS1RC(bool, environment_get_sdfgi_enabled, RID) + PASS1RC(int, environment_get_sdfgi_cascades, RID) + PASS1RC(float, environment_get_sdfgi_min_cell_size, RID) + PASS1RC(bool, environment_get_sdfgi_use_occlusion, RID) + PASS1RC(float, environment_get_sdfgi_bounce_feedback, RID) + PASS1RC(bool, environment_get_sdfgi_read_sky_light, RID) + PASS1RC(float, environment_get_sdfgi_energy, RID) + PASS1RC(float, environment_get_sdfgi_normal_bias, RID) + PASS1RC(float, environment_get_sdfgi_probe_bias, RID) + PASS1RC(RS::EnvironmentSDFGIYScale, environment_get_sdfgi_y_scale, RID) - PASS11(environment_set_sdfgi, RID, bool, int, float, RS::EnvironmentSDFGIYScale, bool, float, bool, float, float, float) PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount) PASS1(environment_set_sdfgi_frames_to_converge, RS::EnvironmentSDFGIFramesToConverge) PASS1(environment_set_sdfgi_frames_to_update_light, RS::EnvironmentSDFGIFramesToUpdateLight) - PASS1RC(RS::EnvironmentBG, environment_get_background, RID) - PASS1RC(int, environment_get_canvas_max_layer, RID) + // Adjustment + PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) + + PASS1RC(bool, environment_get_adjustments_enabled, RID) + PASS1RC(float, environment_get_adjustments_brightness, RID) + PASS1RC(float, environment_get_adjustments_contrast, RID) + PASS1RC(float, environment_get_adjustments_saturation, RID) + PASS1RC(bool, environment_get_use_1d_color_correction, RID) + PASS1RC(RID, environment_get_color_correction, RID) PASS3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp index c0ad0d1187..e024e59ec3 100644 --- a/servers/rendering/renderer_scene_render.cpp +++ b/servers/rendering/renderer_scene_render.cpp @@ -30,6 +30,9 @@ #include "renderer_scene_render.h" +///////////////////////////////////////////////////////////////////////////// +// CameraData + void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter) { view_count = 1; is_orthogonal = p_is_orthogonal; @@ -180,3 +183,461 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count view_projection[v] = p_projections[v] * Projection(view_offset[v].inverse()); } } + +/* Environment API */ + +RID RendererSceneRender::environment_allocate() { + return environment_storage.environment_allocate(); +} + +void RendererSceneRender::environment_initialize(RID p_rid) { + environment_storage.environment_initialize(p_rid); +} + +void RendererSceneRender::environment_free(RID p_rid) { + environment_storage.environment_free(p_rid); +} + +bool RendererSceneRender::is_environment(RID p_rid) const { + return environment_storage.is_environment(p_rid); +} + +// background + +void RendererSceneRender::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { + environment_storage.environment_set_background(p_env, p_bg); +} + +void RendererSceneRender::environment_set_sky(RID p_env, RID p_sky) { + environment_storage.environment_set_sky(p_env, p_sky); +} + +void RendererSceneRender::environment_set_sky_custom_fov(RID p_env, float p_scale) { + environment_storage.environment_set_sky_custom_fov(p_env, p_scale); +} + +void RendererSceneRender::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { + environment_storage.environment_set_sky_orientation(p_env, p_orientation); +} + +void RendererSceneRender::environment_set_bg_color(RID p_env, const Color &p_color) { + environment_storage.environment_set_bg_color(p_env, p_color); +} + +void RendererSceneRender::environment_set_bg_energy(RID p_env, float p_energy) { + environment_storage.environment_set_bg_energy(p_env, p_energy); +} + +void RendererSceneRender::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { + environment_storage.environment_set_canvas_max_layer(p_env, p_max_layer); +} + +void RendererSceneRender::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) { + environment_storage.environment_set_ambient_light(p_env, p_color, p_ambient, p_energy, p_sky_contribution, p_reflection_source); +} + +RS::EnvironmentBG RendererSceneRender::environment_get_background(RID p_env) const { + return environment_storage.environment_get_background(p_env); +} + +RID RendererSceneRender::environment_get_sky(RID p_env) const { + return environment_storage.environment_get_sky(p_env); +} + +float RendererSceneRender::environment_get_sky_custom_fov(RID p_env) const { + return environment_storage.environment_get_sky_custom_fov(p_env); +} + +Basis RendererSceneRender::environment_get_sky_orientation(RID p_env) const { + return environment_storage.environment_get_sky_orientation(p_env); +} + +Color RendererSceneRender::environment_get_bg_color(RID p_env) const { + return environment_storage.environment_get_bg_color(p_env); +} + +float RendererSceneRender::environment_get_bg_energy(RID p_env) const { + return environment_storage.environment_get_bg_energy(p_env); +} + +int RendererSceneRender::environment_get_canvas_max_layer(RID p_env) const { + return environment_storage.environment_get_canvas_max_layer(p_env); +} + +RS::EnvironmentAmbientSource RendererSceneRender::environment_get_ambient_source(RID p_env) const { + return environment_storage.environment_get_ambient_source(p_env); +} + +Color RendererSceneRender::environment_get_ambient_light(RID p_env) const { + return environment_storage.environment_get_ambient_light(p_env); +} + +float RendererSceneRender::environment_get_ambient_light_energy(RID p_env) const { + return environment_storage.environment_get_ambient_light_energy(p_env); +} + +float RendererSceneRender::environment_get_ambient_sky_contribution(RID p_env) const { + return environment_storage.environment_get_ambient_sky_contribution(p_env); +} + +RS::EnvironmentReflectionSource RendererSceneRender::environment_get_reflection_source(RID p_env) const { + return environment_storage.environment_get_reflection_source(p_env); +} + +// Tonemap + +void RendererSceneRender::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { + environment_storage.environment_set_tonemap(p_env, p_tone_mapper, p_exposure, p_white, p_auto_exposure, p_min_luminance, p_max_luminance, p_auto_exp_speed, p_auto_exp_scale); +} + +RS::EnvironmentToneMapper RendererSceneRender::environment_get_tone_mapper(RID p_env) const { + return environment_storage.environment_get_tone_mapper(p_env); +} + +float RendererSceneRender::environment_get_exposure(RID p_env) const { + return environment_storage.environment_get_exposure(p_env); +} + +float RendererSceneRender::environment_get_white(RID p_env) const { + return environment_storage.environment_get_white(p_env); +} + +bool RendererSceneRender::environment_get_auto_exposure(RID p_env) const { + return environment_storage.environment_get_auto_exposure(p_env); +} + +float RendererSceneRender::environment_get_min_luminance(RID p_env) const { + return environment_storage.environment_get_min_luminance(p_env); +} + +float RendererSceneRender::environment_get_max_luminance(RID p_env) const { + return environment_storage.environment_get_max_luminance(p_env); +} + +float RendererSceneRender::environment_get_auto_exp_speed(RID p_env) const { + return environment_storage.environment_get_auto_exp_speed(p_env); +} + +float RendererSceneRender::environment_get_auto_exp_scale(RID p_env) const { + return environment_storage.environment_get_auto_exp_scale(p_env); +} + +uint64_t RendererSceneRender::environment_get_auto_exposure_version(RID p_env) const { + return environment_storage.environment_get_auto_exposure_version(p_env); +} + +// Fog + +void RendererSceneRender::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) { + environment_storage.environment_set_fog(p_env, p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_aerial_perspective); +} + +bool RendererSceneRender::environment_get_fog_enabled(RID p_env) const { + return environment_storage.environment_get_fog_enabled(p_env); +} + +Color RendererSceneRender::environment_get_fog_light_color(RID p_env) const { + return environment_storage.environment_get_fog_light_color(p_env); +} + +float RendererSceneRender::environment_get_fog_light_energy(RID p_env) const { + return environment_storage.environment_get_fog_light_energy(p_env); +} + +float RendererSceneRender::environment_get_fog_sun_scatter(RID p_env) const { + return environment_storage.environment_get_fog_sun_scatter(p_env); +} + +float RendererSceneRender::environment_get_fog_density(RID p_env) const { + return environment_storage.environment_get_fog_density(p_env); +} + +float RendererSceneRender::environment_get_fog_height(RID p_env) const { + return environment_storage.environment_get_fog_height(p_env); +} + +float RendererSceneRender::environment_get_fog_height_density(RID p_env) const { + return environment_storage.environment_get_fog_height_density(p_env); +} + +float RendererSceneRender::environment_get_fog_aerial_perspective(RID p_env) const { + return environment_storage.environment_get_fog_aerial_perspective(p_env); +} + +// Volumetric Fog + +void RendererSceneRender::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { + environment_storage.environment_set_volumetric_fog(p_env, p_enable, p_density, p_albedo, p_emission, p_emission_energy, p_anisotropy, p_length, p_detail_spread, p_gi_inject, p_temporal_reprojection, p_temporal_reprojection_amount, p_ambient_inject); +} + +bool RendererSceneRender::environment_get_volumetric_fog_enabled(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_enabled(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_density(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_density(p_env); +} + +Color RendererSceneRender::environment_get_volumetric_fog_scattering(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_scattering(p_env); +} + +Color RendererSceneRender::environment_get_volumetric_fog_emission(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_emission(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_emission_energy(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_emission_energy(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_anisotropy(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_anisotropy(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_length(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_length(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_detail_spread(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_detail_spread(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_gi_inject(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_gi_inject(p_env); +} + +bool RendererSceneRender::environment_get_volumetric_fog_temporal_reprojection(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_temporal_reprojection(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_temporal_reprojection_amount(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_ambient_inject(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_ambient_inject(p_env); +} + +// GLOW + +void RendererSceneRender::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) { + environment_storage.environment_set_glow(p_env, p_enable, p_levels, p_intensity, p_strength, p_mix, p_bloom_threshold, p_blend_mode, p_hdr_bleed_threshold, p_hdr_bleed_scale, p_hdr_luminance_cap, p_glow_map_strength, p_glow_map); +} + +bool RendererSceneRender::environment_get_glow_enabled(RID p_env) const { + return environment_storage.environment_get_glow_enabled(p_env); +} + +Vector<float> RendererSceneRender::environment_get_glow_levels(RID p_env) const { + return environment_storage.environment_get_glow_levels(p_env); +} + +float RendererSceneRender::environment_get_glow_intensity(RID p_env) const { + return environment_storage.environment_get_glow_intensity(p_env); +} + +float RendererSceneRender::environment_get_glow_strength(RID p_env) const { + return environment_storage.environment_get_glow_strength(p_env); +} + +float RendererSceneRender::environment_get_glow_bloom(RID p_env) const { + return environment_storage.environment_get_glow_bloom(p_env); +} + +float RendererSceneRender::environment_get_glow_mix(RID p_env) const { + return environment_storage.environment_get_glow_mix(p_env); +} + +RS::EnvironmentGlowBlendMode RendererSceneRender::environment_get_glow_blend_mode(RID p_env) const { + return environment_storage.environment_get_glow_blend_mode(p_env); +} + +float RendererSceneRender::environment_get_glow_hdr_bleed_threshold(RID p_env) const { + return environment_storage.environment_get_glow_hdr_bleed_threshold(p_env); +} + +float RendererSceneRender::environment_get_glow_hdr_luminance_cap(RID p_env) const { + return environment_storage.environment_get_glow_hdr_luminance_cap(p_env); +} + +float RendererSceneRender::environment_get_glow_hdr_bleed_scale(RID p_env) const { + return environment_storage.environment_get_glow_hdr_bleed_scale(p_env); +} + +float RendererSceneRender::environment_get_glow_map_strength(RID p_env) const { + return environment_storage.environment_get_glow_map_strength(p_env); +} + +RID RendererSceneRender::environment_get_glow_map(RID p_env) const { + return environment_storage.environment_get_glow_map(p_env); +} + +// SSR + +void RendererSceneRender::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { + environment_storage.environment_set_ssr(p_env, p_enable, p_max_steps, p_fade_int, p_fade_out, p_depth_tolerance); +} + +bool RendererSceneRender::environment_get_ssr_enabled(RID p_env) const { + return environment_storage.environment_get_ssr_enabled(p_env); +} + +int RendererSceneRender::environment_get_ssr_max_steps(RID p_env) const { + return environment_storage.environment_get_ssr_max_steps(p_env); +} + +float RendererSceneRender::environment_get_ssr_fade_in(RID p_env) const { + return environment_storage.environment_get_ssr_fade_in(p_env); +} + +float RendererSceneRender::environment_get_ssr_fade_out(RID p_env) const { + return environment_storage.environment_get_ssr_fade_out(p_env); +} + +float RendererSceneRender::environment_get_ssr_depth_tolerance(RID p_env) const { + return environment_storage.environment_get_ssr_depth_tolerance(p_env); +} + +// SSAO + +void RendererSceneRender::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) { + environment_storage.environment_set_ssao(p_env, p_enable, p_radius, p_intensity, p_power, p_detail, p_horizon, p_sharpness, p_light_affect, p_ao_channel_affect); +} + +bool RendererSceneRender::environment_get_ssao_enabled(RID p_env) const { + return environment_storage.environment_get_ssao_enabled(p_env); +} + +float RendererSceneRender::environment_get_ssao_radius(RID p_env) const { + return environment_storage.environment_get_ssao_radius(p_env); +} + +float RendererSceneRender::environment_get_ssao_intensity(RID p_env) const { + return environment_storage.environment_get_ssao_intensity(p_env); +} + +float RendererSceneRender::environment_get_ssao_power(RID p_env) const { + return environment_storage.environment_get_ssao_power(p_env); +} + +float RendererSceneRender::environment_get_ssao_detail(RID p_env) const { + return environment_storage.environment_get_ssao_detail(p_env); +} + +float RendererSceneRender::environment_get_ssao_horizon(RID p_env) const { + return environment_storage.environment_get_ssao_horizon(p_env); +} + +float RendererSceneRender::environment_get_ssao_sharpness(RID p_env) const { + return environment_storage.environment_get_ssao_sharpness(p_env); +} + +float RendererSceneRender::environment_get_ssao_direct_light_affect(RID p_env) const { + return environment_storage.environment_get_ssao_direct_light_affect(p_env); +} + +float RendererSceneRender::environment_get_ssao_ao_channel_affect(RID p_env) const { + return environment_storage.environment_get_ssao_ao_channel_affect(p_env); +} + +// SSIL + +void RendererSceneRender::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) { + environment_storage.environment_set_ssil(p_env, p_enable, p_radius, p_intensity, p_sharpness, p_normal_rejection); +} + +bool RendererSceneRender::environment_get_ssil_enabled(RID p_env) const { + return environment_storage.environment_get_ssil_enabled(p_env); +} + +float RendererSceneRender::environment_get_ssil_radius(RID p_env) const { + return environment_storage.environment_get_ssil_radius(p_env); +} + +float RendererSceneRender::environment_get_ssil_intensity(RID p_env) const { + return environment_storage.environment_get_ssil_intensity(p_env); +} + +float RendererSceneRender::environment_get_ssil_sharpness(RID p_env) const { + return environment_storage.environment_get_ssil_sharpness(p_env); +} + +float RendererSceneRender::environment_get_ssil_normal_rejection(RID p_env) const { + return environment_storage.environment_get_ssil_normal_rejection(p_env); +} + +// SDFGI + +void RendererSceneRender::environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { + environment_storage.environment_set_sdfgi(p_env, p_enable, p_cascades, p_min_cell_size, p_y_scale, p_use_occlusion, p_bounce_feedback, p_read_sky, p_energy, p_normal_bias, p_probe_bias); +} + +bool RendererSceneRender::environment_get_sdfgi_enabled(RID p_env) const { + return environment_storage.environment_get_sdfgi_enabled(p_env); +} + +int RendererSceneRender::environment_get_sdfgi_cascades(RID p_env) const { + return environment_storage.environment_get_sdfgi_cascades(p_env); +} + +float RendererSceneRender::environment_get_sdfgi_min_cell_size(RID p_env) const { + return environment_storage.environment_get_sdfgi_min_cell_size(p_env); +} + +bool RendererSceneRender::environment_get_sdfgi_use_occlusion(RID p_env) const { + return environment_storage.environment_get_sdfgi_use_occlusion(p_env); +} + +float RendererSceneRender::environment_get_sdfgi_bounce_feedback(RID p_env) const { + return environment_storage.environment_get_sdfgi_bounce_feedback(p_env); +} + +bool RendererSceneRender::environment_get_sdfgi_read_sky_light(RID p_env) const { + return environment_storage.environment_get_sdfgi_read_sky_light(p_env); +} + +float RendererSceneRender::environment_get_sdfgi_energy(RID p_env) const { + return environment_storage.environment_get_sdfgi_energy(p_env); +} + +float RendererSceneRender::environment_get_sdfgi_normal_bias(RID p_env) const { + return environment_storage.environment_get_sdfgi_normal_bias(p_env); +} + +float RendererSceneRender::environment_get_sdfgi_probe_bias(RID p_env) const { + return environment_storage.environment_get_sdfgi_probe_bias(p_env); +} + +RS::EnvironmentSDFGIYScale RendererSceneRender::environment_get_sdfgi_y_scale(RID p_env) const { + return environment_storage.environment_get_sdfgi_y_scale(p_env); +} + +// Adjustments + +void RendererSceneRender::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) { + environment_storage.environment_set_adjustment(p_env, p_enable, p_brightness, p_contrast, p_saturation, p_use_1d_color_correction, p_color_correction); +} + +bool RendererSceneRender::environment_get_adjustments_enabled(RID p_env) const { + return environment_storage.environment_get_adjustments_enabled(p_env); +} + +float RendererSceneRender::environment_get_adjustments_brightness(RID p_env) const { + return environment_storage.environment_get_adjustments_brightness(p_env); +} + +float RendererSceneRender::environment_get_adjustments_contrast(RID p_env) const { + return environment_storage.environment_get_adjustments_contrast(p_env); +} + +float RendererSceneRender::environment_get_adjustments_saturation(RID p_env) const { + return environment_storage.environment_get_adjustments_saturation(p_env); +} + +bool RendererSceneRender::environment_get_use_1d_color_correction(RID p_env) const { + return environment_storage.environment_get_use_1d_color_correction(p_env); +} + +RID RendererSceneRender::environment_get_color_correction(RID p_env) const { + return environment_storage.environment_get_color_correction(p_env); +} diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 641e280511..7f70f4b939 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -33,9 +33,15 @@ #include "core/math/projection.h" #include "core/templates/paged_array.h" +#include "servers/rendering/renderer_geometry_instance.h" #include "servers/rendering/renderer_scene.h" +#include "servers/rendering/storage/environment_storage.h" +#include "storage/utilities.h" class RendererSceneRender { +private: + RendererEnvironmentStorage environment_storage; + public: enum { MAX_DIRECTIONAL_LIGHTS = 8, @@ -43,38 +49,11 @@ public: MAX_RENDER_VIEWS = 2 }; - struct GeometryInstance { - virtual ~GeometryInstance() {} - }; - - virtual GeometryInstance *geometry_instance_create(RID p_base) = 0; - virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) = 0; - virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) = 0; - virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) = 0; - virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) = 0; - virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) = 0; - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0; - virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) = 0; - virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) = 0; - virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) = 0; - virtual void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) = 0; - virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) = 0; - virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) = 0; - virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) = 0; - virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) = 0; - virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) = 0; - virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) = 0; - virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) = 0; + /* Geometry Instance */ + virtual RenderGeometryInstance *geometry_instance_create(RID p_base) = 0; + virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) = 0; virtual uint32_t geometry_instance_get_pair_mask() = 0; - virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) = 0; - virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) = 0; - virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0; - virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) = 0; - - virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) = 0; - - virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) = 0; /* SHADOW ATLAS API */ @@ -106,57 +85,160 @@ public: /* ENVIRONMENT API */ - virtual RID environment_allocate() = 0; - virtual void environment_initialize(RID p_rid) = 0; - - virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0; - virtual void environment_set_sky(RID p_env, RID p_sky) = 0; - virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0; - virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0; - virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0; - virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0; - virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0; - virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) = 0; + RID environment_allocate(); + void environment_initialize(RID p_rid); + void environment_free(RID p_rid); + + bool is_environment(RID p_env) const; + + // Background + void environment_set_background(RID p_env, RS::EnvironmentBG p_bg); + void environment_set_sky(RID p_env, RID p_sky); + void environment_set_sky_custom_fov(RID p_env, float p_scale); + void environment_set_sky_orientation(RID p_env, const Basis &p_orientation); + void environment_set_bg_color(RID p_env, const Color &p_color); + void environment_set_bg_energy(RID p_env, float p_energy); + void environment_set_canvas_max_layer(RID p_env, int p_max_layer); + void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG); // FIXME: Disabled during Vulkan refactoring, should be ported. #if 0 - virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0; + void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id); #endif - virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) = 0; - virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; - virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; + RS::EnvironmentBG environment_get_background(RID p_env) const; + RID environment_get_sky(RID p_env) const; + float environment_get_sky_custom_fov(RID p_env) const; + Basis environment_get_sky_orientation(RID p_env) const; + Color environment_get_bg_color(RID p_env) const; + float environment_get_bg_energy(RID p_env) const; + int environment_get_canvas_max_layer(RID p_env) const; + RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const; + Color environment_get_ambient_light(RID p_env) const; + float environment_get_ambient_light_energy(RID p_env) const; + float environment_get_ambient_sky_contribution(RID p_env) const; + RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const; + + // Tonemap + void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); + RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const; + float environment_get_exposure(RID p_env) const; + float environment_get_white(RID p_env) const; + bool environment_get_auto_exposure(RID p_env) const; + float environment_get_min_luminance(RID p_env) const; + float environment_get_max_luminance(RID p_env) const; + float environment_get_auto_exp_speed(RID p_env) const; + float environment_get_auto_exp_scale(RID p_env) const; + uint64_t environment_get_auto_exposure_version(RID p_env) const; + + // Fog + void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective); + bool environment_get_fog_enabled(RID p_env) const; + Color environment_get_fog_light_color(RID p_env) const; + float environment_get_fog_light_energy(RID p_env) const; + float environment_get_fog_sun_scatter(RID p_env) const; + float environment_get_fog_density(RID p_env) const; + float environment_get_fog_height(RID p_env) const; + float environment_get_fog_height_density(RID p_env) const; + float environment_get_fog_aerial_perspective(RID p_env) const; + + // Volumetric Fog + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject); + bool environment_get_volumetric_fog_enabled(RID p_env) const; + float environment_get_volumetric_fog_density(RID p_env) const; + Color environment_get_volumetric_fog_scattering(RID p_env) const; + Color environment_get_volumetric_fog_emission(RID p_env) const; + float environment_get_volumetric_fog_emission_energy(RID p_env) const; + float environment_get_volumetric_fog_anisotropy(RID p_env) const; + float environment_get_volumetric_fog_length(RID p_env) const; + float environment_get_volumetric_fog_detail_spread(RID p_env) const; + float environment_get_volumetric_fog_gi_inject(RID p_env) const; + bool environment_get_volumetric_fog_temporal_reprojection(RID p_env) const; + float environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const; + float environment_get_volumetric_fog_ambient_inject(RID p_env) const; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; - virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; + // GLOW + void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map); + bool environment_get_glow_enabled(RID p_env) const; + Vector<float> environment_get_glow_levels(RID p_env) const; + float environment_get_glow_intensity(RID p_env) const; + float environment_get_glow_strength(RID p_env) const; + float environment_get_glow_bloom(RID p_env) const; + float environment_get_glow_mix(RID p_env) const; + RS::EnvironmentGlowBlendMode environment_get_glow_blend_mode(RID p_env) const; + float environment_get_glow_hdr_bleed_threshold(RID p_env) const; + float environment_get_glow_hdr_luminance_cap(RID p_env) const; + float environment_get_glow_hdr_bleed_scale(RID p_env) const; + float environment_get_glow_map_strength(RID p_env) const; + RID environment_get_glow_map(RID p_env) const; + + virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; + virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; + + // SSR + void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance); + bool environment_get_ssr_enabled(RID p_env) const; + int environment_get_ssr_max_steps(RID p_env) const; + float environment_get_ssr_fade_in(RID p_env) const; + float environment_get_ssr_fade_out(RID p_env) const; + float environment_get_ssr_depth_tolerance(RID p_env) const; + virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; - virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) = 0; + // SSAO + void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect); + bool environment_get_ssao_enabled(RID p_env) const; + float environment_get_ssao_radius(RID p_env) const; + float environment_get_ssao_intensity(RID p_env) const; + float environment_get_ssao_power(RID p_env) const; + float environment_get_ssao_detail(RID p_env) const; + float environment_get_ssao_horizon(RID p_env) const; + float environment_get_ssao_sharpness(RID p_env) const; + float environment_get_ssao_direct_light_affect(RID p_env) const; + float environment_get_ssao_ao_channel_affect(RID p_env) const; + virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0; - virtual void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) = 0; + // SSIL + void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection); + bool environment_get_ssil_enabled(RID p_env) const; + float environment_get_ssil_radius(RID p_env) const; + float environment_get_ssil_intensity(RID p_env) const; + float environment_get_ssil_sharpness(RID p_env) const; + float environment_get_ssil_normal_rejection(RID p_env) const; + virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + // SDFGI + void environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias); + bool environment_get_sdfgi_enabled(RID p_env) const; + int environment_get_sdfgi_cascades(RID p_env) const; + float environment_get_sdfgi_min_cell_size(RID p_env) const; + bool environment_get_sdfgi_use_occlusion(RID p_env) const; + float environment_get_sdfgi_bounce_feedback(RID p_env) const; + bool environment_get_sdfgi_read_sky_light(RID p_env) const; + float environment_get_sdfgi_energy(RID p_env) const; + float environment_get_sdfgi_normal_bias(RID p_env) const; + float environment_get_sdfgi_probe_bias(RID p_env) const; + RS::EnvironmentSDFGIYScale environment_get_sdfgi_y_scale(RID p_env) const; virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0; virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0; virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) = 0; - virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; - - virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) = 0; - - virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; + // Adjustment + void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction); + bool environment_get_adjustments_enabled(RID p_env) const; + float environment_get_adjustments_brightness(RID p_env) const; + float environment_get_adjustments_contrast(RID p_env) const; + float environment_get_adjustments_saturation(RID p_env) const; + bool environment_get_use_1d_color_correction(RID p_env) const; + RID environment_get_color_correction(RID p_env) const; virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; - virtual bool is_environment(RID p_env) const = 0; - virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0; - virtual int environment_get_canvas_max_layer(RID p_env) const = 0; - virtual RID camera_effects_allocate() = 0; virtual void camera_effects_initialize(RID p_rid) = 0; @@ -205,19 +287,19 @@ public: virtual RID voxel_gi_instance_create(RID p_voxel_gi) = 0; virtual void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) = 0; virtual bool voxel_gi_needs_update(RID p_probe) const = 0; - virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) = 0; + virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) = 0; virtual void voxel_gi_set_quality(RS::VoxelGIQuality) = 0; struct RenderShadowData { RID light; int pass = 0; - PagedArray<GeometryInstance *> instances; + PagedArray<RenderGeometryInstance *> instances; }; struct RenderSDFGIData { int region = 0; - PagedArray<GeometryInstance *> instances; + PagedArray<RenderGeometryInstance *> instances; }; struct RenderSDFGIUpdateData { @@ -249,17 +331,17 @@ public: void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect); }; - virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) = 0; + virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) = 0; - virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0; + virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) = 0; virtual void set_scene_pass(uint64_t p_pass) = 0; virtual void set_time(double p_time, double p_step) = 0; virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0; virtual RID render_buffers_create() = 0; - virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) = 0; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) = 0; virtual void gi_set_use_half_resolution(bool p_enable) = 0; virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 0e26de8bcb..118bf532b3 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -138,7 +138,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) { p_viewport->internal_size = Size2(render_width, render_height); - RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, render_width, render_height, width, height, p_viewport->fsr_sharpness, p_viewport->fsr_mipmap_bias, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->get_view_count()); + RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, render_width, render_height, width, height, p_viewport->fsr_sharpness, p_viewport->texture_mipmap_bias, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->get_view_count()); } } } @@ -746,11 +746,11 @@ void RendererViewport::viewport_set_fsr_sharpness(RID p_viewport, float p_sharpn _configure_3d_render_buffers(viewport); } -void RendererViewport::viewport_set_fsr_mipmap_bias(RID p_viewport, float p_mipmap_bias) { +void RendererViewport::viewport_set_texture_mipmap_bias(RID p_viewport, float p_mipmap_bias) { Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); - viewport->fsr_mipmap_bias = p_mipmap_bias; + viewport->texture_mipmap_bias = p_mipmap_bias; _configure_3d_render_buffers(viewport); } diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index 027f2dfad6..5e37c96336 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -48,33 +48,34 @@ public: RID self; RID parent; - bool use_xr; /* use xr interface to override camera positioning and projection matrices and control output */ + // use xr interface to override camera positioning and projection matrices and control output + bool use_xr = false; Size2i internal_size; Size2i size; RID camera; RID scenario; - RS::ViewportScaling3DMode scaling_3d_mode; + RS::ViewportScaling3DMode scaling_3d_mode = RenderingServer::VIEWPORT_SCALING_3D_MODE_BILINEAR; float scaling_3d_scale = 1.0; float fsr_sharpness = 0.2f; - float fsr_mipmap_bias = 0.0f; - bool fsr_enabled; - RS::ViewportUpdateMode update_mode; + float texture_mipmap_bias = 0.0f; + bool fsr_enabled = false; + RS::ViewportUpdateMode update_mode = RenderingServer::VIEWPORT_UPDATE_WHEN_VISIBLE; RID render_target; RID render_target_texture; RID render_buffers; - RS::ViewportMSAA msaa; - RS::ViewportScreenSpaceAA screen_space_aa; - bool use_taa; - bool use_debanding; + RS::ViewportMSAA msaa = RenderingServer::VIEWPORT_MSAA_DISABLED; + RS::ViewportScreenSpaceAA screen_space_aa = RenderingServer::VIEWPORT_SCREEN_SPACE_AA_DISABLED; + bool use_taa = false; + bool use_debanding = false; RendererSceneRender::CameraData prev_camera_data; uint64_t prev_camera_data_frame = 0; - bool use_occlusion_culling; - bool occlusion_buffer_dirty; + bool use_occlusion_culling = false; + bool occlusion_buffer_dirty = false; DisplayServer::WindowID viewport_to_screen; Rect2 viewport_to_screen_rect; @@ -83,10 +84,10 @@ public: bool disable_2d = false; bool disable_environment = false; bool disable_3d = false; - bool measure_render_time; + bool measure_render_time = false; - bool snap_2d_transforms_to_pixel; - bool snap_2d_vertices_to_pixel; + bool snap_2d_transforms_to_pixel = false; + bool snap_2d_vertices_to_pixel = false; uint64_t time_cpu_begin; uint64_t time_cpu_end; @@ -95,23 +96,23 @@ public: uint64_t time_gpu_end; RID shadow_atlas; - int shadow_atlas_size; + int shadow_atlas_size = 2048; bool shadow_atlas_16_bits = true; - bool sdf_active; + bool sdf_active = false; float mesh_lod_threshold = 1.0; uint64_t last_pass = 0; - RS::ViewportDebugDraw debug_draw; + RS::ViewportDebugDraw debug_draw = RenderingServer::VIEWPORT_DEBUG_DRAW_DISABLED; - RS::ViewportClearMode clear_mode; + RS::ViewportClearMode clear_mode = RenderingServer::VIEWPORT_CLEAR_ALWAYS; RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; - bool transparent_bg; + bool transparent_bg = false; struct CanvasKey { int64_t stacking; @@ -228,7 +229,7 @@ public: void viewport_set_scaling_3d_mode(RID p_viewport, RS::ViewportScaling3DMode p_mode); void viewport_set_scaling_3d_scale(RID p_viewport, float p_scaling_3d_scale); void viewport_set_fsr_sharpness(RID p_viewport, float p_sharpness); - void viewport_set_fsr_mipmap_bias(RID p_viewport, float p_mipmap_bias); + void viewport_set_texture_mipmap_bias(RID p_viewport, float p_mipmap_bias); void viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode); void viewport_set_vflip(RID p_viewport, bool p_enable); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 0b76bb3051..c07a783302 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -387,6 +387,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("framebuffer_create_multipass", "textures", "passes", "validate_with_format", "view_count"), &RenderingDevice::_framebuffer_create_multipass, DEFVAL(INVALID_FORMAT_ID), DEFVAL(1)); ClassDB::bind_method(D_METHOD("framebuffer_create_empty", "size", "samples", "validate_with_format"), &RenderingDevice::framebuffer_create_empty, DEFVAL(TEXTURE_SAMPLES_1), DEFVAL(INVALID_FORMAT_ID)); ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format); + ClassDB::bind_method(D_METHOD("framebuffer_is_valid", "framebuffer"), &RenderingDevice::framebuffer_is_valid); ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 03aa6f7644..a864cfa74c 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -129,6 +129,8 @@ public: typedef Vector<uint8_t> (*ShaderCompileToSPIRVFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, const RenderingDevice *p_render_device); typedef Vector<uint8_t> (*ShaderCacheFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language); + typedef void (*InvalidationCallback)(void *); + private: static ShaderCompileToSPIRVFunction compile_to_spirv_function; static ShaderCacheFunction cache_function; @@ -547,13 +549,15 @@ public: int32_t vrs_attachment = ATTACHMENT_UNUSED; // density map for VRS, only used if supported }; - virtual FramebufferFormatID framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, Vector<FramebufferPass> &p_passes, uint32_t p_view_count = 1) = 0; + virtual FramebufferFormatID framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, uint32_t p_view_count = 1) = 0; virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1) = 0; virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format, uint32_t p_pass = 0) = 0; virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1) = 0; - virtual RID framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1) = 0; + virtual RID framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, const Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1) = 0; virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID) = 0; + virtual bool framebuffer_is_valid(RID p_framebuffer) const = 0; + virtual void framebuffer_set_invalidation_callback(RID p_framebuffer, InvalidationCallback p_callback, void *p_userdata) = 0; virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer) = 0; @@ -793,8 +797,7 @@ public: virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) = 0; virtual bool uniform_set_is_valid(RID p_uniform_set) = 0; - typedef void (*UniformSetInvalidatedCallback)(void *); - virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata) = 0; + virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, InvalidationCallback p_callback, void *p_userdata) = 0; virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index bcd7e6a1dd..8071b7e416 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -106,7 +106,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { Callable c = frame_drawn_callbacks.front()->get(); Variant result; Callable::CallError ce; - c.call(nullptr, 0, result, ce); + c.callp(nullptr, 0, result, ce); if (ce.error != Callable::CallError::CALL_OK) { String err = Variant::get_callable_error_text(c, nullptr, 0, ce); ERR_PRINT("Error calling frame drawn function: " + err); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index f093f43a82..cc79d09503 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -227,7 +227,7 @@ public: FUNC2(shader_set_path_hint, RID, const String &) FUNC1RC(String, shader_get_code, RID) - FUNC2SC(shader_get_param_list, RID, List<PropertyInfo> *) + FUNC2SC(shader_get_shader_uniform_list, RID, List<PropertyInfo> *) FUNC4(shader_set_default_texture_param, RID, const StringName &, RID, int) FUNC3RC(RID, shader_get_default_texture_param, RID, const StringName &, int) @@ -591,7 +591,7 @@ public: FUNC2(viewport_set_scaling_3d_mode, RID, ViewportScaling3DMode) FUNC2(viewport_set_scaling_3d_scale, RID, float) FUNC2(viewport_set_fsr_sharpness, RID, float) - FUNC2(viewport_set_fsr_mipmap_bias, RID, float) + FUNC2(viewport_set_texture_mipmap_bias, RID, float) FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode) @@ -773,10 +773,10 @@ public: FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) FUNC2(instance_geometry_set_lod_bias, RID, float) FUNC2(instance_geometry_set_transparency, RID, float) - FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) - FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) - FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) - FUNC2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) + FUNC3(instance_geometry_set_shader_uniform, RID, const StringName &, const Variant &) + FUNC2RC(Variant, instance_geometry_get_shader_uniform, RID, const StringName &) + FUNC2RC(Variant, instance_geometry_get_shader_uniform_default_value, RID, const StringName &) + FUNC2C(instance_geometry_get_shader_uniform_list, RID, List<PropertyInfo> *) FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) @@ -900,7 +900,7 @@ public: FUNC1(canvas_set_shadow_texture_size, int) - /* GLOBAL VARIABLES */ + /* GLOBAL SHADER UNIFORMS */ #undef server_name #undef ServerName @@ -908,16 +908,16 @@ public: #define ServerName RendererMaterialStorage #define server_name RSG::material_storage - FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &) - FUNC1(global_variable_remove, const StringName &) - FUNC0RC(Vector<StringName>, global_variable_get_list) - FUNC2(global_variable_set, const StringName &, const Variant &) - FUNC2(global_variable_set_override, const StringName &, const Variant &) - FUNC1RC(GlobalVariableType, global_variable_get_type, const StringName &) - FUNC1RC(Variant, global_variable_get, const StringName &) + FUNC3(global_shader_uniform_add, const StringName &, GlobalShaderUniformType, const Variant &) + FUNC1(global_shader_uniform_remove, const StringName &) + FUNC0RC(Vector<StringName>, global_shader_uniform_get_list) + FUNC2(global_shader_uniform_set, const StringName &, const Variant &) + FUNC2(global_shader_uniform_set_override, const StringName &, const Variant &) + FUNC1RC(GlobalShaderUniformType, global_shader_uniform_get_type, const StringName &) + FUNC1RC(Variant, global_shader_uniform_get, const StringName &) - FUNC1(global_variables_load_settings, bool) - FUNC0(global_variables_clear) + FUNC1(global_shader_uniforms_load_settings, bool) + FUNC0(global_shader_uniforms_clear) #undef server_name #undef ServerName diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index e291246d01..7637eae4a6 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -370,7 +370,7 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str } } -static String _get_global_variable_from_type_and_index(const String &p_buffer, const String &p_index, ShaderLanguage::DataType p_type) { +static String _get_global_shader_uniform_from_type_and_index(const String &p_buffer, const String &p_index, ShaderLanguage::DataType p_type) { switch (p_type) { case ShaderLanguage::TYPE_BOOL: { return "(" + p_buffer + "[" + p_index + "].x != 0.0)"; @@ -903,11 +903,11 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { code = actions.base_uniform_string + _mkid(vnode->name); //texture, use as is //global variable, this means the code points to an index to the global table - code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); + code = _get_global_shader_uniform_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); } else if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { //instance variable, index it as such code = "(" + p_default_actions.instance_uniform_index_variable + "+" + itos(u.instance_index) + ")"; - code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); + code = _get_global_shader_uniform_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); } else { //regular uniform, index from UBO code = actions.base_uniform_string + _mkid(vnode->name); @@ -1003,11 +1003,11 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { code = actions.base_uniform_string + _mkid(anode->name); //texture, use as is //global variable, this means the code points to an index to the global table - code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); + code = _get_global_shader_uniform_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); } else if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { //instance variable, index it as such code = "(" + p_default_actions.instance_uniform_index_variable + "+" + itos(u.instance_index) + ")"; - code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); + code = _get_global_shader_uniform_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); } else { //regular uniform, index from UBO code = actions.base_uniform_string + _mkid(anode->name); @@ -1309,8 +1309,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } ShaderLanguage::DataType ShaderCompiler::_get_variable_type(const StringName &p_type) { - RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_type); - return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt); + RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(p_type); + return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); } Error ShaderCompiler::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) { @@ -1318,7 +1318,7 @@ Error ShaderCompiler::compile(RS::ShaderMode p_mode, const String &p_code, Ident info.functions = ShaderTypes::get_singleton()->get_functions(p_mode); info.render_modes = ShaderTypes::get_singleton()->get_modes(p_mode); info.shader_types = ShaderTypes::get_singleton()->get_types(); - info.global_variable_type_func = _get_variable_type; + info.global_shader_uniform_type_func = _get_variable_type; Error err = parser.compile(p_code, info); diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 9fc3e8f8d9..839f5b8eea 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -195,6 +195,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "SOURCE_COLOR", "HINT_DEFAULT_WHITE_TEXTURE", "HINT_DEFAULT_BLACK_TEXTURE", + "HINT_DEFAULT_TRANSPARENT_TEXTURE", "HINT_NORMAL_TEXTURE", "HINT_ANISOTROPY_TEXTURE", "HINT_RANGE", @@ -354,6 +355,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = { { TK_HINT_NORMAL_TEXTURE, "hint_normal", CF_UNSPECIFIED, {}, {} }, { TK_HINT_DEFAULT_WHITE_TEXTURE, "hint_default_white", CF_UNSPECIFIED, {}, {} }, { TK_HINT_DEFAULT_BLACK_TEXTURE, "hint_default_black", CF_UNSPECIFIED, {}, {} }, + { TK_HINT_DEFAULT_TRANSPARENT_TEXTURE, "hint_default_transparent", CF_UNSPECIFIED, {}, {} }, { TK_HINT_ANISOTROPY_TEXTURE, "hint_anisotropy", CF_UNSPECIFIED, {}, {} }, { TK_HINT_ROUGHNESS_R, "hint_roughness_r", CF_UNSPECIFIED, {}, {} }, { TK_HINT_ROUGHNESS_G, "hint_roughness_g", CF_UNSPECIFIED, {}, {} }, @@ -1088,6 +1090,9 @@ String ShaderLanguage::get_uniform_hint_name(ShaderNode::Uniform::Hint p_hint) { case ShaderNode::Uniform::HINT_DEFAULT_WHITE: { result = "hint_default_white"; } break; + case ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT: { + result = "hint_default_transparent"; + } break; case ShaderNode::Uniform::HINT_ANISOTROPY: { result = "hint_anisotropy"; } break; @@ -2458,11 +2463,15 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { // reflect + { "reflect", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "I", "N" }, TAG_GLOBAL, false }, { "reflect", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "I", "N" }, TAG_GLOBAL, false }, + { "reflect", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "I", "N" }, TAG_GLOBAL, false }, // refract + { "refract", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "I", "N", "eta" }, TAG_GLOBAL, false }, { "refract", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "I", "N", "eta" }, TAG_GLOBAL, false }, + { "refract", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "I", "N", "eta" }, TAG_GLOBAL, false }, // faceforward @@ -3856,18 +3865,11 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C } value = Variant(array); } else { - Basis p; - p[0][0] = p_value[0].real; - p[0][1] = p_value[1].real; - p[0][2] = p_value[2].real; - p[1][0] = p_value[4].real; - p[1][1] = p_value[5].real; - p[1][2] = p_value[6].real; - p[2][0] = p_value[8].real; - p[2][1] = p_value[9].real; - p[2][2] = p_value[10].real; - Transform3D t = Transform3D(p, Vector3(p_value[3].real, p_value[7].real, p_value[11].real)); - value = Variant(t); + Projection p = Projection(Vector4(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real), + Vector4(p_value[4].real, p_value[5].real, p_value[6].real, p_value[7].real), + Vector4(p_value[8].real, p_value[9].real, p_value[10].real, p_value[11].real), + Vector4(p_value[12].real, p_value[13].real, p_value[14].real, p_value[15].real)); + value = Variant(p); } break; } @@ -7160,9 +7162,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun if (!n) { return ERR_PARSE_ERROR; } - if (n->get_datatype() != TYPE_INT) { - _set_error(RTR("Expected an integer expression.")); - return ERR_PARSE_ERROR; + { + const ShaderLanguage::DataType switch_type = n->get_datatype(); + if (switch_type != TYPE_INT && switch_type != TYPE_UINT) { + _set_error(RTR("Expected an integer expression.")); + return ERR_PARSE_ERROR; + } } tk = _get_token(); if (tk.type != TK_PARENTHESIS_CLOSE) { @@ -8284,7 +8289,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f if (is_uniform) { if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL && Engine::get_singleton()->is_editor_hint()) { // Type checking for global uniforms is not allowed outside the editor. //validate global uniform - DataType gvtype = global_var_get_type_func(name); + DataType gvtype = global_shader_uniform_get_type_func(name); if (gvtype == TYPE_MAX) { _set_error(vformat(RTR("Global uniform '%s' does not exist. Create it in Project Settings."), String(name))); return ERR_PARSE_ERROR; @@ -8417,6 +8422,9 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f case TK_HINT_DEFAULT_WHITE_TEXTURE: { new_hint = ShaderNode::Uniform::HINT_DEFAULT_WHITE; } break; + case TK_HINT_DEFAULT_TRANSPARENT_TEXTURE: { + new_hint = ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT; + } break; case TK_HINT_NORMAL_TEXTURE: { new_hint = ShaderNode::Uniform::HINT_NORMAL; } break; @@ -9659,7 +9667,7 @@ Error ShaderLanguage::compile(const String &p_code, const ShaderCompileInfo &p_i is_shader_inc = p_info.is_include; code = p_code; - global_var_get_type_func = p_info.global_variable_type_func; + global_shader_uniform_get_type_func = p_info.global_shader_uniform_type_func; varying_function_names = p_info.varying_function_names; @@ -9688,7 +9696,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ varying_function_names = p_info.varying_function_names; nodes = nullptr; - global_var_get_type_func = p_info.global_variable_type_func; + global_shader_uniform_get_type_func = p_info.global_shader_uniform_type_func; shader = alloc_node<ShaderNode>(); _parse_shader(p_info.functions, p_info.render_modes, p_info.shader_types); @@ -10255,6 +10263,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ options.push_back("hint_anisotropy"); options.push_back("hint_default_black"); options.push_back("hint_default_white"); + options.push_back("hint_default_transparent"); options.push_back("hint_normal"); options.push_back("hint_roughness_a"); options.push_back("hint_roughness_b"); diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 42023f25d7..bfec6e1df6 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -164,6 +164,7 @@ public: TK_RENDER_MODE, TK_HINT_DEFAULT_WHITE_TEXTURE, TK_HINT_DEFAULT_BLACK_TEXTURE, + TK_HINT_DEFAULT_TRANSPARENT_TEXTURE, TK_HINT_NORMAL_TEXTURE, TK_HINT_ROUGHNESS_NORMAL_TEXTURE, TK_HINT_ROUGHNESS_R, @@ -664,6 +665,7 @@ public: HINT_ROUGHNESS_GRAY, HINT_DEFAULT_BLACK, HINT_DEFAULT_WHITE, + HINT_DEFAULT_TRANSPARENT, HINT_ANISOTROPY, HINT_MAX }; @@ -869,7 +871,7 @@ public: }; static bool has_builtin(const HashMap<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name); - typedef DataType (*GlobalVariableGetTypeFunc)(const StringName &p_name); + typedef DataType (*GlobalShaderUniformGetTypeFunc)(const StringName &p_name); struct FilePosition { String file; @@ -887,7 +889,7 @@ private: static const KeyWord keyword_list[]; - GlobalVariableGetTypeFunc global_var_get_type_func = nullptr; + GlobalShaderUniformGetTypeFunc global_shader_uniform_get_type_func = nullptr; bool error_set = false; String error_str; @@ -1113,7 +1115,7 @@ public: Vector<ModeInfo> render_modes; VaryingFunctionNames varying_function_names = VaryingFunctionNames(); HashSet<String> shader_types; - GlobalVariableGetTypeFunc global_variable_type_func = nullptr; + GlobalShaderUniformGetTypeFunc global_shader_uniform_type_func = nullptr; bool is_include = false; }; diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 5772179d68..43c483a00d 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -97,6 +97,11 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL); + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NODE_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_DIRECTION_WORLD"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NODE_POSITION_VIEW"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEW_INDEX"] = constt(ShaderLanguage::TYPE_INT); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEW_MONO_LEFT"] = constt(ShaderLanguage::TYPE_INT); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEW_RIGHT"] = constt(ShaderLanguage::TYPE_INT); @@ -139,6 +144,11 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NODE_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_DIRECTION_WORLD"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NODE_POSITION_VIEW"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW_INDEX"] = constt(ShaderLanguage::TYPE_INT); shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW_MONO_LEFT"] = constt(ShaderLanguage::TYPE_INT); shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW_RIGHT"] = constt(ShaderLanguage::TYPE_INT); diff --git a/servers/rendering/storage/environment_storage.cpp b/servers/rendering/storage/environment_storage.cpp new file mode 100644 index 0000000000..1d4dc55e98 --- /dev/null +++ b/servers/rendering/storage/environment_storage.cpp @@ -0,0 +1,769 @@ +/*************************************************************************/ +/* environment_storage.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "environment_storage.h" + +uint64_t RendererEnvironmentStorage::auto_exposure_counter = 2; + +RID RendererEnvironmentStorage::environment_allocate() { + return environment_owner.allocate_rid(); +} + +void RendererEnvironmentStorage::environment_initialize(RID p_rid) { + environment_owner.initialize_rid(p_rid, Environment()); +} + +void RendererEnvironmentStorage::environment_free(RID p_rid) { + environment_owner.free(p_rid); +} + +// Background + +void RendererEnvironmentStorage::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->background = p_bg; +} + +void RendererEnvironmentStorage::environment_set_sky(RID p_env, RID p_sky) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->sky = p_sky; +} + +void RendererEnvironmentStorage::environment_set_sky_custom_fov(RID p_env, float p_scale) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->sky_custom_fov = p_scale; +} + +void RendererEnvironmentStorage::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->sky_orientation = p_orientation; +} + +void RendererEnvironmentStorage::environment_set_bg_color(RID p_env, const Color &p_color) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->bg_color = p_color; +} + +void RendererEnvironmentStorage::environment_set_bg_energy(RID p_env, float p_energy) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->bg_energy = p_energy; +} + +void RendererEnvironmentStorage::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->canvas_max_layer = p_max_layer; +} + +void RendererEnvironmentStorage::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->ambient_light = p_color; + env->ambient_source = p_ambient; + env->ambient_light_energy = p_energy; + env->ambient_sky_contribution = p_sky_contribution; + env->reflection_source = p_reflection_source; +} + +RS::EnvironmentBG RendererEnvironmentStorage::environment_get_background(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_BG_CLEAR_COLOR); + return env->background; +} + +RID RendererEnvironmentStorage::environment_get_sky(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RID()); + return env->sky; +} + +float RendererEnvironmentStorage::environment_get_sky_custom_fov(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->sky_custom_fov; +} + +Basis RendererEnvironmentStorage::environment_get_sky_orientation(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Basis()); + return env->sky_orientation; +} + +Color RendererEnvironmentStorage::environment_get_bg_color(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Color()); + return env->bg_color; +} + +float RendererEnvironmentStorage::environment_get_bg_energy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->bg_energy; +} + +int RendererEnvironmentStorage::environment_get_canvas_max_layer(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0); + return env->canvas_max_layer; +} + +RS::EnvironmentAmbientSource RendererEnvironmentStorage::environment_get_ambient_source(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG); + return env->ambient_source; +} + +Color RendererEnvironmentStorage::environment_get_ambient_light(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Color()); + return env->ambient_light; +} + +float RendererEnvironmentStorage::environment_get_ambient_light_energy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->ambient_light_energy; +} + +float RendererEnvironmentStorage::environment_get_ambient_sky_contribution(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->ambient_sky_contribution; +} + +RS::EnvironmentReflectionSource RendererEnvironmentStorage::environment_get_reflection_source(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_BG); + return env->reflection_source; +} + +// Tonemap + +void RendererEnvironmentStorage::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->exposure = p_exposure; + env->tone_mapper = p_tone_mapper; + if (!env->auto_exposure && p_auto_exposure) { + env->auto_exposure_version = ++auto_exposure_counter; + } + env->auto_exposure = p_auto_exposure; + env->white = p_white; + env->min_luminance = p_min_luminance; + env->max_luminance = p_max_luminance; + env->auto_exp_speed = p_auto_exp_speed; + env->auto_exp_scale = p_auto_exp_scale; +} + +RS::EnvironmentToneMapper RendererEnvironmentStorage::environment_get_tone_mapper(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_TONE_MAPPER_LINEAR); + return env->tone_mapper; +} + +float RendererEnvironmentStorage::environment_get_exposure(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->exposure; +} + +float RendererEnvironmentStorage::environment_get_white(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->white; +} + +bool RendererEnvironmentStorage::environment_get_auto_exposure(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->auto_exposure; +} + +float RendererEnvironmentStorage::environment_get_min_luminance(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.2); + return env->min_luminance; +} + +float RendererEnvironmentStorage::environment_get_max_luminance(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 8.0); + return env->max_luminance; +} + +float RendererEnvironmentStorage::environment_get_auto_exp_speed(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.2); + return env->auto_exp_speed; +} + +float RendererEnvironmentStorage::environment_get_auto_exp_scale(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.5); + return env->auto_exp_scale; +} + +uint64_t RendererEnvironmentStorage::environment_get_auto_exposure_version(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0); + return env->auto_exposure_version; +} + +// Fog + +void RendererEnvironmentStorage::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->fog_enabled = p_enable; + env->fog_light_color = p_light_color; + env->fog_light_energy = p_light_energy; + env->fog_sun_scatter = p_sun_scatter; + env->fog_density = p_density; + env->fog_height = p_height; + env->fog_height_density = p_height_density; + env->fog_aerial_perspective = p_fog_aerial_perspective; +} + +bool RendererEnvironmentStorage::environment_get_fog_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->fog_enabled; +} + +Color RendererEnvironmentStorage::environment_get_fog_light_color(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Color(0.5, 0.6, 0.7)); + return env->fog_light_color; +} + +float RendererEnvironmentStorage::environment_get_fog_light_energy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->fog_light_energy; +} + +float RendererEnvironmentStorage::environment_get_fog_sun_scatter(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->fog_sun_scatter; +} + +float RendererEnvironmentStorage::environment_get_fog_density(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.001); + return env->fog_density; +} + +float RendererEnvironmentStorage::environment_get_fog_height(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->fog_height; +} + +float RendererEnvironmentStorage::environment_get_fog_height_density(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->fog_height_density; +} + +float RendererEnvironmentStorage::environment_get_fog_aerial_perspective(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->fog_aerial_perspective; +} + +// Volumetric Fog + +void RendererEnvironmentStorage::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->volumetric_fog_enabled = p_enable; + env->volumetric_fog_density = p_density; + env->volumetric_fog_scattering = p_albedo; + env->volumetric_fog_emission = p_emission; + env->volumetric_fog_emission_energy = p_emission_energy; + env->volumetric_fog_anisotropy = p_anisotropy, + env->volumetric_fog_length = p_length; + env->volumetric_fog_detail_spread = p_detail_spread; + env->volumetric_fog_gi_inject = p_gi_inject; + env->volumetric_fog_temporal_reprojection = p_temporal_reprojection; + env->volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount; + env->volumetric_fog_ambient_inject = p_ambient_inject; +} + +bool RendererEnvironmentStorage::environment_get_volumetric_fog_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->volumetric_fog_enabled; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_density(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.01); + return env->volumetric_fog_density; +} + +Color RendererEnvironmentStorage::environment_get_volumetric_fog_scattering(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Color(1, 1, 1)); + return env->volumetric_fog_scattering; +} + +Color RendererEnvironmentStorage::environment_get_volumetric_fog_emission(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Color(0, 0, 0)); + return env->volumetric_fog_emission; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_emission_energy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->volumetric_fog_emission_energy; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_anisotropy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.2); + return env->volumetric_fog_anisotropy; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_length(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 64.0); + return env->volumetric_fog_length; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_detail_spread(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 2.0); + return env->volumetric_fog_detail_spread; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_gi_inject(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->volumetric_fog_gi_inject; +} + +bool RendererEnvironmentStorage::environment_get_volumetric_fog_temporal_reprojection(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, true); + return env->volumetric_fog_temporal_reprojection; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.9); + return env->volumetric_fog_temporal_reprojection_amount; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_ambient_inject(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->volumetric_fog_ambient_inject; +} + +// GLOW + +void RendererEnvironmentStorage::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7"); + env->glow_enabled = p_enable; + env->glow_levels = p_levels; + env->glow_intensity = p_intensity; + env->glow_strength = p_strength; + env->glow_mix = p_mix; + env->glow_bloom = p_bloom_threshold; + env->glow_blend_mode = p_blend_mode; + env->glow_hdr_bleed_threshold = p_hdr_bleed_threshold; + env->glow_hdr_bleed_scale = p_hdr_bleed_scale; + env->glow_hdr_luminance_cap = p_hdr_luminance_cap; + env->glow_map_strength = p_glow_map_strength; + env->glow_map = p_glow_map; +} + +bool RendererEnvironmentStorage::environment_get_glow_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->glow_enabled; +} + +Vector<float> RendererEnvironmentStorage::environment_get_glow_levels(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Vector<float>()); + return env->glow_levels; +} + +float RendererEnvironmentStorage::environment_get_glow_intensity(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.8); + return env->glow_intensity; +} + +float RendererEnvironmentStorage::environment_get_glow_strength(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->glow_strength; +} + +float RendererEnvironmentStorage::environment_get_glow_bloom(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->glow_bloom; +} + +float RendererEnvironmentStorage::environment_get_glow_mix(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.01); + return env->glow_mix; +} + +RS::EnvironmentGlowBlendMode RendererEnvironmentStorage::environment_get_glow_blend_mode(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT); + return env->glow_blend_mode; +} + +float RendererEnvironmentStorage::environment_get_glow_hdr_bleed_threshold(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->glow_hdr_bleed_threshold; +} + +float RendererEnvironmentStorage::environment_get_glow_hdr_luminance_cap(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 12.0); + return env->glow_hdr_luminance_cap; +} + +float RendererEnvironmentStorage::environment_get_glow_hdr_bleed_scale(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 2.0); + return env->glow_hdr_bleed_scale; +} + +float RendererEnvironmentStorage::environment_get_glow_map_strength(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->glow_map_strength; +} + +RID RendererEnvironmentStorage::environment_get_glow_map(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RID()); + return env->glow_map; +} + +// SSR + +void RendererEnvironmentStorage::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->ssr_enabled = p_enable; + env->ssr_max_steps = p_max_steps; + env->ssr_fade_in = p_fade_int; + env->ssr_fade_out = p_fade_out; + env->ssr_depth_tolerance = p_depth_tolerance; +} + +bool RendererEnvironmentStorage::environment_get_ssr_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->ssr_enabled; +} + +int RendererEnvironmentStorage::environment_get_ssr_max_steps(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 64); + return env->ssr_max_steps; +} + +float RendererEnvironmentStorage::environment_get_ssr_fade_in(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.15); + return env->ssr_fade_in; +} + +float RendererEnvironmentStorage::environment_get_ssr_fade_out(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 2.0); + return env->ssr_fade_out; +} + +float RendererEnvironmentStorage::environment_get_ssr_depth_tolerance(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.2); + return env->ssr_depth_tolerance; +} + +// SSAO + +void RendererEnvironmentStorage::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->ssao_enabled = p_enable; + env->ssao_radius = p_radius; + env->ssao_intensity = p_intensity; + env->ssao_power = p_power; + env->ssao_detail = p_detail; + env->ssao_horizon = p_horizon; + env->ssao_sharpness = p_sharpness; + env->ssao_direct_light_affect = p_light_affect; + env->ssao_ao_channel_affect = p_ao_channel_affect; +} + +bool RendererEnvironmentStorage::environment_get_ssao_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->ssao_enabled; +} + +float RendererEnvironmentStorage::environment_get_ssao_radius(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->ssao_radius; +} + +float RendererEnvironmentStorage::environment_get_ssao_intensity(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 2.0); + return env->ssao_intensity; +} + +float RendererEnvironmentStorage::environment_get_ssao_power(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.5); + return env->ssao_power; +} + +float RendererEnvironmentStorage::environment_get_ssao_detail(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.5); + return env->ssao_detail; +} + +float RendererEnvironmentStorage::environment_get_ssao_horizon(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.06); + return env->ssao_horizon; +} + +float RendererEnvironmentStorage::environment_get_ssao_sharpness(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.98); + return env->ssao_sharpness; +} + +float RendererEnvironmentStorage::environment_get_ssao_direct_light_affect(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->ssao_direct_light_affect; +} + +float RendererEnvironmentStorage::environment_get_ssao_ao_channel_affect(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->ssao_ao_channel_affect; +} + +// SSIL + +void RendererEnvironmentStorage::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->ssil_enabled = p_enable; + env->ssil_radius = p_radius; + env->ssil_intensity = p_intensity; + env->ssil_sharpness = p_sharpness; + env->ssil_normal_rejection = p_normal_rejection; +} + +bool RendererEnvironmentStorage::environment_get_ssil_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->ssil_enabled; +} + +float RendererEnvironmentStorage::environment_get_ssil_radius(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 5.0); + return env->ssil_radius; +} + +float RendererEnvironmentStorage::environment_get_ssil_intensity(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->ssil_intensity; +} + +float RendererEnvironmentStorage::environment_get_ssil_sharpness(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.98); + return env->ssil_sharpness; +} + +float RendererEnvironmentStorage::environment_get_ssil_normal_rejection(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->ssil_normal_rejection; +} + +// SDFGI + +void RendererEnvironmentStorage::environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->sdfgi_enabled = p_enable; + env->sdfgi_cascades = p_cascades; + env->sdfgi_min_cell_size = p_min_cell_size; + env->sdfgi_use_occlusion = p_use_occlusion; + env->sdfgi_bounce_feedback = p_bounce_feedback; + env->sdfgi_read_sky_light = p_read_sky; + env->sdfgi_energy = p_energy; + env->sdfgi_normal_bias = p_normal_bias; + env->sdfgi_probe_bias = p_probe_bias; + env->sdfgi_y_scale = p_y_scale; +} + +bool RendererEnvironmentStorage::environment_get_sdfgi_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->sdfgi_enabled; +} + +int RendererEnvironmentStorage::environment_get_sdfgi_cascades(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 4); + return env->sdfgi_cascades; +} + +float RendererEnvironmentStorage::environment_get_sdfgi_min_cell_size(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.2); + return env->sdfgi_min_cell_size; +} + +bool RendererEnvironmentStorage::environment_get_sdfgi_use_occlusion(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->sdfgi_use_occlusion; +} + +float RendererEnvironmentStorage::environment_get_sdfgi_bounce_feedback(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.5); + return env->sdfgi_bounce_feedback; +} + +bool RendererEnvironmentStorage::environment_get_sdfgi_read_sky_light(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, true); + return env->sdfgi_read_sky_light; +} + +float RendererEnvironmentStorage::environment_get_sdfgi_energy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->sdfgi_energy; +} + +float RendererEnvironmentStorage::environment_get_sdfgi_normal_bias(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.1); + return env->sdfgi_normal_bias; +} + +float RendererEnvironmentStorage::environment_get_sdfgi_probe_bias(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.1); + return env->sdfgi_probe_bias; +} + +RS::EnvironmentSDFGIYScale RendererEnvironmentStorage::environment_get_sdfgi_y_scale(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_SDFGI_Y_SCALE_75_PERCENT); + return env->sdfgi_y_scale; +} + +// Adjustments + +void RendererEnvironmentStorage::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->adjustments_enabled = p_enable; + env->adjustments_brightness = p_brightness; + env->adjustments_contrast = p_contrast; + env->adjustments_saturation = p_saturation; + env->use_1d_color_correction = p_use_1d_color_correction; + env->color_correction = p_color_correction; +} + +bool RendererEnvironmentStorage::environment_get_adjustments_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->adjustments_enabled; +} + +float RendererEnvironmentStorage::environment_get_adjustments_brightness(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->adjustments_brightness; +} + +float RendererEnvironmentStorage::environment_get_adjustments_contrast(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->adjustments_contrast; +} + +float RendererEnvironmentStorage::environment_get_adjustments_saturation(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->adjustments_saturation; +} + +bool RendererEnvironmentStorage::environment_get_use_1d_color_correction(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->use_1d_color_correction; +} + +RID RendererEnvironmentStorage::environment_get_color_correction(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RID()); + return env->color_correction; +} diff --git a/servers/rendering/storage/environment_storage.h b/servers/rendering/storage/environment_storage.h new file mode 100644 index 0000000000..29bba86930 --- /dev/null +++ b/servers/rendering/storage/environment_storage.h @@ -0,0 +1,296 @@ +/*************************************************************************/ +/* environment_storage.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef ENVIRONMENT_STORAGE_H +#define ENVIRONMENT_STORAGE_H + +#include "core/templates/rid_owner.h" +#include "servers/rendering_server.h" + +class RendererEnvironmentStorage { +private: + struct Environment { + // Note, we capture and store all environment parameters received from Godot here. + // Not all renderers support all effects and should just ignore the bits they don't support. + + // Background + RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR; + RID sky; + float sky_custom_fov = 0.0; + Basis sky_orientation; + Color bg_color; + float bg_energy = 1.0; + int canvas_max_layer = 0; + RS::EnvironmentAmbientSource ambient_source = RS::ENV_AMBIENT_SOURCE_BG; + Color ambient_light; + float ambient_light_energy = 1.0; + float ambient_sky_contribution = 1.0; + RS::EnvironmentReflectionSource reflection_source = RS::ENV_REFLECTION_SOURCE_BG; + + // Tonemap + RS::EnvironmentToneMapper tone_mapper; + float exposure = 1.0; + float white = 1.0; + bool auto_exposure = false; + float min_luminance = 0.2; + float max_luminance = 8.0; + float auto_exp_speed = 0.2; + float auto_exp_scale = 0.5; + uint64_t auto_exposure_version = 0; + + // Fog + bool fog_enabled = false; + Color fog_light_color = Color(0.518, 0.553, 0.608); + float fog_light_energy = 1.0; + float fog_sun_scatter = 0.0; + float fog_density = 0.01; + float fog_height = 0.0; + float fog_height_density = 0.0; //can be negative to invert effect + float fog_aerial_perspective = 0.0; + + // Volumetric Fog + bool volumetric_fog_enabled = false; + float volumetric_fog_density = 0.01; + Color volumetric_fog_scattering = Color(1, 1, 1); + Color volumetric_fog_emission = Color(0, 0, 0); + float volumetric_fog_emission_energy = 0.0; + float volumetric_fog_anisotropy = 0.2; + float volumetric_fog_length = 64.0; + float volumetric_fog_detail_spread = 2.0; + float volumetric_fog_gi_inject = 1.0; + float volumetric_fog_ambient_inject = 0.0; + bool volumetric_fog_temporal_reprojection = true; + float volumetric_fog_temporal_reprojection_amount = 0.9; + + // Glow + bool glow_enabled = false; + Vector<float> glow_levels; + float glow_intensity = 0.8; + float glow_strength = 1.0; + float glow_bloom = 0.0; + float glow_mix = 0.01; + RS::EnvironmentGlowBlendMode glow_blend_mode = RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT; + float glow_hdr_bleed_threshold = 1.0; + float glow_hdr_luminance_cap = 12.0; + float glow_hdr_bleed_scale = 2.0; + float glow_map_strength = 0.0f; // 1.0f in GLES3 ?? + RID glow_map = RID(); + + // SSR + bool ssr_enabled = false; + int ssr_max_steps = 64; + float ssr_fade_in = 0.15; + float ssr_fade_out = 2.0; + float ssr_depth_tolerance = 0.2; + + // SSAO + bool ssao_enabled = false; + float ssao_radius = 1.0; + float ssao_intensity = 2.0; + float ssao_power = 1.5; + float ssao_detail = 0.5; + float ssao_horizon = 0.06; + float ssao_sharpness = 0.98; + float ssao_direct_light_affect = 0.0; + float ssao_ao_channel_affect = 0.0; + + // SSIL + bool ssil_enabled = false; + float ssil_radius = 5.0; + float ssil_intensity = 1.0; + float ssil_sharpness = 0.98; + float ssil_normal_rejection = 1.0; + + // SDFGI + bool sdfgi_enabled = false; + int sdfgi_cascades = 4; + float sdfgi_min_cell_size = 0.2; + bool sdfgi_use_occlusion = false; + float sdfgi_bounce_feedback = 0.5; + bool sdfgi_read_sky_light = true; + float sdfgi_energy = 1.0; + float sdfgi_normal_bias = 1.1; + float sdfgi_probe_bias = 1.1; + RS::EnvironmentSDFGIYScale sdfgi_y_scale = RS::ENV_SDFGI_Y_SCALE_75_PERCENT; + + // Adjustments + bool adjustments_enabled = false; + float adjustments_brightness = 1.0f; + float adjustments_contrast = 1.0f; + float adjustments_saturation = 1.0f; + bool use_1d_color_correction = false; + RID color_correction = RID(); + }; + + static uint64_t auto_exposure_counter; + + mutable RID_Owner<Environment, true> environment_owner; + +public: + RID environment_allocate(); + void environment_initialize(RID p_rid); + void environment_free(RID p_rid); + + bool is_environment(RID p_environment) const { + return environment_owner.owns(p_environment); + } + + // Background + void environment_set_background(RID p_env, RS::EnvironmentBG p_bg); + void environment_set_sky(RID p_env, RID p_sky); + void environment_set_sky_custom_fov(RID p_env, float p_scale); + void environment_set_sky_orientation(RID p_env, const Basis &p_orientation); + void environment_set_bg_color(RID p_env, const Color &p_color); + void environment_set_bg_energy(RID p_env, float p_energy); + void environment_set_canvas_max_layer(RID p_env, int p_max_layer); + void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG); +// FIXME: Disabled during Vulkan refactoring, should be ported. +#if 0 + void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id); +#endif + + RS::EnvironmentBG environment_get_background(RID p_env) const; + RID environment_get_sky(RID p_env) const; + float environment_get_sky_custom_fov(RID p_env) const; + Basis environment_get_sky_orientation(RID p_env) const; + Color environment_get_bg_color(RID p_env) const; + float environment_get_bg_energy(RID p_env) const; + int environment_get_canvas_max_layer(RID p_env) const; + RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const; + Color environment_get_ambient_light(RID p_env) const; + float environment_get_ambient_light_energy(RID p_env) const; + float environment_get_ambient_sky_contribution(RID p_env) const; + RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const; + + // Tonemap + void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); + RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const; + float environment_get_exposure(RID p_env) const; + float environment_get_white(RID p_env) const; + bool environment_get_auto_exposure(RID p_env) const; + float environment_get_min_luminance(RID p_env) const; + float environment_get_max_luminance(RID p_env) const; + float environment_get_auto_exp_speed(RID p_env) const; + float environment_get_auto_exp_scale(RID p_env) const; + uint64_t environment_get_auto_exposure_version(RID p_env) const; + + // Fog + void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective); + bool environment_get_fog_enabled(RID p_env) const; + Color environment_get_fog_light_color(RID p_env) const; + float environment_get_fog_light_energy(RID p_env) const; + float environment_get_fog_sun_scatter(RID p_env) const; + float environment_get_fog_density(RID p_env) const; + float environment_get_fog_height(RID p_env) const; + float environment_get_fog_height_density(RID p_env) const; + float environment_get_fog_aerial_perspective(RID p_env) const; + + // Volumetric Fog + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject); + bool environment_get_volumetric_fog_enabled(RID p_env) const; + float environment_get_volumetric_fog_density(RID p_env) const; + Color environment_get_volumetric_fog_scattering(RID p_env) const; + Color environment_get_volumetric_fog_emission(RID p_env) const; + float environment_get_volumetric_fog_emission_energy(RID p_env) const; + float environment_get_volumetric_fog_anisotropy(RID p_env) const; + float environment_get_volumetric_fog_length(RID p_env) const; + float environment_get_volumetric_fog_detail_spread(RID p_env) const; + float environment_get_volumetric_fog_gi_inject(RID p_env) const; + bool environment_get_volumetric_fog_temporal_reprojection(RID p_env) const; + float environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const; + float environment_get_volumetric_fog_ambient_inject(RID p_env) const; + + // GLOW + void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map); + bool environment_get_glow_enabled(RID p_env) const; + Vector<float> environment_get_glow_levels(RID p_env) const; + float environment_get_glow_intensity(RID p_env) const; + float environment_get_glow_strength(RID p_env) const; + float environment_get_glow_bloom(RID p_env) const; + float environment_get_glow_mix(RID p_env) const; + RS::EnvironmentGlowBlendMode environment_get_glow_blend_mode(RID p_env) const; + float environment_get_glow_hdr_bleed_threshold(RID p_env) const; + float environment_get_glow_hdr_luminance_cap(RID p_env) const; + float environment_get_glow_hdr_bleed_scale(RID p_env) const; + float environment_get_glow_map_strength(RID p_env) const; + RID environment_get_glow_map(RID p_env) const; + + // SSR + void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance); + bool environment_get_ssr_enabled(RID p_env) const; + int environment_get_ssr_max_steps(RID p_env) const; + float environment_get_ssr_fade_in(RID p_env) const; + float environment_get_ssr_fade_out(RID p_env) const; + float environment_get_ssr_depth_tolerance(RID p_env) const; + + // SSAO + void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect); + bool environment_get_ssao_enabled(RID p_env) const; + float environment_get_ssao_radius(RID p_env) const; + float environment_get_ssao_intensity(RID p_env) const; + float environment_get_ssao_power(RID p_env) const; + float environment_get_ssao_detail(RID p_env) const; + float environment_get_ssao_horizon(RID p_env) const; + float environment_get_ssao_sharpness(RID p_env) const; + float environment_get_ssao_direct_light_affect(RID p_env) const; + float environment_get_ssao_ao_channel_affect(RID p_env) const; + + // SSIL + void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection); + bool environment_get_ssil_enabled(RID p_env) const; + float environment_get_ssil_radius(RID p_env) const; + float environment_get_ssil_intensity(RID p_env) const; + float environment_get_ssil_sharpness(RID p_env) const; + float environment_get_ssil_normal_rejection(RID p_env) const; + + // SDFGI + void environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias); + bool environment_get_sdfgi_enabled(RID p_env) const; + int environment_get_sdfgi_cascades(RID p_env) const; + float environment_get_sdfgi_min_cell_size(RID p_env) const; + bool environment_get_sdfgi_use_occlusion(RID p_env) const; + float environment_get_sdfgi_bounce_feedback(RID p_env) const; + bool environment_get_sdfgi_read_sky_light(RID p_env) const; + float environment_get_sdfgi_energy(RID p_env) const; + float environment_get_sdfgi_normal_bias(RID p_env) const; + float environment_get_sdfgi_probe_bias(RID p_env) const; + RS::EnvironmentSDFGIYScale environment_get_sdfgi_y_scale(RID p_env) const; + + // Adjustment + void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction); + bool environment_get_adjustments_enabled(RID p_env) const; + float environment_get_adjustments_brightness(RID p_env) const; + float environment_get_adjustments_contrast(RID p_env) const; + float environment_get_adjustments_saturation(RID p_env) const; + bool environment_get_use_1d_color_correction(RID p_env) const; + RID environment_get_color_correction(RID p_env) const; +}; + +#endif // ENVIRONMENT_STORAGE_H diff --git a/servers/rendering/storage/material_storage.h b/servers/rendering/storage/material_storage.h index 3566502144..ad8e3e79bf 100644 --- a/servers/rendering/storage/material_storage.h +++ b/servers/rendering/storage/material_storage.h @@ -38,22 +38,22 @@ class RendererMaterialStorage { public: virtual ~RendererMaterialStorage(){}; - /* GLOBAL VARIABLE API */ - virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0; - virtual void global_variable_remove(const StringName &p_name) = 0; - virtual Vector<StringName> global_variable_get_list() const = 0; + /* GLOBAL SHADER UNIFORM API */ + virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) = 0; + virtual void global_shader_uniform_remove(const StringName &p_name) = 0; + virtual Vector<StringName> global_shader_uniform_get_list() const = 0; - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0; - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0; - virtual Variant global_variable_get(const StringName &p_name) const = 0; - virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0; + virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) = 0; + virtual Variant global_shader_uniform_get(const StringName &p_name) const = 0; + virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const = 0; - virtual void global_variables_load_settings(bool p_load_textures = true) = 0; - virtual void global_variables_clear() = 0; + virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) = 0; + virtual void global_shader_uniforms_clear() = 0; - virtual int32_t global_variables_instance_allocate(RID p_instance) = 0; - virtual void global_variables_instance_free(RID p_instance) = 0; - virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; + virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) = 0; + virtual void global_shader_uniforms_instance_free(RID p_instance) = 0; + virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; /* SHADER API */ virtual RID shader_allocate() = 0; @@ -63,7 +63,7 @@ public: virtual void shader_set_code(RID p_shader, const String &p_code) = 0; virtual void shader_set_path_hint(RID p_shader, const String &p_path) = 0; virtual String shader_get_code(RID p_shader) const = 0; - virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; + virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) = 0; virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const = 0; @@ -94,7 +94,7 @@ public: Variant default_value; }; - virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0; + virtual void material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) = 0; virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) = 0; }; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 73405dcbed..a54d4f0384 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -772,19 +772,11 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i elem_size = 3; } - { - elem_size *= sizeof(float); - } - - if (elem_size == 6) { - elem_size = 8; - } - + elem_size *= sizeof(float); } break; case RS::ARRAY_NORMAL: { elem_size = 4; } break; - case RS::ARRAY_TANGENT: { elem_size = 4; } break; @@ -793,12 +785,9 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i } break; case RS::ARRAY_TEX_UV: { elem_size = 8; - } break; - case RS::ARRAY_TEX_UV2: { elem_size = 8; - } break; case RS::ARRAY_CUSTOM0: case RS::ARRAY_CUSTOM1: @@ -1410,7 +1399,7 @@ Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_su } #endif -int RenderingServer::global_variable_type_get_shader_datatype(GlobalVariableType p_type) { +int RenderingServer::global_shader_uniform_type_get_shader_datatype(GlobalShaderUniformType p_type) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: return ShaderLanguage::TYPE_BOOL; @@ -1511,9 +1500,9 @@ TypedArray<Image> RenderingServer::_texture_3d_get(RID p_texture) const { return ret; } -TypedArray<Dictionary> RenderingServer::_shader_get_param_list(RID p_shader) const { +TypedArray<Dictionary> RenderingServer::_shader_get_shader_uniform_list(RID p_shader) const { List<PropertyInfo> l; - shader_get_param_list(p_shader, &l); + shader_get_shader_uniform_list(p_shader, &l); return convert_property_list(&l); } @@ -1636,9 +1625,9 @@ Dictionary RenderingServer::_mesh_get_surface(RID p_mesh, int p_idx) { return d; } -Array RenderingServer::_instance_geometry_get_shader_parameter_list(RID p_instance) const { +Array RenderingServer::_instance_geometry_get_shader_uniform_list(RID p_instance) const { List<PropertyInfo> params; - instance_geometry_get_shader_parameter_list(p_instance, ¶ms); + instance_geometry_get_shader_uniform_list(p_instance, ¶ms); return convert_property_list(¶ms); } @@ -1712,7 +1701,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("shader_set_code", "shader", "code"), &RenderingServer::shader_set_code); ClassDB::bind_method(D_METHOD("shader_set_path_hint", "shader", "path"), &RenderingServer::shader_set_path_hint); ClassDB::bind_method(D_METHOD("shader_get_code", "shader"), &RenderingServer::shader_get_code); - ClassDB::bind_method(D_METHOD("shader_get_param_list", "shader"), &RenderingServer::_shader_get_param_list); + ClassDB::bind_method(D_METHOD("shader_get_shader_uniform_list", "shader"), &RenderingServer::_shader_get_shader_uniform_list); ClassDB::bind_method(D_METHOD("shader_get_param_default", "shader", "param"), &RenderingServer::shader_get_param_default); ClassDB::bind_method(D_METHOD("shader_set_default_texture_param", "shader", "param", "texture", "index"), &RenderingServer::shader_set_default_texture_param, DEFVAL(0)); @@ -1896,9 +1885,10 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("light_projectors_set_filter", "filter"), &RenderingServer::light_projectors_set_filter); BIND_ENUM_CONSTANT(LIGHT_PROJECTOR_FILTER_NEAREST); - BIND_ENUM_CONSTANT(LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS); BIND_ENUM_CONSTANT(LIGHT_PROJECTOR_FILTER_LINEAR); + BIND_ENUM_CONSTANT(LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS); BIND_ENUM_CONSTANT(LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS); + BIND_ENUM_CONSTANT(LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS_ANISOTROPIC); BIND_ENUM_CONSTANT(LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC); BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL); @@ -1921,6 +1911,7 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_NORMAL_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_PANCAKE_SIZE); + BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_OPACITY); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BLUR); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE); BIND_ENUM_CONSTANT(LIGHT_PARAM_TRANSMITTANCE_BIAS); @@ -2000,9 +1991,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(DECAL_TEXTURE_MAX); BIND_ENUM_CONSTANT(DECAL_FILTER_NEAREST); - BIND_ENUM_CONSTANT(DECAL_FILTER_NEAREST_MIPMAPS); BIND_ENUM_CONSTANT(DECAL_FILTER_LINEAR); + BIND_ENUM_CONSTANT(DECAL_FILTER_NEAREST_MIPMAPS); BIND_ENUM_CONSTANT(DECAL_FILTER_LINEAR_MIPMAPS); + BIND_ENUM_CONSTANT(DECAL_FILTER_NEAREST_MIPMAPS_ANISOTROPIC); BIND_ENUM_CONSTANT(DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC); /* GI API (affects VoxelGI and SDFGI) */ @@ -2184,7 +2176,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("viewport_set_scaling_3d_mode", "viewport", "scaling_3d_mode"), &RenderingServer::viewport_set_scaling_3d_mode); ClassDB::bind_method(D_METHOD("viewport_set_scaling_3d_scale", "viewport", "scale"), &RenderingServer::viewport_set_scaling_3d_scale); ClassDB::bind_method(D_METHOD("viewport_set_fsr_sharpness", "viewport", "sharpness"), &RenderingServer::viewport_set_fsr_sharpness); - ClassDB::bind_method(D_METHOD("viewport_set_fsr_mipmap_bias", "viewport", "mipmap_bias"), &RenderingServer::viewport_set_fsr_mipmap_bias); + ClassDB::bind_method(D_METHOD("viewport_set_texture_mipmap_bias", "viewport", "mipmap_bias"), &RenderingServer::viewport_set_texture_mipmap_bias); ClassDB::bind_method(D_METHOD("viewport_set_update_mode", "viewport", "update_mode"), &RenderingServer::viewport_set_update_mode); ClassDB::bind_method(D_METHOD("viewport_set_clear_mode", "viewport", "clear_mode"), &RenderingServer::viewport_set_clear_mode); ClassDB::bind_method(D_METHOD("viewport_get_texture", "viewport"), &RenderingServer::viewport_get_texture); @@ -2493,10 +2485,10 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("instance_geometry_set_lightmap", "instance", "lightmap", "lightmap_uv_scale", "lightmap_slice"), &RenderingServer::instance_geometry_set_lightmap); ClassDB::bind_method(D_METHOD("instance_geometry_set_lod_bias", "instance", "lod_bias"), &RenderingServer::instance_geometry_set_lod_bias); - ClassDB::bind_method(D_METHOD("instance_geometry_set_shader_parameter", "instance", "parameter", "value"), &RenderingServer::instance_geometry_set_shader_parameter); - ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_parameter", "instance", "parameter"), &RenderingServer::instance_geometry_get_shader_parameter); - ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_parameter_default_value", "instance", "parameter"), &RenderingServer::instance_geometry_get_shader_parameter_default_value); - ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_parameter_list", "instance"), &RenderingServer::_instance_geometry_get_shader_parameter_list); + ClassDB::bind_method(D_METHOD("instance_geometry_set_shader_uniform", "instance", "parameter", "value"), &RenderingServer::instance_geometry_set_shader_uniform); + ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_uniform", "instance", "parameter"), &RenderingServer::instance_geometry_get_shader_uniform); + ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_uniform_default_value", "instance", "parameter"), &RenderingServer::instance_geometry_get_shader_uniform_default_value); + ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_uniform_list", "instance"), &RenderingServer::_instance_geometry_get_shader_uniform_list); ClassDB::bind_method(D_METHOD("instances_cull_aabb", "aabb", "scenario"), &RenderingServer::_instances_cull_aabb_bind, DEFVAL(RID())); ClassDB::bind_method(D_METHOD("instances_cull_ray", "from", "to", "scenario"), &RenderingServer::_instances_cull_ray_bind, DEFVAL(RID())); @@ -2690,15 +2682,15 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE); BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE); - /* GLOBAL VARIABLES */ + /* GLOBAL SHADER UNIFORMS */ - ClassDB::bind_method(D_METHOD("global_variable_add", "name", "type", "default_value"), &RenderingServer::global_variable_add); - ClassDB::bind_method(D_METHOD("global_variable_remove", "name"), &RenderingServer::global_variable_remove); - ClassDB::bind_method(D_METHOD("global_variable_get_list"), &RenderingServer::global_variable_get_list); - ClassDB::bind_method(D_METHOD("global_variable_set", "name", "value"), &RenderingServer::global_variable_set); - ClassDB::bind_method(D_METHOD("global_variable_set_override", "name", "value"), &RenderingServer::global_variable_set_override); - ClassDB::bind_method(D_METHOD("global_variable_get", "name"), &RenderingServer::global_variable_get); - ClassDB::bind_method(D_METHOD("global_variable_get_type", "name"), &RenderingServer::global_variable_get_type); + ClassDB::bind_method(D_METHOD("global_shader_uniform_add", "name", "type", "default_value"), &RenderingServer::global_shader_uniform_add); + ClassDB::bind_method(D_METHOD("global_shader_uniform_remove", "name"), &RenderingServer::global_shader_uniform_remove); + ClassDB::bind_method(D_METHOD("global_shader_uniform_get_list"), &RenderingServer::global_shader_uniform_get_list); + ClassDB::bind_method(D_METHOD("global_shader_uniform_set", "name", "value"), &RenderingServer::global_shader_uniform_set); + ClassDB::bind_method(D_METHOD("global_shader_uniform_set_override", "name", "value"), &RenderingServer::global_shader_uniform_set_override); + ClassDB::bind_method(D_METHOD("global_shader_uniform_get", "name"), &RenderingServer::global_shader_uniform_get); + ClassDB::bind_method(D_METHOD("global_shader_uniform_get_type", "name"), &RenderingServer::global_shader_uniform_get_type); BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BOOL); BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BVEC2); @@ -2946,7 +2938,7 @@ void RenderingServer::init() { GLOBAL_DEF("rendering/scaling_3d/mode", 0); GLOBAL_DEF("rendering/scaling_3d/scale", 1.0); GLOBAL_DEF("rendering/scaling_3d/fsr_sharpness", 0.2f); - GLOBAL_DEF("rendering/scaling_3d/fsr_mipmap_bias", 0.0f); + GLOBAL_DEF("rendering/textures/default_filters/texture_mipmap_bias", 0.0f); ProjectSettings::get_singleton()->set_custom_property_info("rendering/scaling_3d/mode", PropertyInfo(Variant::INT, "rendering/scaling_3d/mode", @@ -2961,15 +2953,15 @@ void RenderingServer::init() { PropertyInfo(Variant::FLOAT, "rendering/scaling_3d/fsr_sharpness", PROPERTY_HINT_RANGE, "0,2,0.1")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/scaling_3d/fsr_mipmap_bias", + ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/default_filters/texture_mipmap_bias", PropertyInfo(Variant::FLOAT, - "rendering/scaling_3d/fsr_mipmap_bias", - PROPERTY_HINT_RANGE, "-2,2,0.1")); + "rendering/textures/default_filters/texture_mipmap_bias", + PROPERTY_HINT_RANGE, "-2,2,0.001")); GLOBAL_DEF("rendering/textures/decals/filter", DECAL_FILTER_LINEAR_MIPMAPS); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/decals/filter", PropertyInfo(Variant::INT, "rendering/textures/decals/filter", PROPERTY_HINT_ENUM, "Nearest (Fast),Nearest+Mipmaps,Linear,Linear+Mipmaps,Linear+Mipmaps Anisotropic (Slow)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/decals/filter", PropertyInfo(Variant::INT, "rendering/textures/decals/filter", PROPERTY_HINT_ENUM, "Nearest (Fast),Linear (Fast),Nearest Mipmap (Fast),Linear Mipmap (Fast),Nearest Mipmap Anisotropic (Average),Linear Mipmap Anisotropic (Average)")); GLOBAL_DEF("rendering/textures/light_projectors/filter", LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/light_projectors/filter", PropertyInfo(Variant::INT, "rendering/textures/light_projectors/filter", PROPERTY_HINT_ENUM, "Nearest (Fast),Nearest+Mipmaps,Linear,Linear+Mipmaps,Linear+Mipmaps Anisotropic (Slow)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/light_projectors/filter", PropertyInfo(Variant::INT, "rendering/textures/light_projectors/filter", PROPERTY_HINT_ENUM, "Nearest (Fast),Linear (Fast),Nearest Mipmap (Fast),Linear Mipmap (Fast),Nearest Mipmap Anisotropic (Average),Linear Mipmap Anisotropic (Average)")); GLOBAL_DEF_RST("rendering/occlusion_culling/occlusion_rays_per_thread", 512); GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index dcb2683add..a2fe9caf19 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -170,7 +170,7 @@ public: virtual void shader_set_code(RID p_shader, const String &p_code) = 0; virtual void shader_set_path_hint(RID p_shader, const String &p_path) = 0; virtual String shader_get_code(RID p_shader) const = 0; - virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; + virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; virtual Variant shader_get_param_default(RID p_shader, const StringName &p_param) const = 0; virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index = 0) = 0; @@ -425,6 +425,7 @@ public: LIGHT_PARAM_SHADOW_NORMAL_BIAS, LIGHT_PARAM_SHADOW_BIAS, LIGHT_PARAM_SHADOW_PANCAKE_SIZE, + LIGHT_PARAM_SHADOW_OPACITY, LIGHT_PARAM_SHADOW_BLUR, LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE, LIGHT_PARAM_TRANSMITTANCE_BIAS, @@ -495,9 +496,10 @@ public: enum LightProjectorFilter { LIGHT_PROJECTOR_FILTER_NEAREST, - LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS, LIGHT_PROJECTOR_FILTER_LINEAR, + LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS, LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS, + LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS_ANISOTROPIC, LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC, }; @@ -557,9 +559,10 @@ public: enum DecalFilter { DECAL_FILTER_NEAREST, - DECAL_FILTER_NEAREST_MIPMAPS, DECAL_FILTER_LINEAR, + DECAL_FILTER_NEAREST_MIPMAPS, DECAL_FILTER_LINEAR_MIPMAPS, + DECAL_FILTER_NEAREST_MIPMAPS_ANISOTROPIC, DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC, }; @@ -797,7 +800,7 @@ public: virtual void viewport_set_scaling_3d_mode(RID p_viewport, ViewportScaling3DMode p_scaling_3d_mode) = 0; virtual void viewport_set_scaling_3d_scale(RID p_viewport, float p_scaling_3d_scale) = 0; virtual void viewport_set_fsr_sharpness(RID p_viewport, float p_fsr_sharpness) = 0; - virtual void viewport_set_fsr_mipmap_bias(RID p_viewport, float p_fsr_mipmap_bias) = 0; + virtual void viewport_set_texture_mipmap_bias(RID p_viewport, float p_texture_mipmap_bias) = 0; enum ViewportUpdateMode { VIEWPORT_UPDATE_DISABLED, @@ -1242,10 +1245,10 @@ public: virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0; virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency) = 0; - virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &, const Variant &p_value) = 0; - virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &) const = 0; - virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &) const = 0; - virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; + virtual void instance_geometry_set_shader_uniform(RID p_instance, const StringName &, const Variant &p_value) = 0; + virtual Variant instance_geometry_get_shader_uniform(RID p_instance, const StringName &) const = 0; + virtual Variant instance_geometry_get_shader_uniform_default_value(RID p_instance, const StringName &) const = 0; + virtual void instance_geometry_get_shader_uniform_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; /* Bake 3D objects */ @@ -1425,9 +1428,9 @@ public: virtual void canvas_set_shadow_texture_size(int p_size) = 0; - /* GLOBAL VARIABLES */ + /* GLOBAL SHADER UNIFORMS */ - enum GlobalVariableType { + enum GlobalShaderUniformType { GLOBAL_VAR_TYPE_BOOL, GLOBAL_VAR_TYPE_BVEC2, GLOBAL_VAR_TYPE_BVEC3, @@ -1459,20 +1462,20 @@ public: GLOBAL_VAR_TYPE_MAX }; - virtual void global_variable_add(const StringName &p_name, GlobalVariableType p_type, const Variant &p_value) = 0; - virtual void global_variable_remove(const StringName &p_name) = 0; - virtual Vector<StringName> global_variable_get_list() const = 0; + virtual void global_shader_uniform_add(const StringName &p_name, GlobalShaderUniformType p_type, const Variant &p_value) = 0; + virtual void global_shader_uniform_remove(const StringName &p_name) = 0; + virtual Vector<StringName> global_shader_uniform_get_list() const = 0; - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0; - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) = 0; - virtual Variant global_variable_get(const StringName &p_name) const = 0; - virtual GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0; + virtual Variant global_shader_uniform_get(const StringName &p_name) const = 0; + virtual GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const = 0; - virtual void global_variables_load_settings(bool p_load_textures) = 0; - virtual void global_variables_clear() = 0; + virtual void global_shader_uniforms_load_settings(bool p_load_textures) = 0; + virtual void global_shader_uniforms_clear() = 0; - static int global_variable_type_get_shader_datatype(GlobalVariableType p_type); + static int global_shader_uniform_type_get_shader_datatype(GlobalShaderUniformType p_type); /* FREE */ @@ -1569,11 +1572,11 @@ private: RID _texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data); void _texture_3d_update(RID p_texture, const TypedArray<Image> &p_data); TypedArray<Image> _texture_3d_get(RID p_texture) const; - TypedArray<Dictionary> _shader_get_param_list(RID p_shader) const; + TypedArray<Dictionary> _shader_get_shader_uniform_list(RID p_shader) const; RID _mesh_create_from_surfaces(const TypedArray<Dictionary> &p_surfaces, int p_blend_shape_count); void _mesh_add_surface(RID p_mesh, const Dictionary &p_surface); Dictionary _mesh_get_surface(RID p_mesh, int p_idx); - Array _instance_geometry_get_shader_parameter_list(RID p_instance) const; + Array _instance_geometry_get_shader_uniform_list(RID p_instance) const; TypedArray<Image> _bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size); void _particles_set_trail_bind_poses(RID p_particles, const TypedArray<Transform3D> &p_bind_poses); }; @@ -1648,7 +1651,7 @@ VARIANT_ENUM_CAST(RenderingServer::CanvasLightMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightBlendMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightShadowFilter); VARIANT_ENUM_CAST(RenderingServer::CanvasOccluderPolygonCullMode); -VARIANT_ENUM_CAST(RenderingServer::GlobalVariableType); +VARIANT_ENUM_CAST(RenderingServer::GlobalShaderUniformType); VARIANT_ENUM_CAST(RenderingServer::RenderingInfo); VARIANT_ENUM_CAST(RenderingServer::Features); VARIANT_ENUM_CAST(RenderingServer::CanvasTextureChannel); diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index 47598abce7..59310ab69b 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -297,9 +297,13 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(percent_sign, "language"); GDVIRTUAL_BIND(strip_diacritics, "string"); + GDVIRTUAL_BIND(is_valid_identifier, "string"); GDVIRTUAL_BIND(string_get_word_breaks, "string", "language"); + GDVIRTUAL_BIND(is_confusable, "string", "dict"); + GDVIRTUAL_BIND(spoof_check, "string"); + GDVIRTUAL_BIND(string_to_upper, "string", "language"); GDVIRTUAL_BIND(string_to_lower, "string", "language"); @@ -1498,6 +1502,14 @@ String TextServerExtension::percent_sign(const String &p_language) const { return "%"; } +bool TextServerExtension::is_valid_identifier(const String &p_string) const { + bool ret; + if (GDVIRTUAL_CALL(is_valid_identifier, p_string, ret)) { + return ret; + } + return TextServer::is_valid_identifier(p_string); +} + String TextServerExtension::strip_diacritics(const String &p_string) const { String ret; if (GDVIRTUAL_CALL(strip_diacritics, p_string, ret)) { @@ -1538,6 +1550,22 @@ PackedInt32Array TextServerExtension::string_get_word_breaks(const String &p_str return PackedInt32Array(); } +int TextServerExtension::is_confusable(const String &p_string, const PackedStringArray &p_dict) const { + int ret; + if (GDVIRTUAL_CALL(is_confusable, p_string, p_dict, ret)) { + return ret; + } + return TextServer::is_confusable(p_string, p_dict); +} + +bool TextServerExtension::spoof_check(const String &p_string) const { + bool ret; + if (GDVIRTUAL_CALL(spoof_check, p_string, ret)) { + return ret; + } + return TextServer::spoof_check(p_string); +} + TextServerExtension::TextServerExtension() { //NOP } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 571753ea67..81af1b60e5 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -496,6 +496,9 @@ public: virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const override; GDVIRTUAL2RC(PackedInt32Array, string_get_word_breaks, const String &, const String &); + virtual bool is_valid_identifier(const String &p_string) const override; + GDVIRTUAL1RC(bool, is_valid_identifier, const String &); + virtual String string_to_upper(const String &p_string, const String &p_language = "") const override; virtual String string_to_lower(const String &p_string, const String &p_language = "") const override; GDVIRTUAL2RC(String, string_to_upper, const String &, const String &); @@ -504,6 +507,11 @@ public: Array parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; GDVIRTUAL3RC(Array, parse_structured_text, StructuredTextParser, const Array &, const String &); + virtual int is_confusable(const String &p_string, const PackedStringArray &p_dict) const override; + virtual bool spoof_check(const String &p_string) const override; + GDVIRTUAL2RC(int, is_confusable, const String &, const PackedStringArray &); + GDVIRTUAL1RC(bool, spoof_check, const String &); + TextServerExtension(); ~TextServerExtension(); }; diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 4a6b03d943..2bf0837d88 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -446,7 +446,11 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("string_get_word_breaks", "string", "language"), &TextServer::string_get_word_breaks, DEFVAL("")); + ClassDB::bind_method(D_METHOD("is_confusable", "string", "dict"), &TextServer::is_confusable); + ClassDB::bind_method(D_METHOD("spoof_check", "string"), &TextServer::spoof_check); + ClassDB::bind_method(D_METHOD("strip_diacritics", "string"), &TextServer::strip_diacritics); + ClassDB::bind_method(D_METHOD("is_valid_identifier", "string"), &TextServer::is_valid_identifier); ClassDB::bind_method(D_METHOD("string_to_upper", "string", "language"), &TextServer::string_to_upper, DEFVAL("")); ClassDB::bind_method(D_METHOD("string_to_lower", "string", "language"), &TextServer::string_to_lower, DEFVAL("")); @@ -517,6 +521,7 @@ void TextServer::_bind_methods() { BIND_BITFIELD_FLAG(GRAPHEME_IS_PUNCTUATION); BIND_BITFIELD_FLAG(GRAPHEME_IS_UNDERSCORE); BIND_BITFIELD_FLAG(GRAPHEME_IS_CONNECTED); + BIND_BITFIELD_FLAG(GRAPHEME_IS_SAFE_TO_INSERT_TATWEEL); /* Hinting */ BIND_ENUM_CONSTANT(HINTING_NONE); @@ -545,6 +550,8 @@ void TextServer::_bind_methods() { BIND_ENUM_CONSTANT(FEATURE_FONT_VARIABLE); BIND_ENUM_CONSTANT(FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION); BIND_ENUM_CONSTANT(FEATURE_USE_SUPPORT_DATA); + BIND_ENUM_CONSTANT(FEATURE_UNICODE_IDENTIFIERS); + BIND_ENUM_CONSTANT(FEATURE_UNICODE_SECURITY); /* FT Contour Point Types */ BIND_ENUM_CONSTANT(CONTOUR_CURVE_TAG_ON); @@ -1730,6 +1737,26 @@ Array TextServer::_shaped_text_get_ellipsis_glyphs_wrapper(const RID &p_shaped) return ret; } +bool TextServer::is_valid_identifier(const String &p_string) const { + const char32_t *str = p_string.ptr(); + int len = p_string.length(); + + if (len == 0) { + return false; // Empty string. + } + + if (!is_unicode_identifier_start(str[0])) { + return false; + } + + for (int i = 1; i < len; i++) { + if (!is_unicode_identifier_continue(str[i])) { + return false; + } + } + return true; +} + TextServer::TextServer() { _init_diacritics_map(); } diff --git a/servers/text_server.h b/servers/text_server.h index f6ab165bfc..d45bea3271 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -116,6 +116,7 @@ public: GRAPHEME_IS_PUNCTUATION = 1 << 8, // Punctuation, except underscore (can be used as word break, but not line break or justifiction). GRAPHEME_IS_UNDERSCORE = 1 << 9, // Underscore (can be used as word break). GRAPHEME_IS_CONNECTED = 1 << 10, // Connected to previous grapheme. + GRAPHEME_IS_SAFE_TO_INSERT_TATWEEL = 1 << 11, // It is safe to insert a U+0640 before this grapheme for elongation. }; enum Hinting { @@ -148,6 +149,8 @@ public: FEATURE_FONT_VARIABLE = 1 << 10, FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION = 1 << 11, FEATURE_USE_SUPPORT_DATA = 1 << 12, + FEATURE_UNICODE_IDENTIFIERS = 1 << 13, + FEATURE_UNICODE_SECURITY = 1 << 14, }; enum ContourPointTag { @@ -463,7 +466,11 @@ public: // String functions. virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const = 0; + virtual int is_confusable(const String &p_string, const PackedStringArray &p_dict) const { return -1; }; + virtual bool spoof_check(const String &p_string) const { return false; }; + virtual String strip_diacritics(const String &p_string) const; + virtual bool is_valid_identifier(const String &p_string) const; // Other string operations. virtual String string_to_upper(const String &p_string, const String &p_language = "") const = 0; diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp index ad61aa94bc..990281d96d 100644 --- a/servers/xr_server.cpp +++ b/servers/xr_server.cpp @@ -33,6 +33,16 @@ #include "xr/xr_interface.h" #include "xr/xr_positional_tracker.h" +XRServer::XRMode XRServer::xr_mode = XRMODE_DEFAULT; + +XRServer::XRMode XRServer::get_xr_mode() { + return xr_mode; +} + +void XRServer::set_xr_mode(XRServer::XRMode p_mode) { + xr_mode = p_mode; +} + XRServer *XRServer::singleton = nullptr; XRServer *XRServer::get_singleton() { diff --git a/servers/xr_server.h b/servers/xr_server.h index d9188d2de1..74128bfb54 100644 --- a/servers/xr_server.h +++ b/servers/xr_server.h @@ -57,6 +57,12 @@ class XRServer : public Object { _THREAD_SAFE_CLASS_ public: + enum XRMode { + XRMODE_DEFAULT, /* Default behaviour, means we check project settings */ + XRMODE_OFF, /* Ignore project settings, disable OpenXR, disable shaders */ + XRMODE_ON, /* Ignore project settings, enable OpenXR, enable shaders, run editor in VR (if applicable) */ + }; + enum TrackerType { TRACKER_HEAD = 0x01, /* tracks the position of the players head (or in case of handheld AR, location of the phone) */ TRACKER_CONTROLLER = 0x02, /* tracks a controller */ @@ -75,6 +81,8 @@ public: }; private: + static XRMode xr_mode; + Vector<Ref<XRInterface>> interfaces; Dictionary trackers; @@ -90,6 +98,9 @@ protected: static void _bind_methods(); public: + static XRMode get_xr_mode(); + static void set_xr_mode(XRMode p_mode); + static XRServer *get_singleton(); /* diff --git a/tests/core/input/test_input_event_key.h b/tests/core/input/test_input_event_key.h new file mode 100644 index 0000000000..5d4ca55a35 --- /dev/null +++ b/tests/core/input/test_input_event_key.h @@ -0,0 +1,294 @@ +/*************************************************************************/ +/* test_input_event_key.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_INPUT_EVENT_KEY_H +#define TEST_INPUT_EVENT_KEY_H + +#include "core/input/input_event.h" +#include "core/os/keyboard.h" + +#include "tests/test_macros.h" + +namespace TestInputEventKey { + +TEST_CASE("[InputEventKey] Key correctly registers being pressed") { + InputEventKey key; + key.set_pressed(true); + CHECK(key.is_pressed() == true); + + key.set_pressed(false); + CHECK(key.is_pressed() == false); +} + +TEST_CASE("[InputEventKey] Key correctly stores and retrieves keycode") { + InputEventKey key; + + key.set_keycode(Key::ENTER); + CHECK(key.get_keycode() == Key::ENTER); + CHECK(key.get_keycode() != Key::PAUSE); + + key.set_physical_keycode(Key::BACKSPACE); + CHECK(key.get_physical_keycode() == Key::BACKSPACE); + CHECK(key.get_physical_keycode() != Key::PAUSE); +} + +TEST_CASE("[InputEventKey] Key correctly stores and retrieves keycode with modifiers") { + InputEventKey key; + + key.set_keycode(Key::ENTER); + key.set_ctrl_pressed(true); + + CHECK(key.get_keycode_with_modifiers() == (Key::ENTER | KeyModifierMask::CTRL)); + CHECK(key.get_keycode_with_modifiers() != (Key::ENTER | KeyModifierMask::SHIFT)); + CHECK(key.get_keycode_with_modifiers() != Key::ENTER); + + key.set_physical_keycode(Key::SPACE); + key.set_ctrl_pressed(true); + + CHECK(key.get_physical_keycode_with_modifiers() == (Key::SPACE | KeyModifierMask::CTRL)); + CHECK(key.get_physical_keycode_with_modifiers() != (Key::SPACE | KeyModifierMask::SHIFT)); + CHECK(key.get_physical_keycode_with_modifiers() != Key::SPACE); +} + +TEST_CASE("[InputEventKey] Key correctly stores and retrieves unicode") { + InputEventKey key; + + key.set_unicode('x'); + CHECK(key.get_unicode() == 'x'); + CHECK(key.get_unicode() != 'y'); +} + +TEST_CASE("[InputEventKey] Key correctly stores and checks echo") { + InputEventKey key; + + key.set_echo(true); + CHECK(key.is_echo() == true); + + key.set_echo(false); + CHECK(key.is_echo() == false); +} + +TEST_CASE("[InputEventKey] Key correctly converts itself to text") { + InputEventKey none_key; + + // These next three tests test the functionality of getting a key that is set to None + // as text. These cases are a bit weird, since None has no textual representation + // (find_keycode_name(Key::NONE) results in a nullptr). Thus, these tests look weird + // with only (Physical) or a lonely modifier with (Physical) but (as far as I + // understand the code, that is intended behaviour. + + // Key is None without a physical key. + none_key.set_keycode(Key::NONE); + CHECK(none_key.as_text() == " (Physical)"); + + // Key is none and has modifiers. + none_key.set_ctrl_pressed(true); + CHECK(none_key.as_text() == "Ctrl+ (Physical)"); + + // Key is None WITH a physical key AND modifiers. + none_key.set_physical_keycode(Key::ENTER); + CHECK(none_key.as_text() == "Ctrl+Enter (Physical)"); + + InputEventKey none_key2; + + // Key is None without modifers with a physical key. + none_key2.set_keycode(Key::NONE); + none_key2.set_physical_keycode(Key::ENTER); + + CHECK(none_key2.as_text() == "Enter (Physical)"); + + InputEventKey key; + + // Key has keycode. + key.set_keycode(Key::SPACE); + CHECK(key.as_text() != ""); + CHECK(key.as_text() == "Space"); + + // Key has keycode and modifiers. + key.set_ctrl_pressed(true); + CHECK(key.as_text() != "Space"); + CHECK(key.as_text() == "Ctrl+Space"); + + // Since the keycode is set to Key::NONE upon initialization of the + // InputEventKey and you can only update it with another Key, the keycode + // cannot be empty, so the kc.is_empty() case cannot be tested. +} + +TEST_CASE("[InputEventKey] Key correctly converts its state to a string representation") { + InputEventKey none_key; + + // Set physical to true. + CHECK(none_key.to_string() == "InputEventKey: keycode=0 (), mods=none, physical=true, pressed=false, echo=false"); + // Set physical key to Escape. + none_key.set_physical_keycode(Key::ESCAPE); + CHECK(none_key.to_string() == "InputEventKey: keycode=16777217 (Escape), mods=none, physical=true, pressed=false, echo=false"); + + InputEventKey key; + + // Set physical to None, set keycode to Space. + key.set_keycode(Key::SPACE); + CHECK(key.to_string() == "InputEventKey: keycode=32 (Space), mods=none, physical=false, pressed=false, echo=false"); + + // Set pressed to true. + key.set_pressed(true); + CHECK(key.to_string() == "InputEventKey: keycode=32 (Space), mods=none, physical=false, pressed=true, echo=false"); + + // set echo to true. + key.set_echo(true); + CHECK(key.to_string() == "InputEventKey: keycode=32 (Space), mods=none, physical=false, pressed=true, echo=true"); + + // Press Ctrl and Alt. + key.set_ctrl_pressed(true); + key.set_alt_pressed(true); + CHECK(key.to_string() == "InputEventKey: keycode=32 (Space), mods=Ctrl+Alt, physical=false, pressed=true, echo=true"); +} + +TEST_CASE("[InputEventKey] Key is correctly converted to reference") { + InputEventKey base_key; + Ref<InputEventKey> key_ref = base_key.create_reference(Key::ENTER); + + CHECK(key_ref->get_keycode() == Key::ENTER); +} + +TEST_CASE("[InputEventKey] Keys are correctly matched based on action") { + bool pressed = false; + float strength, raw_strength = 0.0; + + InputEventKey key; + + // Nullptr. + CHECK_MESSAGE(key.action_match(nullptr, false, 0.0f, &pressed, &strength, &raw_strength) == false, "nullptr as key reference should result in false"); + + // Match on keycode. + key.set_keycode(Key::SPACE); + Ref<InputEventKey> match = key.create_reference(Key::SPACE); + Ref<InputEventKey> no_match = key.create_reference(Key::ENTER); + + CHECK(key.action_match(match, false, 0.0f, &pressed, &strength, &raw_strength) == true); + CHECK(key.action_match(no_match, false, 0.0f, &pressed, &strength, &raw_strength) == false); + + // Check that values are correctly transferred to the pointers. + CHECK(pressed == false); + CHECK(strength < 0.5); + CHECK(raw_strength < 0.5); + + match->set_pressed(true); + key.action_match(match, false, 0.0f, &pressed, &strength, &raw_strength); + + CHECK(pressed == true); + CHECK(strength > 0.5); + CHECK(raw_strength > 0.5); + + // Tests when keycode is None: Then you rely on physical keycode. + InputEventKey none_key; + none_key.set_physical_keycode(Key::SPACE); + + Ref<InputEventKey> match_none = none_key.create_reference(Key::NONE); + match_none->set_physical_keycode(Key::SPACE); + + Ref<InputEventKey> no_match_none = none_key.create_reference(Key::NONE); + no_match_none->set_physical_keycode(Key::ENTER); + + CHECK(none_key.action_match(match_none, false, 0.0f, &pressed, &strength, &raw_strength) == true); + CHECK(none_key.action_match(no_match_none, false, 0.0f, &pressed, &strength, &raw_strength) == false); + + // Test exact match. + InputEventKey key2, ref_key; + key2.set_keycode(Key::SPACE); + + Ref<InputEventKey> match2 = ref_key.create_reference(Key::SPACE); + + // Now both press Ctrl and Shift. + key2.set_ctrl_pressed(true); + key2.set_shift_pressed(true); + + match2->set_ctrl_pressed(true); + match2->set_shift_pressed(true); + + // Now they should match. + bool exact_match = true; + CHECK(key2.action_match(match2, exact_match, 0.0f, &pressed, &strength, &raw_strength) == true); + + // Modify matching key such that it does no longer match in terms of modifiers: Shift + // is no longer pressed. + match2->set_shift_pressed(false); + CHECK(match2->is_shift_pressed() == false); + CHECK(key2.action_match(match2, exact_match, 0.0f, &pressed, &strength, &raw_strength) == false); +} + +TEST_CASE("[IsMatch] Keys are correctly matched") { + // Key with NONE as keycode. + InputEventKey key; + key.set_keycode(Key::NONE); + key.set_physical_keycode(Key::SPACE); + + // Nullptr. + CHECK(key.is_match(nullptr, false) == false); + + Ref<InputEventKey> none_ref = key.create_reference(Key::NONE); + + none_ref->set_physical_keycode(Key::SPACE); + CHECK(key.is_match(none_ref, false) == true); + + none_ref->set_physical_keycode(Key::ENTER); + CHECK(key.is_match(none_ref, false) == false); + + none_ref->set_physical_keycode(Key::SPACE); + + key.set_ctrl_pressed(true); + none_ref->set_ctrl_pressed(false); + CHECK(key.is_match(none_ref, true) == false); + + none_ref->set_ctrl_pressed(true); + CHECK(key.is_match(none_ref, true) == true); + + // Ref with actual keycode. + InputEventKey key2; + key2.set_keycode(Key::SPACE); + + Ref<InputEventKey> match = key2.create_reference(Key::SPACE); + Ref<InputEventKey> no_match = key2.create_reference(Key::ENTER); + + CHECK(key2.is_match(match, false) == true); + CHECK(key2.is_match(no_match, false) == false); + + // Now the keycode is the same, but the modifiers differ. + no_match->set_keycode(Key::SPACE); + + key2.set_ctrl_pressed(true); + match->set_ctrl_pressed(true); + no_match->set_shift_pressed(true); + + CHECK(key2.is_match(match, true) == true); + CHECK(key2.is_match(no_match, true) == false); +} +} // namespace TestInputEventKey + +#endif // TEST_INPUT_EVENT_KEY_H diff --git a/tests/core/input/test_shortcut.h b/tests/core/input/test_shortcut.h new file mode 100644 index 0000000000..93edc685ad --- /dev/null +++ b/tests/core/input/test_shortcut.h @@ -0,0 +1,235 @@ +/*************************************************************************/ +/* test_shortcut.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_SHORTCUT_H +#define TEST_SHORTCUT_H + +#include "core/input/input_event.h" +#include "core/input/shortcut.h" +#include "core/io/config_file.h" +#include "core/object/ref_counted.h" +#include "core/os/keyboard.h" +#include "core/os/os.h" + +#include "tests/test_macros.h" + +namespace TestShortcut { + +TEST_CASE("[Shortcut] Empty shortcut should have no valid events and text equal to None") { + Shortcut s; + + CHECK(s.get_as_text() == "None"); + CHECK(s.has_valid_event() == false); +} + +TEST_CASE("[Shortcut] Setting and getting an event should result in the same event as the input") { + Ref<InputEventKey> k1; + Ref<InputEventKey> k2; + k1.instantiate(); + k2.instantiate(); + + k1->set_keycode(Key::ENTER); + k2->set_keycode(Key::BACKSPACE); + + // Cast to InputEvent so the internal code recognizes the objects. + Ref<InputEvent> e1 = k1; + Ref<InputEvent> e2 = k2; + + Array input_array; + input_array.append(e1); + input_array.append(e2); + + Shortcut s; + s.set_events(input_array); + + // Get result, read it out, check whether it equals the input. + Array result_array = s.get_events(); + Ref<InputEventKey> result1 = result_array.front(); + Ref<InputEventKey> result2 = result_array.back(); + + CHECK(result1->get_keycode() == k1->get_keycode()); + CHECK(result2->get_keycode() == k2->get_keycode()); +} + +TEST_CASE("[Shortcut] 'set_events_list' should result in the same events as the input") { + Ref<InputEventKey> k1; + Ref<InputEventKey> k2; + k1.instantiate(); + k2.instantiate(); + + k1->set_keycode(Key::ENTER); + k2->set_keycode(Key::BACKSPACE); + + // Cast to InputEvent so the set_events_list() method recognizes the objects. + Ref<InputEvent> e1 = k1; + Ref<InputEvent> e2 = k2; + + List<Ref<InputEvent>> list; + list.push_back(e1); + list.push_back(e2); + + Shortcut s; + s.set_events_list(&list); + + // Get result, read it out, check whether it equals the input. + Array result_array = s.get_events(); + Ref<InputEventKey> result1 = result_array.front(); + Ref<InputEventKey> result2 = result_array.back(); + + CHECK(result1->get_keycode() == k1->get_keycode()); + CHECK(result2->get_keycode() == k2->get_keycode()); +} + +TEST_CASE("[Shortcut] 'matches_event' should correctly match the same event") { + Ref<InputEventKey> original; // The one we compare with. + Ref<InputEventKey> similar_but_not_equal; // Same keycode, different event. + Ref<InputEventKey> different; // Different event, different keycode. + Ref<InputEventKey> copy; // Copy of original event. + + original.instantiate(); + similar_but_not_equal.instantiate(); + different.instantiate(); + copy.instantiate(); + + original->set_keycode(Key::ENTER); + similar_but_not_equal->set_keycode(Key::ENTER); + similar_but_not_equal->set_keycode(Key::ESCAPE); + copy = original; + + // Only the copy is really the same, so only that one should match. + // The rest should not match. + + Ref<InputEvent> e_original = original; + + Ref<InputEvent> e_similar_but_not_equal = similar_but_not_equal; + Ref<InputEvent> e_different = different; + Ref<InputEvent> e_copy = copy; + + Array a; + a.append(e_original); + Shortcut s; + s.set_events(a); + + CHECK(s.matches_event(e_similar_but_not_equal) == false); + CHECK(s.matches_event(e_different) == false); + + CHECK(s.matches_event(e_copy) == true); +} + +TEST_CASE("[Shortcut] 'get_as_text' text representation should be correct") { + Ref<InputEventKey> same; + // k2 will not go into the shortcut but only be used to compare. + Ref<InputEventKey> different; + + same.instantiate(); + different.instantiate(); + + same->set_keycode(Key::ENTER); + different->set_keycode(Key::ESCAPE); + + Ref<InputEvent> key_event1 = same; + + Array a; + a.append(key_event1); + Shortcut s; + s.set_events(a); + + CHECK(s.get_as_text() == same->as_text()); + CHECK(s.get_as_text() != different->as_text()); +} + +TEST_CASE("[Shortcut] Event validity should be correctly checked.") { + Ref<InputEventKey> valid; + // k2 will not go into the shortcut but only be used to compare. + Ref<InputEventKey> invalid = nullptr; + + valid.instantiate(); + valid->set_keycode(Key::ENTER); + + Ref<InputEvent> valid_event = valid; + Ref<InputEvent> invalid_event = invalid; + + Array a; + a.append(invalid_event); + a.append(valid_event); + + Shortcut s; + s.set_events(a); + + CHECK(s.has_valid_event() == true); + + Array b; + b.append(invalid_event); + + Shortcut shortcut_with_invalid_event; + shortcut_with_invalid_event.set_events(b); + + CHECK(shortcut_with_invalid_event.has_valid_event() == false); +} + +TEST_CASE("[Shortcut] Equal arrays should be recognized as such.") { + Ref<InputEventKey> k1; + // k2 will not go into the shortcut but only be used to compare. + Ref<InputEventKey> k2; + + k1.instantiate(); + k2.instantiate(); + + k1->set_keycode(Key::ENTER); + k2->set_keycode(Key::ESCAPE); + + Ref<InputEvent> key_event1 = k1; + Ref<InputEvent> key_event2 = k2; + + Array same; + same.append(key_event1); + + Array same_as_same; + same_as_same.append(key_event1); + + Array different1; + different1.append(key_event2); + + Array different2; + different2.append(key_event1); + different2.append(key_event2); + + Array different3; + + Shortcut s; + + CHECK(s.is_event_array_equal(same, same_as_same) == true); + CHECK(s.is_event_array_equal(same, different1) == false); + CHECK(s.is_event_array_equal(same, different2) == false); + CHECK(s.is_event_array_equal(same, different3) == false); +} +} // namespace TestShortcut + +#endif // TEST_SHORTCUT_H diff --git a/tests/core/io/test_file_access.h b/tests/core/io/test_file_access.h index f0e1cceacf..aab62955cb 100644 --- a/tests/core/io/test_file_access.h +++ b/tests/core/io/test_file_access.h @@ -78,6 +78,29 @@ TEST_CASE("[FileAccess] CSV read") { CHECK(row5[1] == "tab separated"); CHECK(row5[2] == "lines, good?"); } + +TEST_CASE("[FileAccess] Get as UTF-8 String") { + Ref<FileAccess> f_lf = FileAccess::open(TestUtils::get_data_path("line_endings_lf.test.txt"), FileAccess::READ); + String s_lf = f_lf->get_as_utf8_string(); + f_lf->seek(0); + String s_lf_nocr = f_lf->get_as_utf8_string(true); + CHECK(s_lf == "Hello darkness\nMy old friend\nI've come to talk\nWith you again\n"); + CHECK(s_lf_nocr == "Hello darkness\nMy old friend\nI've come to talk\nWith you again\n"); + + Ref<FileAccess> f_crlf = FileAccess::open(TestUtils::get_data_path("line_endings_crlf.test.txt"), FileAccess::READ); + String s_crlf = f_crlf->get_as_utf8_string(); + f_crlf->seek(0); + String s_crlf_nocr = f_crlf->get_as_utf8_string(true); + CHECK(s_crlf == "Hello darkness\r\nMy old friend\r\nI've come to talk\r\nWith you again\r\n"); + CHECK(s_crlf_nocr == "Hello darkness\nMy old friend\nI've come to talk\nWith you again\n"); + + Ref<FileAccess> f_cr = FileAccess::open(TestUtils::get_data_path("line_endings_cr.test.txt"), FileAccess::READ); + String s_cr = f_cr->get_as_utf8_string(); + f_cr->seek(0); + String s_cr_nocr = f_cr->get_as_utf8_string(true); + CHECK(s_cr == "Hello darkness\rMy old friend\rI've come to talk\rWith you again\r"); + CHECK(s_cr_nocr == "Hello darknessMy old friendI've come to talkWith you again"); +} } // namespace TestFileAccess #endif // TEST_FILE_ACCESS_H diff --git a/tests/core/io/test_marshalls.h b/tests/core/io/test_marshalls.h index 546a2e9358..7490df2b2c 100644 --- a/tests/core/io/test_marshalls.h +++ b/tests/core/io/test_marshalls.h @@ -254,11 +254,13 @@ TEST_CASE("[Marshalls] Invalid data Variant decoding") { uint8_t some_buffer[1] = { 0x00 }; uint8_t out_of_range_type_buffer[4] = { 0xff }; // Greater than Variant::VARIANT_MAX + ERR_PRINT_OFF; CHECK(decode_variant(variant, some_buffer, /* less than 4 */ 1, &r_len) == ERR_INVALID_DATA); CHECK(r_len == 0); CHECK(decode_variant(variant, out_of_range_type_buffer, 4, &r_len) == ERR_INVALID_DATA); CHECK(r_len == 0); + ERR_PRINT_ON; } TEST_CASE("[Marshalls] NIL Variant decoding") { diff --git a/tests/core/io/test_resource.h b/tests/core/io/test_resource.h index f94349fdd2..c880ca7d2a 100644 --- a/tests/core/io/test_resource.h +++ b/tests/core/io/test_resource.h @@ -76,8 +76,8 @@ TEST_CASE("[Resource] Saving and loading") { resource->set_meta("other_resource", child_resource); const String save_path_binary = OS::get_singleton()->get_cache_path().plus_file("resource.res"); const String save_path_text = OS::get_singleton()->get_cache_path().plus_file("resource.tres"); - ResourceSaver::save(save_path_binary, resource); - ResourceSaver::save(save_path_text, resource); + ResourceSaver::save(resource, save_path_binary); + ResourceSaver::save(resource, save_path_text); const Ref<Resource> &loaded_resource_binary = ResourceLoader::load(save_path_binary); CHECK_MESSAGE( diff --git a/tests/core/math/test_aabb.h b/tests/core/math/test_aabb.h index 526972a82f..447420fc12 100644 --- a/tests/core/math/test_aabb.h +++ b/tests/core/math/test_aabb.h @@ -299,34 +299,28 @@ TEST_CASE("[AABB] Get longest/shortest axis") { "get_shortest_axis_size() should return the expected value."); } -#ifndef _MSC_VER -#warning Support tests need to be re-done -#endif - -/* Support function was actually broken. As it was fixed, the tests now fail. Tests need to be re-done. - TEST_CASE("[AABB] Get support") { const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6)); CHECK_MESSAGE( - aabb.get_support(Vector3(1, 0, 0)).is_equal_approx(Vector3(-1.5, 7, 3.5)), + aabb.get_support(Vector3(1, 0, 0)).is_equal_approx(Vector3(2.5, 2, -2.5)), "get_support() should return the expected value."); CHECK_MESSAGE( - aabb.get_support(Vector3(0.5, 1, 0)).is_equal_approx(Vector3(-1.5, 2, 3.5)), + aabb.get_support(Vector3(0.5, 1, 0)).is_equal_approx(Vector3(2.5, 7, -2.5)), "get_support() should return the expected value."); CHECK_MESSAGE( - aabb.get_support(Vector3(0.5, 1, -400)).is_equal_approx(Vector3(-1.5, 2, 3.5)), + aabb.get_support(Vector3(0.5, 1, -400)).is_equal_approx(Vector3(2.5, 7, -2.5)), "get_support() should return the expected value."); CHECK_MESSAGE( - aabb.get_support(Vector3(0, -1, 0)).is_equal_approx(Vector3(2.5, 7, 3.5)), + aabb.get_support(Vector3(0, -1, 0)).is_equal_approx(Vector3(-1.5, 2, -2.5)), "get_support() should return the expected value."); CHECK_MESSAGE( - aabb.get_support(Vector3(0, -0.1, 0)).is_equal_approx(Vector3(2.5, 7, 3.5)), + aabb.get_support(Vector3(0, -0.1, 0)).is_equal_approx(Vector3(-1.5, 2, -2.5)), "get_support() should return the expected value."); CHECK_MESSAGE( - aabb.get_support(Vector3()).is_equal_approx(Vector3(2.5, 7, 3.5)), + aabb.get_support(Vector3()).is_equal_approx(Vector3(-1.5, 2, -2.5)), "get_support() should return the expected value with a null vector."); } -*/ + TEST_CASE("[AABB] Grow") { const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6)); CHECK_MESSAGE( diff --git a/tests/core/math/test_quaternion.h b/tests/core/math/test_quaternion.h new file mode 100644 index 0000000000..94eef6c463 --- /dev/null +++ b/tests/core/math/test_quaternion.h @@ -0,0 +1,389 @@ +/*************************************************************************/ +/* test_quaternion.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_QUATERNION_H +#define TEST_QUATERNION_H + +#include "core/math/math_defs.h" +#include "core/math/math_funcs.h" +#include "core/math/quaternion.h" +#include "core/math/vector3.h" + +#include "tests/test_macros.h" + +namespace TestQuaternion { + +Quaternion quat_euler_yxz_deg(Vector3 angle) { + double yaw = Math::deg2rad(angle[1]); + double pitch = Math::deg2rad(angle[0]); + double roll = Math::deg2rad(angle[2]); + + // Generate YXZ (Z-then-X-then-Y) Quaternion using single-axis Euler + // constructor and quaternion product, both tested separately. + Quaternion q_y(Vector3(0.0, yaw, 0.0)); + Quaternion q_p(Vector3(pitch, 0.0, 0.0)); + Quaternion q_r(Vector3(0.0, 0.0, roll)); + // Roll-Z is followed by Pitch-X, then Yaw-Y. + Quaternion q_yxz = q_y * q_p * q_r; + + return q_yxz; +} + +TEST_CASE("[Quaternion] Default Construct") { + Quaternion q; + + CHECK(q[0] == 0.0); + CHECK(q[1] == 0.0); + CHECK(q[2] == 0.0); + CHECK(q[3] == 1.0); +} + +TEST_CASE("[Quaternion] Construct x,y,z,w") { + // Values are taken from actual use in another project & are valid (except roundoff error). + Quaternion q(0.2391, 0.099, 0.3696, 0.8924); + + CHECK(q[0] == doctest::Approx(0.2391)); + CHECK(q[1] == doctest::Approx(0.099)); + CHECK(q[2] == doctest::Approx(0.3696)); + CHECK(q[3] == doctest::Approx(0.8924)); +} + +TEST_CASE("[Quaternion] Construct AxisAngle 1") { + // Easy to visualize: 120 deg about X-axis. + Quaternion q(Vector3(1.0, 0.0, 0.0), Math::deg2rad(120.0)); + + // 0.866 isn't close enough; doctest::Approx doesn't cut much slack! + CHECK(q[0] == doctest::Approx(0.866025)); // Sine of half the angle. + CHECK(q[1] == doctest::Approx(0.0)); + CHECK(q[2] == doctest::Approx(0.0)); + CHECK(q[3] == doctest::Approx(0.5)); // Cosine of half the angle. +} + +TEST_CASE("[Quaternion] Construct AxisAngle 2") { + // Easy to visualize: 30 deg about Y-axis. + Quaternion q(Vector3(0.0, 1.0, 0.0), Math::deg2rad(30.0)); + + CHECK(q[0] == doctest::Approx(0.0)); + CHECK(q[1] == doctest::Approx(0.258819)); // Sine of half the angle. + CHECK(q[2] == doctest::Approx(0.0)); + CHECK(q[3] == doctest::Approx(0.965926)); // Cosine of half the angle. +} + +TEST_CASE("[Quaternion] Construct AxisAngle 3") { + // Easy to visualize: 60 deg about Z-axis. + Quaternion q(Vector3(0.0, 0.0, 1.0), Math::deg2rad(60.0)); + + CHECK(q[0] == doctest::Approx(0.0)); + CHECK(q[1] == doctest::Approx(0.0)); + CHECK(q[2] == doctest::Approx(0.5)); // Sine of half the angle. + CHECK(q[3] == doctest::Approx(0.866025)); // Cosine of half the angle. +} + +TEST_CASE("[Quaternion] Construct AxisAngle 4") { + // More complex & hard to visualize, so test w/ data from online calculator. + Vector3 axis(1.0, 2.0, 0.5); + Quaternion q(axis.normalized(), Math::deg2rad(35.0)); + + CHECK(q[0] == doctest::Approx(0.131239)); + CHECK(q[1] == doctest::Approx(0.262478)); + CHECK(q[2] == doctest::Approx(0.0656194)); + CHECK(q[3] == doctest::Approx(0.953717)); +} + +TEST_CASE("[Quaternion] Construct from Quaternion") { + Vector3 axis(1.0, 2.0, 0.5); + Quaternion q_src(axis.normalized(), Math::deg2rad(35.0)); + Quaternion q(q_src); + + CHECK(q[0] == doctest::Approx(0.131239)); + CHECK(q[1] == doctest::Approx(0.262478)); + CHECK(q[2] == doctest::Approx(0.0656194)); + CHECK(q[3] == doctest::Approx(0.953717)); +} + +TEST_CASE("[Quaternion] Construct Euler SingleAxis") { + double yaw = Math::deg2rad(45.0); + double pitch = Math::deg2rad(30.0); + double roll = Math::deg2rad(10.0); + + Vector3 euler_y(0.0, yaw, 0.0); + Quaternion q_y(euler_y); + CHECK(q_y[0] == doctest::Approx(0.0)); + CHECK(q_y[1] == doctest::Approx(0.382684)); + CHECK(q_y[2] == doctest::Approx(0.0)); + CHECK(q_y[3] == doctest::Approx(0.923879)); + + Vector3 euler_p(pitch, 0.0, 0.0); + Quaternion q_p(euler_p); + CHECK(q_p[0] == doctest::Approx(0.258819)); + CHECK(q_p[1] == doctest::Approx(0.0)); + CHECK(q_p[2] == doctest::Approx(0.0)); + CHECK(q_p[3] == doctest::Approx(0.965926)); + + Vector3 euler_r(0.0, 0.0, roll); + Quaternion q_r(euler_r); + CHECK(q_r[0] == doctest::Approx(0.0)); + CHECK(q_r[1] == doctest::Approx(0.0)); + CHECK(q_r[2] == doctest::Approx(0.0871558)); + CHECK(q_r[3] == doctest::Approx(0.996195)); +} + +TEST_CASE("[Quaternion] Construct Euler YXZ dynamic axes") { + double yaw = Math::deg2rad(45.0); + double pitch = Math::deg2rad(30.0); + double roll = Math::deg2rad(10.0); + + // Generate YXZ comparision data (Z-then-X-then-Y) using single-axis Euler + // constructor and quaternion product, both tested separately. + Vector3 euler_y(0.0, yaw, 0.0); + Quaternion q_y(euler_y); + Vector3 euler_p(pitch, 0.0, 0.0); + Quaternion q_p(euler_p); + Vector3 euler_r(0.0, 0.0, roll); + Quaternion q_r(euler_r); + + // Roll-Z is followed by Pitch-X. + Quaternion check_xz = q_p * q_r; + // Then Yaw-Y follows both. + Quaternion check_yxz = q_y * check_xz; + + // Test construction from YXZ Euler angles. + Vector3 euler_yxz(pitch, yaw, roll); + Quaternion q(euler_yxz); + CHECK(q[0] == doctest::Approx(check_yxz[0])); + CHECK(q[1] == doctest::Approx(check_yxz[1])); + CHECK(q[2] == doctest::Approx(check_yxz[2])); + CHECK(q[3] == doctest::Approx(check_yxz[3])); + + // Sneak in a test of is_equal_approx. + CHECK(q.is_equal_approx(check_yxz)); +} + +TEST_CASE("[Quaternion] Construct Basis Euler") { + double yaw = Math::deg2rad(45.0); + double pitch = Math::deg2rad(30.0); + double roll = Math::deg2rad(10.0); + Vector3 euler_yxz(pitch, yaw, roll); + Quaternion q_yxz(euler_yxz); + Basis basis_axes(euler_yxz); + Quaternion q(basis_axes); + CHECK(q.is_equal_approx(q_yxz)); +} + +TEST_CASE("[Quaternion] Construct Basis Axes") { + // Arbitrary Euler angles. + Vector3 euler_yxz(Math::deg2rad(31.41), Math::deg2rad(-49.16), Math::deg2rad(12.34)); + // Basis vectors from online calculation of rotation matrix. + Vector3 i_unit(0.5545787, 0.1823950, 0.8118957); + Vector3 j_unit(-0.5249245, 0.8337420, 0.1712555); + Vector3 k_unit(-0.6456754, -0.5211586, 0.5581192); + // Quaternion from online calculation. + Quaternion q_calc(0.2016913, -0.4245716, 0.206033, 0.8582598); + // Quaternion from local calculation. + Quaternion q_local = quat_euler_yxz_deg(Vector3(31.41, -49.16, 12.34)); + // Quaternion from Euler angles constructor. + Quaternion q_euler(euler_yxz); + CHECK(q_calc.is_equal_approx(q_local)); + CHECK(q_local.is_equal_approx(q_euler)); + + // Calculate Basis and construct Quaternion. + // When this is written, C++ Basis class does not construct from basis vectors. + // This is by design, but may be subject to change. + // Workaround by constructing Basis from Euler angles. + // basis_axes = Basis(i_unit, j_unit, k_unit); + Basis basis_axes(euler_yxz); + Quaternion q(basis_axes); + + CHECK(basis_axes.get_column(0).is_equal_approx(i_unit)); + CHECK(basis_axes.get_column(1).is_equal_approx(j_unit)); + CHECK(basis_axes.get_column(2).is_equal_approx(k_unit)); + + CHECK(q.is_equal_approx(q_calc)); + CHECK_FALSE(q.inverse().is_equal_approx(q_calc)); + CHECK(q.is_equal_approx(q_local)); + CHECK(q.is_equal_approx(q_euler)); + CHECK(q[0] == doctest::Approx(0.2016913)); + CHECK(q[1] == doctest::Approx(-0.4245716)); + CHECK(q[2] == doctest::Approx(0.206033)); + CHECK(q[3] == doctest::Approx(0.8582598)); +} + +TEST_CASE("[Quaternion] Product (book)") { + // Example from "Quaternions and Rotation Sequences" by Jack Kuipers, p. 108. + Quaternion p(1.0, -2.0, 1.0, 3.0); + Quaternion q(-1.0, 2.0, 3.0, 2.0); + + Quaternion pq = p * q; + CHECK(pq[0] == doctest::Approx(-9.0)); + CHECK(pq[1] == doctest::Approx(-2.0)); + CHECK(pq[2] == doctest::Approx(11.0)); + CHECK(pq[3] == doctest::Approx(8.0)); +} + +TEST_CASE("[Quaternion] Product") { + double yaw = Math::deg2rad(45.0); + double pitch = Math::deg2rad(30.0); + double roll = Math::deg2rad(10.0); + + Vector3 euler_y(0.0, yaw, 0.0); + Quaternion q_y(euler_y); + CHECK(q_y[0] == doctest::Approx(0.0)); + CHECK(q_y[1] == doctest::Approx(0.382684)); + CHECK(q_y[2] == doctest::Approx(0.0)); + CHECK(q_y[3] == doctest::Approx(0.923879)); + + Vector3 euler_p(pitch, 0.0, 0.0); + Quaternion q_p(euler_p); + CHECK(q_p[0] == doctest::Approx(0.258819)); + CHECK(q_p[1] == doctest::Approx(0.0)); + CHECK(q_p[2] == doctest::Approx(0.0)); + CHECK(q_p[3] == doctest::Approx(0.965926)); + + Vector3 euler_r(0.0, 0.0, roll); + Quaternion q_r(euler_r); + CHECK(q_r[0] == doctest::Approx(0.0)); + CHECK(q_r[1] == doctest::Approx(0.0)); + CHECK(q_r[2] == doctest::Approx(0.0871558)); + CHECK(q_r[3] == doctest::Approx(0.996195)); + + // Test ZYX dynamic-axes since test data is available online. + // Rotate first about X axis, then new Y axis, then new Z axis. + // (Godot uses YXZ Yaw-Pitch-Roll order). + Quaternion q_yp = q_y * q_p; + CHECK(q_yp[0] == doctest::Approx(0.239118)); + CHECK(q_yp[1] == doctest::Approx(0.369644)); + CHECK(q_yp[2] == doctest::Approx(-0.099046)); + CHECK(q_yp[3] == doctest::Approx(0.892399)); + + Quaternion q_ryp = q_r * q_yp; + CHECK(q_ryp[0] == doctest::Approx(0.205991)); + CHECK(q_ryp[1] == doctest::Approx(0.389078)); + CHECK(q_ryp[2] == doctest::Approx(-0.0208912)); + CHECK(q_ryp[3] == doctest::Approx(0.897636)); +} + +TEST_CASE("[Quaternion] xform unit vectors") { + // Easy to visualize: 120 deg about X-axis. + // Transform the i, j, & k unit vectors. + Quaternion q(Vector3(1.0, 0.0, 0.0), Math::deg2rad(120.0)); + Vector3 i_t = q.xform(Vector3(1.0, 0.0, 0.0)); + Vector3 j_t = q.xform(Vector3(0.0, 1.0, 0.0)); + Vector3 k_t = q.xform(Vector3(0.0, 0.0, 1.0)); + // + CHECK(i_t.is_equal_approx(Vector3(1.0, 0.0, 0.0))); + CHECK(j_t.is_equal_approx(Vector3(0.0, -0.5, 0.866025))); + CHECK(k_t.is_equal_approx(Vector3(0.0, -0.866025, -0.5))); + CHECK(i_t.length_squared() == doctest::Approx(1.0)); + CHECK(j_t.length_squared() == doctest::Approx(1.0)); + CHECK(k_t.length_squared() == doctest::Approx(1.0)); + + // Easy to visualize: 30 deg about Y-axis. + q = Quaternion(Vector3(0.0, 1.0, 0.0), Math::deg2rad(30.0)); + i_t = q.xform(Vector3(1.0, 0.0, 0.0)); + j_t = q.xform(Vector3(0.0, 1.0, 0.0)); + k_t = q.xform(Vector3(0.0, 0.0, 1.0)); + // + CHECK(i_t.is_equal_approx(Vector3(0.866025, 0.0, -0.5))); + CHECK(j_t.is_equal_approx(Vector3(0.0, 1.0, 0.0))); + CHECK(k_t.is_equal_approx(Vector3(0.5, 0.0, 0.866025))); + CHECK(i_t.length_squared() == doctest::Approx(1.0)); + CHECK(j_t.length_squared() == doctest::Approx(1.0)); + CHECK(k_t.length_squared() == doctest::Approx(1.0)); + + // Easy to visualize: 60 deg about Z-axis. + q = Quaternion(Vector3(0.0, 0.0, 1.0), Math::deg2rad(60.0)); + i_t = q.xform(Vector3(1.0, 0.0, 0.0)); + j_t = q.xform(Vector3(0.0, 1.0, 0.0)); + k_t = q.xform(Vector3(0.0, 0.0, 1.0)); + // + CHECK(i_t.is_equal_approx(Vector3(0.5, 0.866025, 0.0))); + CHECK(j_t.is_equal_approx(Vector3(-0.866025, 0.5, 0.0))); + CHECK(k_t.is_equal_approx(Vector3(0.0, 0.0, 1.0))); + CHECK(i_t.length_squared() == doctest::Approx(1.0)); + CHECK(j_t.length_squared() == doctest::Approx(1.0)); + CHECK(k_t.length_squared() == doctest::Approx(1.0)); +} + +TEST_CASE("[Quaternion] xform vector") { + // Arbitrary quaternion rotates an arbitrary vector. + Vector3 euler_yzx(Math::deg2rad(31.41), Math::deg2rad(-49.16), Math::deg2rad(12.34)); + Basis basis_axes(euler_yzx); + Quaternion q(basis_axes); + + Vector3 v_arb(3.0, 4.0, 5.0); + Vector3 v_rot = q.xform(v_arb); + Vector3 v_compare = basis_axes.xform(v_arb); + + CHECK(v_rot.length_squared() == doctest::Approx(v_arb.length_squared())); + CHECK(v_rot.is_equal_approx(v_compare)); +} + +// Test vector xform for a single combination of Quaternion and Vector. +void test_quat_vec_rotate(Vector3 euler_yzx, Vector3 v_in) { + Basis basis_axes(euler_yzx); + Quaternion q(basis_axes); + + Vector3 v_rot = q.xform(v_in); + Vector3 v_compare = basis_axes.xform(v_in); + + CHECK(v_rot.length_squared() == doctest::Approx(v_in.length_squared())); + CHECK(v_rot.is_equal_approx(v_compare)); +} + +TEST_CASE("[Stress][Quaternion] Many vector xforms") { + // Many arbitrary quaternions rotate many arbitrary vectors. + // For each trial, check that rotation by Quaternion yields same result as + // rotation by Basis. + const int STEPS = 100; // Number of test steps in each dimension + const double delta = 2.0 * Math_PI / STEPS; // Angle increment per step + const double delta_vec = 20.0 / STEPS; // Vector increment per step + Vector3 vec_arb(1.0, 1.0, 1.0); + double x_angle = -Math_PI; + double y_angle = -Math_PI; + double z_angle = -Math_PI; + for (double i = 0; i < STEPS; ++i) { + vec_arb[0] = -10.0 + i * delta_vec; + x_angle = i * delta - Math_PI; + for (double j = 0; j < STEPS; ++j) { + vec_arb[1] = -10.0 + j * delta_vec; + y_angle = j * delta - Math_PI; + for (double k = 0; k < STEPS; ++k) { + vec_arb[2] = -10.0 + k * delta_vec; + z_angle = k * delta - Math_PI; + Vector3 euler_yzx(x_angle, y_angle, z_angle); + test_quat_vec_rotate(euler_yzx, vec_arb); + } + } + } +} + +} // namespace TestQuaternion + +#endif // TEST_QUATERNION_H diff --git a/tests/core/math/test_transform_2d.h b/tests/core/math/test_transform_2d.h new file mode 100644 index 0000000000..697bf63fc5 --- /dev/null +++ b/tests/core/math/test_transform_2d.h @@ -0,0 +1,88 @@ +/*************************************************************************/ +/* test_transform_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_TRANSFORM_2D_H +#define TEST_TRANSFORM_2D_H + +#include "core/math/transform_2d.h" + +#include "tests/test_macros.h" + +namespace TestTransform2D { + +Transform2D create_dummy_transform() { + return Transform2D(Vector2(1, 2), Vector2(3, 4), Vector2(5, 6)); +} + +Transform2D identity() { + return Transform2D(); +} + +TEST_CASE("[Transform2D] translation") { + Vector2 offset = Vector2(1, 2); + + // Both versions should give the same result applied to identity. + CHECK(identity().translated(offset) == identity().translated_local(offset)); + + // Check both versions against left and right multiplications. + Transform2D orig = create_dummy_transform(); + Transform2D T = identity().translated(offset); + CHECK(orig.translated(offset) == T * orig); + CHECK(orig.translated_local(offset) == orig * T); +} + +TEST_CASE("[Transform2D] scaling") { + Vector2 scaling = Vector2(1, 2); + + // Both versions should give the same result applied to identity. + CHECK(identity().scaled(scaling) == identity().scaled_local(scaling)); + + // Check both versions against left and right multiplications. + Transform2D orig = create_dummy_transform(); + Transform2D S = identity().scaled(scaling); + CHECK(orig.scaled(scaling) == S * orig); + CHECK(orig.scaled_local(scaling) == orig * S); +} + +TEST_CASE("[Transform2D] rotation") { + real_t phi = 1.0; + + // Both versions should give the same result applied to identity. + CHECK(identity().rotated(phi) == identity().rotated_local(phi)); + + // Check both versions against left and right multiplications. + Transform2D orig = create_dummy_transform(); + Transform2D R = identity().rotated(phi); + CHECK(orig.rotated(phi) == R * orig); + CHECK(orig.rotated_local(phi) == orig * R); +} +} // namespace TestTransform2D + +#endif // TEST_TRANSFORM_2D_H diff --git a/tests/core/math/test_transform_3d.h b/tests/core/math/test_transform_3d.h new file mode 100644 index 0000000000..da166b43f7 --- /dev/null +++ b/tests/core/math/test_transform_3d.h @@ -0,0 +1,89 @@ +/*************************************************************************/ +/* test_transform_3d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_TRANSFORM_3D_H +#define TEST_TRANSFORM_3D_H + +#include "core/math/transform_3d.h" + +#include "tests/test_macros.h" + +namespace TestTransform3D { + +Transform3D create_dummy_transform() { + return Transform3D(Basis(Vector3(1, 2, 3), Vector3(4, 5, 6), Vector3(7, 8, 9)), Vector3(10, 11, 12)); +} + +Transform3D identity() { + return Transform3D(); +} + +TEST_CASE("[Transform3D] translation") { + Vector3 offset = Vector3(1, 2, 3); + + // Both versions should give the same result applied to identity. + CHECK(identity().translated(offset) == identity().translated_local(offset)); + + // Check both versions against left and right multiplications. + Transform3D orig = create_dummy_transform(); + Transform3D T = identity().translated(offset); + CHECK(orig.translated(offset) == T * orig); + CHECK(orig.translated_local(offset) == orig * T); +} + +TEST_CASE("[Transform3D] scaling") { + Vector3 scaling = Vector3(1, 2, 3); + + // Both versions should give the same result applied to identity. + CHECK(identity().scaled(scaling) == identity().scaled_local(scaling)); + + // Check both versions against left and right multiplications. + Transform3D orig = create_dummy_transform(); + Transform3D S = identity().scaled(scaling); + CHECK(orig.scaled(scaling) == S * orig); + CHECK(orig.scaled_local(scaling) == orig * S); +} + +TEST_CASE("[Transform3D] rotation") { + Vector3 axis = Vector3(1, 2, 3).normalized(); + real_t phi = 1.0; + + // Both versions should give the same result applied to identity. + CHECK(identity().rotated(axis, phi) == identity().rotated_local(axis, phi)); + + // Check both versions against left and right multiplications. + Transform3D orig = create_dummy_transform(); + Transform3D R = identity().rotated(axis, phi); + CHECK(orig.rotated(axis, phi) == R * orig); + CHECK(orig.rotated_local(axis, phi) == orig * R); +} +} // namespace TestTransform3D + +#endif // TEST_TRANSFORM_3D_H diff --git a/tests/core/math/test_vector4.h b/tests/core/math/test_vector4.h new file mode 100644 index 0000000000..4b8759c0ca --- /dev/null +++ b/tests/core/math/test_vector4.h @@ -0,0 +1,312 @@ +/*************************************************************************/ +/* test_vector4.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_VECTOR4_H +#define TEST_VECTOR4_H + +#include "core/math/vector4.h" +#include "tests/test_macros.h" + +#define Math_SQRT3 1.7320508075688772935274463415059 + +namespace TestVector4 { + +TEST_CASE("[Vector4] Axis methods") { + Vector4 vector = Vector4(1.2, 3.4, 5.6, -0.9); + CHECK_MESSAGE( + vector.max_axis_index() == Vector4::Axis::AXIS_Z, + "Vector4 max_axis_index should work as expected."); + CHECK_MESSAGE( + vector.min_axis_index() == Vector4::Axis::AXIS_W, + "Vector4 min_axis_index should work as expected."); + CHECK_MESSAGE( + vector.get_axis(vector.max_axis_index()) == (real_t)5.6, + "Vector4 get_axis should work as expected."); + CHECK_MESSAGE( + vector[vector.min_axis_index()] == (real_t)-0.9, + "Vector4 array operator should work as expected."); + + vector.set_axis(Vector4::Axis::AXIS_Y, 4.7); + CHECK_MESSAGE( + vector.get_axis(Vector4::Axis::AXIS_Y) == (real_t)4.7, + "Vector4 set_axis should work as expected."); + vector[Vector4::Axis::AXIS_Y] = 3.7; + CHECK_MESSAGE( + vector[Vector4::Axis::AXIS_Y] == (real_t)3.7, + "Vector4 array operator setter should work as expected."); +} + +TEST_CASE("[Vector4] Interpolation methods") { + const Vector4 vector1 = Vector4(1, 2, 3, 4); + const Vector4 vector2 = Vector4(4, 5, 6, 7); + CHECK_MESSAGE( + vector1.lerp(vector2, 0.5) == Vector4(2.5, 3.5, 4.5, 5.5), + "Vector4 lerp should work as expected."); + CHECK_MESSAGE( + vector1.lerp(vector2, 1.0 / 3.0).is_equal_approx(Vector4(2, 3, 4, 5)), + "Vector4 lerp should work as expected."); + CHECK_MESSAGE( + vector1.cubic_interpolate(vector2, Vector4(), Vector4(7, 7, 7, 7), 0.5) == Vector4(2.375, 3.5, 4.625, 5.75), + "Vector4 cubic_interpolate should work as expected."); + CHECK_MESSAGE( + vector1.cubic_interpolate(vector2, Vector4(), Vector4(7, 7, 7, 7), 1.0 / 3.0).is_equal_approx(Vector4(1.851851940155029297, 2.962963104248046875, 4.074074268341064453, 5.185185185185)), + "Vector4 cubic_interpolate should work as expected."); +} + +TEST_CASE("[Vector4] Length methods") { + const Vector4 vector1 = Vector4(10, 10, 10, 10); + const Vector4 vector2 = Vector4(20, 30, 40, 50); + CHECK_MESSAGE( + vector1.length_squared() == 400, + "Vector4 length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.length(), 20), + "Vector4 length should work as expected."); + CHECK_MESSAGE( + vector2.length_squared() == 5400, + "Vector4 length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector2.length(), (real_t)73.484692283495), + "Vector4 length should work as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.distance_to(vector2), (real_t)54.772255750517), + "Vector4 distance_to should work as expected."); +} + +TEST_CASE("[Vector4] Limiting methods") { + const Vector4 vector = Vector4(10, 10, 10, 10); + CHECK_MESSAGE( + Vector4(-5, 5, 15, -15).clamp(Vector4(), vector) == Vector4(0, 5, 10, 0), + "Vector4 clamp should work as expected."); + CHECK_MESSAGE( + vector.clamp(Vector4(0, 10, 15, 18), Vector4(5, 10, 20, 25)) == Vector4(5, 10, 15, 18), + "Vector4 clamp should work as expected."); +} + +TEST_CASE("[Vector4] Normalization methods") { + CHECK_MESSAGE( + Vector4(1, 0, 0, 0).is_normalized() == true, + "Vector4 is_normalized should return true for a normalized vector."); + CHECK_MESSAGE( + Vector4(1, 1, 1, 1).is_normalized() == false, + "Vector4 is_normalized should return false for a non-normalized vector."); + CHECK_MESSAGE( + Vector4(1, 0, 0, 0).normalized() == Vector4(1, 0, 0, 0), + "Vector4 normalized should return the same vector for a normalized vector."); + CHECK_MESSAGE( + Vector4(1, 1, 0, 0).normalized().is_equal_approx(Vector4(Math_SQRT12, Math_SQRT12, 0, 0)), + "Vector4 normalized should work as expected."); + CHECK_MESSAGE( + Vector4(1, 1, 1, 1).normalized().is_equal_approx(Vector4(0.5, 0.5, 0.5, 0.5)), + "Vector4 normalized should work as expected."); +} + +TEST_CASE("[Vector4] Operators") { + const Vector4 decimal1 = Vector4(2.3, 4.9, 7.8, 3.2); + const Vector4 decimal2 = Vector4(1.2, 3.4, 5.6, 1.7); + const Vector4 power1 = Vector4(0.75, 1.5, 0.625, 0.125); + const Vector4 power2 = Vector4(0.5, 0.125, 0.25, 0.75); + const Vector4 int1 = Vector4(4, 5, 9, 2); + const Vector4 int2 = Vector4(1, 2, 3, 1); + + CHECK_MESSAGE( + -decimal1 == Vector4(-2.3, -4.9, -7.8, -3.2), + "Vector4 change of sign should work as expected."); + CHECK_MESSAGE( + (decimal1 + decimal2).is_equal_approx(Vector4(3.5, 8.3, 13.4, 4.9)), + "Vector4 addition should behave as expected."); + CHECK_MESSAGE( + (power1 + power2) == Vector4(1.25, 1.625, 0.875, 0.875), + "Vector4 addition with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 + int2) == Vector4(5, 7, 12, 3), + "Vector4 addition with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 - decimal2).is_equal_approx(Vector4(1.1, 1.5, 2.2, 1.5)), + "Vector4 subtraction should behave as expected."); + CHECK_MESSAGE( + (power1 - power2) == Vector4(0.25, 1.375, 0.375, -0.625), + "Vector4 subtraction with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 - int2) == Vector4(3, 3, 6, 1), + "Vector4 subtraction with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 * decimal2).is_equal_approx(Vector4(2.76, 16.66, 43.68, 5.44)), + "Vector4 multiplication should behave as expected."); + CHECK_MESSAGE( + (power1 * power2) == Vector4(0.375, 0.1875, 0.15625, 0.09375), + "Vector4 multiplication with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 * int2) == Vector4(4, 10, 27, 2), + "Vector4 multiplication with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 / decimal2).is_equal_approx(Vector4(1.91666666666666666, 1.44117647058823529, 1.39285714285714286, 1.88235294118)), + "Vector4 division should behave as expected."); + CHECK_MESSAGE( + (power1 / power2) == Vector4(1.5, 12.0, 2.5, 1.0 / 6.0), + "Vector4 division with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 / int2) == Vector4(4, 2.5, 3, 2), + "Vector4 division with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 * 2).is_equal_approx(Vector4(4.6, 9.8, 15.6, 6.4)), + "Vector4 multiplication should behave as expected."); + CHECK_MESSAGE( + (power1 * 2) == Vector4(1.5, 3, 1.25, 0.25), + "Vector4 multiplication with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 * 2) == Vector4(8, 10, 18, 4), + "Vector4 multiplication with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 / 2).is_equal_approx(Vector4(1.15, 2.45, 3.9, 1.6)), + "Vector4 division should behave as expected."); + CHECK_MESSAGE( + (power1 / 2) == Vector4(0.375, 0.75, 0.3125, 0.0625), + "Vector4 division with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 / 2) == Vector4(2, 2.5, 4.5, 1), + "Vector4 division with integers should give exact results."); + + CHECK_MESSAGE( + ((String)decimal1) == "(2.3, 4.9, 7.8, 3.2)", + "Vector4 cast to String should work as expected."); + CHECK_MESSAGE( + ((String)decimal2) == "(1.2, 3.4, 5.6, 1.7)", + "Vector4 cast to String should work as expected."); + CHECK_MESSAGE( + ((String)Vector4(9.7, 9.8, 9.9, -1.8)) == "(9.7, 9.8, 9.9, -1.8)", + "Vector4 cast to String should work as expected."); +#ifdef REAL_T_IS_DOUBLE + CHECK_MESSAGE( + ((String)Vector4(Math_E, Math_SQRT2, Math_SQRT3, Math_SQRT3)) == "(2.71828182845905, 1.4142135623731, 1.73205080756888, 1.73205080756888)", + "Vector4 cast to String should print the correct amount of digits for real_t = double."); +#else + CHECK_MESSAGE( + ((String)Vector4(Math_E, Math_SQRT2, Math_SQRT3, Math_SQRT3)) == "(2.718282, 1.414214, 1.732051, 1.732051)", + "Vector4 cast to String should print the correct amount of digits for real_t = float."); +#endif // REAL_T_IS_DOUBLE +} + +TEST_CASE("[Vector4] Other methods") { + const Vector4 vector = Vector4(1.2, 3.4, 5.6, 1.6); + CHECK_MESSAGE( + vector.direction_to(Vector4()).is_equal_approx(-vector.normalized()), + "Vector4 direction_to should work as expected."); + CHECK_MESSAGE( + Vector4(1, 1, 1, 1).direction_to(Vector4(2, 2, 2, 2)).is_equal_approx(Vector4(0.5, 0.5, 0.5, 0.5)), + "Vector4 direction_to should work as expected."); + CHECK_MESSAGE( + vector.inverse().is_equal_approx(Vector4(1 / 1.2, 1 / 3.4, 1 / 5.6, 1 / 1.6)), + "Vector4 inverse should work as expected."); + CHECK_MESSAGE( + vector.posmod(2).is_equal_approx(Vector4(1.2, 1.4, 1.6, 1.6)), + "Vector4 posmod should work as expected."); + CHECK_MESSAGE( + (-vector).posmod(2).is_equal_approx(Vector4(0.8, 0.6, 0.4, 0.4)), + "Vector4 posmod should work as expected."); + CHECK_MESSAGE( + vector.posmodv(Vector4(1, 2, 3, 4)).is_equal_approx(Vector4(0.2, 1.4, 2.6, 1.6)), + "Vector4 posmodv should work as expected."); + CHECK_MESSAGE( + (-vector).posmodv(Vector4(2, 3, 4, 5)).is_equal_approx(Vector4(0.8, 2.6, 2.4, 3.4)), + "Vector4 posmodv should work as expected."); + CHECK_MESSAGE( + vector.snapped(Vector4(1, 1, 1, 1)) == Vector4(1, 3, 6, 2), + "Vector4 snapped to integers should be the same as rounding."); + CHECK_MESSAGE( + vector.snapped(Vector4(0.25, 0.25, 0.25, 0.25)) == Vector4(1.25, 3.5, 5.5, 1.5), + "Vector4 snapped to 0.25 should give exact results."); +} + +TEST_CASE("[Vector4] Rounding methods") { + const Vector4 vector1 = Vector4(1.2, 3.4, 5.6, 1.6); + const Vector4 vector2 = Vector4(1.2, -3.4, -5.6, -1.6); + CHECK_MESSAGE( + vector1.abs() == vector1, + "Vector4 abs should work as expected."); + CHECK_MESSAGE( + vector2.abs() == vector1, + "Vector4 abs should work as expected."); + CHECK_MESSAGE( + vector1.ceil() == Vector4(2, 4, 6, 2), + "Vector4 ceil should work as expected."); + CHECK_MESSAGE( + vector2.ceil() == Vector4(2, -3, -5, -1), + "Vector4 ceil should work as expected."); + + CHECK_MESSAGE( + vector1.floor() == Vector4(1, 3, 5, 1), + "Vector4 floor should work as expected."); + CHECK_MESSAGE( + vector2.floor() == Vector4(1, -4, -6, -2), + "Vector4 floor should work as expected."); + + CHECK_MESSAGE( + vector1.round() == Vector4(1, 3, 6, 2), + "Vector4 round should work as expected."); + CHECK_MESSAGE( + vector2.round() == Vector4(1, -3, -6, -2), + "Vector4 round should work as expected."); + + CHECK_MESSAGE( + vector1.sign() == Vector4(1, 1, 1, 1), + "Vector4 sign should work as expected."); + CHECK_MESSAGE( + vector2.sign() == Vector4(1, -1, -1, -1), + "Vector4 sign should work as expected."); +} + +TEST_CASE("[Vector4] Linear algebra methods") { + const Vector4 vector_x = Vector4(1, 0, 0, 0); + const Vector4 vector_y = Vector4(0, 1, 0, 0); + const Vector4 vector1 = Vector4(1.7, 2.3, 1, 9.1); + const Vector4 vector2 = Vector4(-8.2, -16, 3, 2.4); + + CHECK_MESSAGE( + vector_x.dot(vector_y) == 0.0, + "Vector4 dot product of perpendicular vectors should be zero."); + CHECK_MESSAGE( + vector_x.dot(vector_x) == 1.0, + "Vector4 dot product of identical unit vectors should be one."); + CHECK_MESSAGE( + (vector_x * 10).dot(vector_x * 10) == 100.0, + "Vector4 dot product of same direction vectors should behave as expected."); + CHECK_MESSAGE( + Math::is_equal_approx((vector1 * 2).dot(vector2 * 4), (real_t)-25.9 * 8), + "Vector4 dot product should work as expected."); +} +} // namespace TestVector4 + +#endif // TEST_VECTOR4_H diff --git a/tests/core/math/test_vector4i.h b/tests/core/math/test_vector4i.h new file mode 100644 index 0000000000..ac63001b24 --- /dev/null +++ b/tests/core/math/test_vector4i.h @@ -0,0 +1,148 @@ +/*************************************************************************/ +/* test_vector4i.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_VECTOR4I_H +#define TEST_VECTOR4I_H + +#include "core/math/vector4i.h" +#include "tests/test_macros.h" + +namespace TestVector4i { + +TEST_CASE("[Vector4i] Axis methods") { + Vector4i vector = Vector4i(1, 2, 3, 4); + CHECK_MESSAGE( + vector.max_axis_index() == Vector4i::Axis::AXIS_W, + "Vector4i max_axis_index should work as expected."); + CHECK_MESSAGE( + vector.min_axis_index() == Vector4i::Axis::AXIS_X, + "Vector4i min_axis_index should work as expected."); + CHECK_MESSAGE( + vector.get_axis(vector.max_axis_index()) == 4, + "Vector4i get_axis should work as expected."); + CHECK_MESSAGE( + vector[vector.min_axis_index()] == 1, + "Vector4i array operator should work as expected."); + + vector.set_axis(Vector4i::Axis::AXIS_Y, 5); + CHECK_MESSAGE( + vector.get_axis(Vector4i::Axis::AXIS_Y) == 5, + "Vector4i set_axis should work as expected."); + vector[Vector4i::Axis::AXIS_Y] = 5; + CHECK_MESSAGE( + vector[Vector4i::Axis::AXIS_Y] == 5, + "Vector4i array operator setter should work as expected."); +} + +TEST_CASE("[Vector4i] Clamp method") { + const Vector4i vector = Vector4i(10, 10, 10, 10); + CHECK_MESSAGE( + Vector4i(-5, 5, 15, INT_MAX).clamp(Vector4i(), vector) == Vector4i(0, 5, 10, 10), + "Vector4i clamp should work as expected."); + CHECK_MESSAGE( + vector.clamp(Vector4i(0, 10, 15, -10), Vector4i(5, 10, 20, -5)) == Vector4i(5, 10, 15, -5), + "Vector4i clamp should work as expected."); +} + +TEST_CASE("[Vector4i] Length methods") { + const Vector4i vector1 = Vector4i(10, 10, 10, 10); + const Vector4i vector2 = Vector4i(20, 30, 40, 50); + CHECK_MESSAGE( + vector1.length_squared() == 400, + "Vector4i length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.length(), 20), + "Vector4i length should work as expected."); + CHECK_MESSAGE( + vector2.length_squared() == 5400, + "Vector4i length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector2.length(), 73.4846922835), + "Vector4i length should work as expected."); +} + +TEST_CASE("[Vector4i] Operators") { + const Vector4i vector1 = Vector4i(4, 5, 9, 2); + const Vector4i vector2 = Vector4i(1, 2, 3, 4); + + CHECK_MESSAGE( + -vector1 == Vector4i(-4, -5, -9, -2), + "Vector4i change of sign should work as expected."); + CHECK_MESSAGE( + (vector1 + vector2) == Vector4i(5, 7, 12, 6), + "Vector4i addition with integers should give exact results."); + CHECK_MESSAGE( + (vector1 - vector2) == Vector4i(3, 3, 6, -2), + "Vector4i subtraction with integers should give exact results."); + CHECK_MESSAGE( + (vector1 * vector2) == Vector4i(4, 10, 27, 8), + "Vector4i multiplication with integers should give exact results."); + CHECK_MESSAGE( + (vector1 / vector2) == Vector4i(4, 2, 3, 0), + "Vector4i division with integers should give exact results."); + + CHECK_MESSAGE( + (vector1 * 2) == Vector4i(8, 10, 18, 4), + "Vector4i multiplication with integers should give exact results."); + CHECK_MESSAGE( + (vector1 / 2) == Vector4i(2, 2, 4, 1), + "Vector4i division with integers should give exact results."); + + CHECK_MESSAGE( + ((Vector4)vector1) == Vector4(4, 5, 9, 2), + "Vector4i cast to Vector4 should work as expected."); + CHECK_MESSAGE( + ((Vector4)vector2) == Vector4(1, 2, 3, 4), + "Vector4i cast to Vector4 should work as expected."); + CHECK_MESSAGE( + Vector4i(Vector4(1.1, 2.9, 3.9, 100.5)) == Vector4i(1, 2, 3, 100), + "Vector4i constructed from Vector4 should work as expected."); +} + +TEST_CASE("[Vector4i] Abs and sign methods") { + const Vector4i vector1 = Vector4i(1, 3, 5, 7); + const Vector4i vector2 = Vector4i(1, -3, -5, 7); + CHECK_MESSAGE( + vector1.abs() == vector1, + "Vector4i abs should work as expected."); + CHECK_MESSAGE( + vector2.abs() == vector1, + "Vector4i abs should work as expected."); + + CHECK_MESSAGE( + vector1.sign() == Vector4i(1, 1, 1, 1), + "Vector4i sign should work as expected."); + CHECK_MESSAGE( + vector2.sign() == Vector4i(1, -1, -1, 1), + "Vector4i sign should work as expected."); +} +} // namespace TestVector4i + +#endif // TEST_VECTOR4I_H diff --git a/tests/core/object/test_class_db.h b/tests/core/object/test_class_db.h index c7535426df..fc329ba0eb 100644 --- a/tests/core/object/test_class_db.h +++ b/tests/core/object/test_class_db.h @@ -493,13 +493,13 @@ void add_exposed_classes(Context &r_context) { } if (!ClassDB::is_class_exposed(class_name)) { - MESSAGE(vformat("Ignoring class '%s' because it's not exposed.", class_name).utf8().get_data()); + MESSAGE(vformat("Ignoring class '%s' because it's not exposed.", class_name)); class_list.pop_front(); continue; } if (!ClassDB::is_class_enabled(class_name)) { - MESSAGE(vformat("Ignoring class '%s' because it's not enabled.", class_name).utf8().get_data()); + MESSAGE(vformat("Ignoring class '%s' because it's not enabled.", class_name)); class_list.pop_front(); continue; } diff --git a/tests/core/object/test_method_bind.h b/tests/core/object/test_method_bind.h index 350a08b6e2..2fe0c264a1 100644 --- a/tests/core/object/test_method_bind.h +++ b/tests/core/object/test_method_bind.h @@ -155,7 +155,6 @@ public: TEST_CASE("[MethodBind] check all method binds") { MethodBindTester *mbt = memnew(MethodBindTester); - print_line("testing method bind"); mbt->run_tests(); CHECK(mbt->test_valid[MethodBindTester::TEST_METHOD]); diff --git a/tests/core/object/test_object.h b/tests/core/object/test_object.h index 5b9d9cab53..88a3e4ccad 100644 --- a/tests/core/object/test_object.h +++ b/tests/core/object/test_object.h @@ -95,8 +95,8 @@ public: Ref<Script> get_script() const override { return Ref<Script>(); } - const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override { - return Vector<Multiplayer::RPCConfig>(); + const Variant get_rpc_config() const override { + return Variant(); } ScriptLanguage *get_language() override { return nullptr; diff --git a/tests/core/os/test_os.h b/tests/core/os/test_os.h new file mode 100644 index 0000000000..c46da5e156 --- /dev/null +++ b/tests/core/os/test_os.h @@ -0,0 +1,158 @@ +/*************************************************************************/ +/* test_os.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_OS_H +#define TEST_OS_H + +#include "core/os/os.h" + +#include "thirdparty/doctest/doctest.h" + +namespace TestOS { + +TEST_CASE("[OS] Environment variables") { +#ifdef WINDOWS_ENABLED + CHECK_MESSAGE( + OS::get_singleton()->has_environment("USERPROFILE"), + "The USERPROFILE environment variable should be present."); +#else + CHECK_MESSAGE( + OS::get_singleton()->has_environment("HOME"), + "The HOME environment variable should be present."); +#endif + + OS::get_singleton()->set_environment("HELLO", "world"); + CHECK_MESSAGE( + OS::get_singleton()->get_environment("HELLO") == "world", + "The previously-set HELLO environment variable should return the expected value."); +} + +TEST_CASE("[OS] Command line arguments") { + List<String> arguments = OS::get_singleton()->get_cmdline_args(); + bool found = false; + for (int i = 0; i < arguments.size(); i++) { + if (arguments[i] == "--test") { + found = true; + break; + } + } + CHECK_MESSAGE( + found, + "The `--test` option must be present in the list of command line arguments."); +} + +TEST_CASE("[OS] Executable and data paths") { + CHECK_MESSAGE( + OS::get_singleton()->get_executable_path().is_absolute_path(), + "The executable path returned should be an absolute path."); + CHECK_MESSAGE( + OS::get_singleton()->get_data_path().is_absolute_path(), + "The user data path returned should be an absolute path."); + CHECK_MESSAGE( + OS::get_singleton()->get_config_path().is_absolute_path(), + "The user configuration path returned should be an absolute path."); + CHECK_MESSAGE( + OS::get_singleton()->get_cache_path().is_absolute_path(), + "The cache path returned should be an absolute path."); +} + +TEST_CASE("[OS] Ticks") { + CHECK_MESSAGE( + OS::get_singleton()->get_ticks_usec() > 1000, + "The returned ticks (in microseconds) must be greater than 1,000."); + CHECK_MESSAGE( + OS::get_singleton()->get_ticks_msec() > 1, + "The returned ticks (in milliseconds) must be greater than 1."); +} + +TEST_CASE("[OS] Feature tags") { + CHECK_MESSAGE( + OS::get_singleton()->has_feature("editor"), + "The binary has the \"editor\" feature tag."); + CHECK_MESSAGE( + !OS::get_singleton()->has_feature("standalone"), + "The binary does not have the \"standalone\" feature tag."); + CHECK_MESSAGE( + OS::get_singleton()->has_feature("debug"), + "The binary has the \"debug\" feature tag."); + CHECK_MESSAGE( + !OS::get_singleton()->has_feature("release"), + "The binary does not have the \"release\" feature tag."); +} + +TEST_CASE("[OS] Process ID") { + CHECK_MESSAGE( + OS::get_singleton()->get_process_id() >= 1, + "The returned process ID should be greater than zero."); +} + +TEST_CASE("[OS] Processor count and memory information") { + CHECK_MESSAGE( + OS::get_singleton()->get_processor_count() >= 1, + "The returned processor count should be greater than zero."); + CHECK_MESSAGE( + OS::get_singleton()->get_static_memory_usage() >= 1, + "The returned static memory usage should be greater than zero."); + CHECK_MESSAGE( + OS::get_singleton()->get_static_memory_peak_usage() >= 1, + "The returned static memory peak usage should be greater than zero."); +} + +TEST_CASE("[OS] Execute") { +#ifdef WINDOWS_ENABLED + List<String> arguments; + arguments.push_back("/C"); + arguments.push_back("dir > NUL"); + int exit_code; + const Error err = OS::get_singleton()->execute("cmd", arguments, nullptr, &exit_code); + CHECK_MESSAGE( + err == OK, + "(Running the command `cmd /C \"dir > NUL\"` returns the expected Godot error code (OK)."); + CHECK_MESSAGE( + exit_code == 0, + "Running the command `cmd /C \"dir > NUL\"` returns a zero (successful) exit code."); +#else + List<String> arguments; + arguments.push_back("-c"); + arguments.push_back("ls > /dev/null"); + int exit_code; + const Error err = OS::get_singleton()->execute("sh", arguments, nullptr, &exit_code); + CHECK_MESSAGE( + err == OK, + "(Running the command `sh -c \"ls > /dev/null\"` returns the expected Godot error code (OK)."); + CHECK_MESSAGE( + exit_code == 0, + "Running the command `sh -c \"ls > /dev/null\"` returns a zero (successful) exit code."); +#endif +} + +} // namespace TestOS + +#endif // TEST_OS_H diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 0c5704d6c9..8914dbfd9a 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -152,6 +152,20 @@ TEST_CASE("[String] UTF16 with BOM") { CHECK(String::utf16(cs) == s); } +TEST_CASE("[String] UTF8 with CR") { + const String base = U"Hello darkness\r\nMy old friend\nI've come to talk\rWith you again"; + + String keep_cr; + Error err = keep_cr.parse_utf8(base.utf8().get_data()); + CHECK(err == OK); + CHECK(keep_cr == base); + + String no_cr; + err = no_cr.parse_utf8(base.utf8().get_data(), -1, true); // Skip CR. + CHECK(err == OK); + CHECK(no_cr == base.replace("\r", "")); +} + TEST_CASE("[String] Invalid UTF8 (non-standard)") { ERR_PRINT_OFF static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0xF0, 0x82, 0x82, 0xAC, 0xED, 0xA0, 0x81, 0 }; @@ -683,7 +697,9 @@ TEST_CASE("[String] sprintf") { format = "fish %-05d frog"; args.clear(); args.push_back(-5); + ERR_PRINT_OFF; // Silence warning about 0 ignored. output = format.sprintf(args, &error); + ERR_PRINT_ON; REQUIRE(error == false); CHECK(output == String("fish -5 frog")); @@ -781,7 +797,9 @@ TEST_CASE("[String] sprintf") { format = "fish %-011f frog"; args.clear(); args.push_back(-99.99); + ERR_PRINT_OFF; // Silence warning about 0 ignored. output = format.sprintf(args, &error); + ERR_PRINT_ON; REQUIRE(error == false); CHECK(output == String("fish -99.990000 frog")); diff --git a/tests/core/templates/test_hash_set.h b/tests/core/templates/test_hash_set.h index 3b9a800641..dad149604b 100644 --- a/tests/core/templates/test_hash_set.h +++ b/tests/core/templates/test_hash_set.h @@ -38,7 +38,6 @@ namespace TestHashSet { TEST_CASE("[HashSet] Insert element") { - print_line("SMALL BEGIN MEM: ", Memory::get_mem_usage()); HashSet<int> set; HashSet<int>::Iterator e = set.insert(42); @@ -47,7 +46,6 @@ TEST_CASE("[HashSet] Insert element") { CHECK(set.has(42)); CHECK(set.find(42)); set.reset(); - print_line("SMALL END MEM: ", Memory::get_mem_usage()); } TEST_CASE("[HashSet] Insert existing element") { diff --git a/tests/core/templates/test_rid.h b/tests/core/templates/test_rid.h new file mode 100644 index 0000000000..8d4dd0703b --- /dev/null +++ b/tests/core/templates/test_rid.h @@ -0,0 +1,101 @@ +/*************************************************************************/ +/* test_rid.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_RID_H +#define TEST_RID_H + +#include "core/templates/rid.h" + +#include "tests/test_macros.h" + +namespace TestRID { +TEST_CASE("[RID] Default Constructor") { + RID rid; + + CHECK(rid.get_id() == 0); +} + +TEST_CASE("[RID] Factory method") { + RID rid = RID::from_uint64(1); + + CHECK(rid.get_id() == 1); +} + +TEST_CASE("[RID] Operators") { + RID rid = RID::from_uint64(1); + + RID rid_zero = RID::from_uint64(0); + RID rid_one = RID::from_uint64(1); + RID rid_two = RID::from_uint64(2); + + CHECK_FALSE(rid == rid_zero); + CHECK(rid == rid_one); + CHECK_FALSE(rid == rid_two); + + CHECK_FALSE(rid < rid_zero); + CHECK_FALSE(rid < rid_one); + CHECK(rid < rid_two); + + CHECK_FALSE(rid <= rid_zero); + CHECK(rid <= rid_one); + CHECK(rid <= rid_two); + + CHECK(rid > rid_zero); + CHECK_FALSE(rid > rid_one); + CHECK_FALSE(rid > rid_two); + + CHECK(rid >= rid_zero); + CHECK(rid >= rid_one); + CHECK_FALSE(rid >= rid_two); + + CHECK(rid != rid_zero); + CHECK_FALSE(rid != rid_one); + CHECK(rid != rid_two); +} + +TEST_CASE("[RID] 'is_valid' & 'is_null'") { + RID rid_zero = RID::from_uint64(0); + RID rid_one = RID::from_uint64(1); + + CHECK_FALSE(rid_zero.is_valid()); + CHECK(rid_zero.is_null()); + + CHECK(rid_one.is_valid()); + CHECK_FALSE(rid_one.is_null()); +} + +TEST_CASE("[RID] 'get_local_index'") { + CHECK(RID::from_uint64(1).get_local_index() == 1); + CHECK(RID::from_uint64(4'294'967'295).get_local_index() == 4'294'967'295); + CHECK(RID::from_uint64(4'294'967'297).get_local_index() == 1); +} +} // namespace TestRID + +#endif // TEST_RID_H diff --git a/tests/core/templates/test_vector.h b/tests/core/templates/test_vector.h index f27d6a332e..3fc9264f5a 100644 --- a/tests/core/templates/test_vector.h +++ b/tests/core/templates/test_vector.h @@ -291,8 +291,10 @@ TEST_CASE("[Vector] Slice") { CHECK(slice6[1] == 3); CHECK(slice6[2] == 4); + ERR_PRINT_OFF; Vector<int> slice7 = vector.slice(5, 1); - CHECK(slice7.size() == 0); + CHECK(slice7.size() == 0); // Expected to fail. + ERR_PRINT_ON; } TEST_CASE("[Vector] Find, has") { diff --git a/tests/data/line_endings_cr.test.txt b/tests/data/line_endings_cr.test.txt new file mode 100644 index 0000000000..556154bb25 --- /dev/null +++ b/tests/data/line_endings_cr.test.txt @@ -0,0 +1 @@ +Hello darkness
My old friend
I've come to talk
With you again
\ No newline at end of file diff --git a/tests/data/line_endings_crlf.test.txt b/tests/data/line_endings_crlf.test.txt new file mode 100644 index 0000000000..a3cbe55b7f --- /dev/null +++ b/tests/data/line_endings_crlf.test.txt @@ -0,0 +1,4 @@ +Hello darkness
+My old friend
+I've come to talk
+With you again
diff --git a/tests/data/line_endings_lf.test.txt b/tests/data/line_endings_lf.test.txt new file mode 100644 index 0000000000..0aabcd911e --- /dev/null +++ b/tests/data/line_endings_lf.test.txt @@ -0,0 +1,4 @@ +Hello darkness +My old friend +I've come to talk +With you again diff --git a/tests/scene/test_audio_stream_wav.h b/tests/scene/test_audio_stream_wav.h new file mode 100644 index 0000000000..92c524525c --- /dev/null +++ b/tests/scene/test_audio_stream_wav.h @@ -0,0 +1,243 @@ +/*************************************************************************/ +/* test_audio_stream_wav.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_AUDIO_STREAM_WAV_H +#define TEST_AUDIO_STREAM_WAV_H + +#include "core/math/math_defs.h" +#include "core/math/math_funcs.h" +#include "scene/resources/audio_stream_wav.h" + +#include "tests/test_macros.h" + +#ifdef TOOLS_ENABLED +#include "core/io/resource_loader.h" +#include "editor/import/resource_importer_wav.h" +#endif + +namespace TestAudioStreamWAV { + +// Default wav rate for test cases. +constexpr float WAV_RATE = 44100; +/* Default wav count for test cases. 1 second of audio is used so that the file can be listened +to manually if needed. */ +constexpr int WAV_COUNT = WAV_RATE; + +float gen_wav(float frequency, float wav_rate, int wav_number) { + // formula for generating a sin wave with given frequency. + return Math::sin((Math_TAU * frequency / wav_rate) * wav_number); +} + +/* Generates a 440Hz sin wave in channel 0 (mono channel or left stereo channel) + * and a 261.63Hz wave in channel 1 (right stereo channel). + * These waves correspond to the music notes A4 and C4 respectively. + */ +Vector<uint8_t> gen_pcm8_test(float wav_rate, int wav_count, bool stereo) { + Vector<uint8_t> buffer; + buffer.resize(stereo ? wav_count * 2 : wav_count); + + uint8_t *write_ptr = buffer.ptrw(); + for (int i = 0; i < buffer.size(); i++) { + float wav; + if (stereo) { + if (i % 2 == 0) { + wav = gen_wav(440, wav_rate, i / 2); + } else { + wav = gen_wav(261.63, wav_rate, i / 2); + } + } else { + wav = gen_wav(440, wav_rate, i); + } + + // Map sin wave to full range of 8-bit values. + uint8_t wav_8bit = Math::fast_ftoi(((wav + 1) / 2) * UINT8_MAX); + // Unlike the .wav format, AudioStreamWAV expects signed 8-bit wavs. + uint8_t wav_8bit_signed = wav_8bit - (INT8_MAX + 1); + write_ptr[i] = wav_8bit_signed; + } + + return buffer; +} + +// Same as gen_pcm8_test but with 16-bit wavs. +Vector<uint8_t> gen_pcm16_test(float wav_rate, int wav_count, bool stereo) { + Vector<uint8_t> buffer; + buffer.resize(stereo ? wav_count * 4 : wav_count * 2); + + uint8_t *write_ptr = buffer.ptrw(); + for (int i = 0; i < buffer.size() / 2; i++) { + float wav; + if (stereo) { + if (i % 2 == 0) { + wav = gen_wav(440, wav_rate, i / 2); + } else { + wav = gen_wav(261.63, wav_rate, i / 2); + } + } else { + wav = gen_wav(440, wav_rate, i); + } + + // Map sin wave to full range of 16-bit values. + uint16_t wav_16bit = Math::fast_ftoi(((wav + 1) / 2) * UINT16_MAX); + // The .wav format expects wavs larger than 8 bits to be signed. + uint16_t wav_16bit_signed = wav_16bit - (INT16_MAX + 1); + encode_uint16(wav_16bit_signed, write_ptr + (i * 2)); + } + + return buffer; +} + +void run_test(String file_name, AudioStreamWAV::Format data_format, bool stereo, float wav_rate, float wav_count) { + String save_path = OS::get_singleton()->get_cache_path().plus_file(file_name); + + Vector<uint8_t> test_data; + if (data_format == AudioStreamWAV::FORMAT_8_BITS) { + test_data = gen_pcm8_test(wav_rate, wav_count, stereo); + } else { + test_data = gen_pcm16_test(wav_rate, wav_count, stereo); + } + + Ref<AudioStreamWAV> stream = memnew(AudioStreamWAV); + stream->set_mix_rate(wav_rate); + CHECK(stream->get_mix_rate() == wav_rate); + + stream->set_format(data_format); + CHECK(stream->get_format() == data_format); + + stream->set_stereo(stereo); + CHECK(stream->is_stereo() == stereo); + + stream->set_data(test_data); + CHECK(stream->get_data() == test_data); + + SUBCASE("Stream length is computed properly") { + CHECK(Math::is_equal_approx(stream->get_length(), wav_count / wav_rate)); + } + + SUBCASE("Stream can be saved as .wav") { + REQUIRE(stream->save_to_wav(save_path) == OK); + + Error error; + Ref<FileAccess> wav_file = FileAccess::open(save_path, FileAccess::READ, &error); + REQUIRE(error == OK); + +#if TOOLS_ENABLED + // The WAV importer can be used if enabled to check that the saved file is valid. + Ref<ResourceImporterWAV> wav_importer = memnew(ResourceImporterWAV); + + List<ResourceImporter::ImportOption> options_list; + wav_importer->get_import_options("", &options_list); + + HashMap<StringName, Variant> options_map; + for (const ResourceImporter::ImportOption &E : options_list) { + options_map[E.option.name] = E.default_value; + } + + REQUIRE(wav_importer->import(save_path, save_path, options_map, nullptr) == OK); + + String load_path = save_path + "." + wav_importer->get_save_extension(); + Ref<AudioStreamWAV> loaded_stream = ResourceLoader::load(load_path, "AudioStreamWAV", ResourceFormatImporter::CACHE_MODE_IGNORE, &error); + REQUIRE(error == OK); + + CHECK(loaded_stream->get_format() == stream->get_format()); + CHECK(loaded_stream->get_loop_mode() == stream->get_loop_mode()); + CHECK(loaded_stream->get_loop_begin() == stream->get_loop_begin()); + CHECK(loaded_stream->get_loop_end() == stream->get_loop_end()); + CHECK(loaded_stream->get_mix_rate() == stream->get_mix_rate()); + CHECK(loaded_stream->is_stereo() == stream->is_stereo()); + CHECK(loaded_stream->get_length() == stream->get_length()); + CHECK(loaded_stream->is_monophonic() == stream->is_monophonic()); + CHECK(loaded_stream->get_data() == stream->get_data()); +#endif + } +} + +TEST_CASE("[AudioStreamWAV] Mono PCM8 format") { + run_test("test_pcm8_mono.wav", AudioStreamWAV::FORMAT_8_BITS, false, WAV_RATE, WAV_COUNT); +} + +TEST_CASE("[AudioStreamWAV] Mono PCM16 format") { + run_test("test_pcm16_mono.wav", AudioStreamWAV::FORMAT_16_BITS, false, WAV_RATE, WAV_COUNT); +} + +TEST_CASE("[AudioStreamWAV] Stereo PCM8 format") { + run_test("test_pcm8_stereo.wav", AudioStreamWAV::FORMAT_8_BITS, true, WAV_RATE, WAV_COUNT); +} + +TEST_CASE("[AudioStreamWAV] Stereo PCM16 format") { + run_test("test_pcm16_stereo.wav", AudioStreamWAV::FORMAT_16_BITS, true, WAV_RATE, WAV_COUNT); +} + +TEST_CASE("[AudioStreamWAV] Alternate mix rate") { + run_test("test_pcm16_stereo_38000Hz.wav", AudioStreamWAV::FORMAT_16_BITS, true, 38000, 38000); +} + +TEST_CASE("[AudioStreamWAV] save_to_wav() adds '.wav' file extension automatically") { + String save_path = OS::get_singleton()->get_cache_path().plus_file("test_wav_extension"); + Vector<uint8_t> test_data = gen_pcm8_test(WAV_RATE, WAV_COUNT, false); + Ref<AudioStreamWAV> stream = memnew(AudioStreamWAV); + stream->set_data(test_data); + + REQUIRE(stream->save_to_wav(save_path) == OK); + Error error; + Ref<FileAccess> wav_file = FileAccess::open(save_path + ".wav", FileAccess::READ, &error); + CHECK(error == OK); +} + +TEST_CASE("[AudioStreamWAV] Default values") { + Ref<AudioStreamWAV> stream = memnew(AudioStreamWAV); + CHECK(stream->get_format() == AudioStreamWAV::FORMAT_8_BITS); + CHECK(stream->get_loop_mode() == AudioStreamWAV::LOOP_DISABLED); + CHECK(stream->get_loop_begin() == 0); + CHECK(stream->get_loop_end() == 0); + CHECK(stream->get_mix_rate() == 44100); + CHECK(stream->is_stereo() == false); + CHECK(stream->get_length() == 0); + CHECK(stream->is_monophonic() == false); + CHECK(stream->get_data() == Vector<uint8_t>{}); + CHECK(stream->get_stream_name() == ""); +} + +TEST_CASE("[AudioStreamWAV] Save empty file") { + run_test("test_empty.wav", AudioStreamWAV::FORMAT_8_BITS, false, WAV_RATE, 0); +} + +TEST_CASE("[AudioStreamWAV] Saving IMA ADPCM is not supported") { + String save_path = OS::get_singleton()->get_cache_path().plus_file("test_adpcm.wav"); + Ref<AudioStreamWAV> stream = memnew(AudioStreamWAV); + stream->set_format(AudioStreamWAV::FORMAT_IMA_ADPCM); + ERR_PRINT_OFF; + CHECK(stream->save_to_wav(save_path) == ERR_UNAVAILABLE); + ERR_PRINT_ON; +} + +} // namespace TestAudioStreamWAV + +#endif // TEST_AUDIO_STREAM_WAV_H diff --git a/tests/scene/test_sprite_frames.h b/tests/scene/test_sprite_frames.h new file mode 100644 index 0000000000..61bbd16493 --- /dev/null +++ b/tests/scene/test_sprite_frames.h @@ -0,0 +1,247 @@ +/*************************************************************************/ +/* test_sprite_frames.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_SPRITE_FRAMES_H +#define TEST_SPRITE_FRAMES_H + +#include "scene/resources/sprite_frames.h" + +#include "tests/test_macros.h" + +namespace TestSpriteFrames { +const String test_animation_name = "GodotTest"; + +TEST_CASE("[SpriteFrames] Constructor methods") { + const SpriteFrames frames; + CHECK_MESSAGE( + frames.get_animation_names().size() == 1, + "Should be initialized with 1 entry."); + CHECK_MESSAGE( + frames.get_animation_names().get(0) == "default", + "Should be initialized with default entry."); +} + +TEST_CASE("[SpriteFrames] Animation addition, list getter, renaming, removal, and retrieval") { + SpriteFrames frames; + Vector<String> test_names = { "default", "2", "1", "3" }; + + // "default" is there already + frames.add_animation("2"); + frames.add_animation("1"); + frames.add_animation("3"); + + for (int i = 0; i < test_names.size(); i++) { + CHECK_MESSAGE( + frames.has_animation(test_names[i]), + "Add animation properly worked for each value"); + } + + CHECK_MESSAGE( + !frames.has_animation("999"), + "Return false when checking for animation that does not exist"); + + List<StringName> sname_list; + frames.get_animation_list(&sname_list); + + CHECK_MESSAGE( + sname_list.size() == test_names.size(), + "StringName List getter returned list of expected size"); + + for (int i = 0; i < test_names.size(); i++) { + CHECK_MESSAGE( + sname_list[i] == StringName(test_names[i]), + "StringName List getter returned expected values"); + } + + // get_animation_names() sorts the results. + Vector<String> string_vector = frames.get_animation_names(); + test_names.sort(); + + for (int i = 0; i < test_names.size(); i++) { + CHECK_MESSAGE( + string_vector[i] == test_names[i], + "String Vector getter returned expected values"); + } + + // These error handling cases should not crash. + ERR_PRINT_OFF; + frames.rename_animation("This does not exist", "0"); + ERR_PRINT_ON; + + CHECK_MESSAGE( + !frames.has_animation("0"), + "Correctly handles rename error when entry does not exist"); + + // These error handling cases should not crash. + ERR_PRINT_OFF; + frames.rename_animation("3", "1"); + ERR_PRINT_ON; + + CHECK_MESSAGE( + frames.has_animation("3"), + "Correctly handles rename error when entry exists, but new name already exists"); + + ERR_PRINT_OFF; + frames.add_animation("1"); + ERR_PRINT_ON; + + CHECK_MESSAGE( + frames.get_animation_names().size() == 4, + "Correctly does not add when entry already exists"); + + frames.rename_animation("3", "9"); + + CHECK_MESSAGE( + frames.has_animation("9"), + "Animation renamed correctly"); + + frames.remove_animation("9"); + + CHECK_MESSAGE( + !frames.has_animation("9"), + "Animation removed correctly"); + + frames.clear_all(); + + CHECK_MESSAGE( + frames.get_animation_names().size() == 1, + "Clear all removed all animations and re-added the default animation entry"); +} + +TEST_CASE("[SpriteFrames] Animation Speed getter and setter") { + SpriteFrames frames; + + frames.add_animation(test_animation_name); + + CHECK_MESSAGE( + frames.get_animation_speed(test_animation_name) == 5.0, + "Sets new animation to default speed"); + + frames.set_animation_speed(test_animation_name, 123.0004); + + CHECK_MESSAGE( + frames.get_animation_speed(test_animation_name) == 123.0004, + "Sets animation to positive double"); + + // These error handling cases should not crash. + ERR_PRINT_OFF; + frames.get_animation_speed("This does not exist"); + frames.set_animation_speed("This does not exist", 100); + frames.set_animation_speed(test_animation_name, -999.999); + ERR_PRINT_ON; + + CHECK_MESSAGE( + frames.get_animation_speed(test_animation_name) == 123.0004, + "Prevents speed of animation being set to a negative value"); + + frames.set_animation_speed(test_animation_name, 0.0); + + CHECK_MESSAGE( + frames.get_animation_speed(test_animation_name) == 0.0, + "Sets animation to zero"); +} + +TEST_CASE("[SpriteFrames] Animation Loop getter and setter") { + SpriteFrames frames; + + frames.add_animation(test_animation_name); + + CHECK_MESSAGE( + frames.get_animation_loop(test_animation_name), + "Sets new animation to default loop value."); + + frames.set_animation_loop(test_animation_name, true); + + CHECK_MESSAGE( + frames.get_animation_loop(test_animation_name), + "Sets animation loop to true"); + + frames.set_animation_loop(test_animation_name, false); + + CHECK_MESSAGE( + !frames.get_animation_loop(test_animation_name), + "Sets animation loop to false"); + + // These error handling cases should not crash. + ERR_PRINT_OFF; + frames.get_animation_loop("This does not exist"); + frames.set_animation_loop("This does not exist", false); + ERR_PRINT_ON; +} + +// TODO +TEST_CASE("[SpriteFrames] Frame addition, removal, and retrieval") { + Ref<Texture2D> dummy_frame1; + dummy_frame1.instantiate(); + + SpriteFrames frames; + frames.add_animation(test_animation_name); + frames.add_animation("1"); + frames.add_animation("2"); + + CHECK_MESSAGE( + frames.get_frame_count(test_animation_name) == 0, + "Animation has a default frame count of 0"); + + frames.add_frame(test_animation_name, dummy_frame1, 0); + frames.add_frame(test_animation_name, dummy_frame1, 1); + frames.add_frame(test_animation_name, dummy_frame1, 2); + + CHECK_MESSAGE( + frames.get_frame_count(test_animation_name) == 3, + "Adds multiple frames"); + + frames.remove_frame(test_animation_name, 1); + frames.remove_frame(test_animation_name, 0); + + CHECK_MESSAGE( + frames.get_frame_count(test_animation_name) == 1, + "Removes multiple frames"); + + // These error handling cases should not crash. + ERR_PRINT_OFF; + frames.add_frame("does not exist", dummy_frame1, 0); + frames.remove_frame(test_animation_name, -99); + frames.remove_frame("does not exist", 0); + ERR_PRINT_ON; + + CHECK_MESSAGE( + frames.get_frame_count(test_animation_name) == 1, + "Handles bad values when adding or removing frames."); + + frames.clear(test_animation_name); + + CHECK_MESSAGE( + frames.get_frame_count(test_animation_name) == 0, + "Clears frames."); +} +} // namespace TestSpriteFrames + +#endif // TEST_SPRITE_FRAMES_H diff --git a/tests/scene/test_theme.h b/tests/scene/test_theme.h index f7cfa0fd5b..f5b21eec32 100644 --- a/tests/scene/test_theme.h +++ b/tests/scene/test_theme.h @@ -101,18 +101,24 @@ TEST_CASE_FIXTURE(Fixture, "[Theme] Good theme type names") { SUBCASE("set_type_variation") { for (const StringName &name : names) { + if (name == StringName()) { // Skip empty here, not allowed. + continue; + } Ref<Theme> theme = memnew(Theme); ErrorDetector ed; theme->set_type_variation(valid_type_name, name); - CHECK(ed.has_error == (name == StringName())); + CHECK_FALSE(ed.has_error); } for (const StringName &name : names) { + if (name == StringName()) { // Skip empty here, not allowed. + continue; + } Ref<Theme> theme = memnew(Theme); ErrorDetector ed; theme->set_type_variation(name, valid_type_name); - CHECK(ed.has_error == (name == StringName())); + CHECK_FALSE(ed.has_error); } } } @@ -125,6 +131,8 @@ TEST_CASE_FIXTURE(Fixture, "[Theme] Bad theme type names") { String::utf8("contains_汉字"), }; + ERR_PRINT_OFF; // All these rightfully print errors. + SUBCASE("add_type") { for (const StringName &name : names) { Ref<Theme> theme = memnew(Theme); @@ -175,6 +183,8 @@ TEST_CASE_FIXTURE(Fixture, "[Theme] Bad theme type names") { CHECK(ed.has_error); } } + + ERR_PRINT_ON; } TEST_CASE_FIXTURE(Fixture, "[Theme] Good theme item names") { @@ -223,6 +233,8 @@ TEST_CASE_FIXTURE(Fixture, "[Theme] Bad theme item names") { String::utf8("contains_汉字"), }; + ERR_PRINT_OFF; // All these rightfully print errors. + SUBCASE("set_theme_item") { for (const StringName &name : names) { for (const DataEntry &entry : valid_data) { @@ -250,6 +262,8 @@ TEST_CASE_FIXTURE(Fixture, "[Theme] Bad theme item names") { } } } + + ERR_PRINT_ON; } } // namespace TestTheme diff --git a/tests/servers/test_text_server.h b/tests/servers/test_text_server.h index 61207216fc..9ebd0f34b4 100644 --- a/tests/servers/test_text_server.h +++ b/tests/servers/test_text_server.h @@ -39,12 +39,12 @@ namespace TestTextServer { -TEST_SUITE("[[TextServer]") { +TEST_SUITE("[TextServer]") { TEST_CASE("[TextServer] Init, font loading and shaping") { SUBCASE("[TextServer] Loading fonts") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC)) { continue; @@ -52,7 +52,7 @@ TEST_SUITE("[[TextServer]") { RID font = ts->create_font(); ts->font_set_data_ptr(font, _font_NotoSans_Regular, _font_NotoSans_Regular_size); - TEST_FAIL_COND(font == RID(), "Loading font failed."); + CHECK_FALSE_MESSAGE(font == RID(), "Loading font failed."); ts->free_rid(font); } } @@ -60,7 +60,7 @@ TEST_SUITE("[[TextServer]") { SUBCASE("[TextServer] Text layout: Font fallback") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -79,26 +79,26 @@ TEST_SUITE("[[TextServer]") { // 6^ 17^ RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size == 0, "Shaping failed"); + CHECK_FALSE_MESSAGE(gl_size == 0, "Shaping failed"); for (int j = 0; j < gl_size; j++) { if (glyphs[j].start < 6) { - TEST_FAIL_COND(glyphs[j].font_rid != font[1], "Incorrect font selected."); + CHECK_FALSE_MESSAGE(glyphs[j].font_rid != font[1], "Incorrect font selected."); } if ((glyphs[j].start > 6) && (glyphs[j].start < 16)) { - TEST_FAIL_COND(glyphs[j].font_rid != font[0], "Incorrect font selected."); + CHECK_FALSE_MESSAGE(glyphs[j].font_rid != font[0], "Incorrect font selected."); } if (glyphs[j].start > 16) { - TEST_FAIL_COND(glyphs[j].font_rid != RID(), "Incorrect font selected."); - TEST_FAIL_COND(glyphs[j].index != test[glyphs[j].start], "Incorrect glyph index."); + CHECK_FALSE_MESSAGE(glyphs[j].font_rid != RID(), "Incorrect font selected."); + CHECK_FALSE_MESSAGE(glyphs[j].index != test[glyphs[j].start], "Incorrect glyph index."); } - TEST_FAIL_COND((glyphs[j].start < 0 || glyphs[j].end > test.length()), "Incorrect glyph range."); - TEST_FAIL_COND(glyphs[j].font_size != 16, "Incorrect glyph font size."); + CHECK_FALSE_MESSAGE((glyphs[j].start < 0 || glyphs[j].end > test.length()), "Incorrect glyph range."); + CHECK_FALSE_MESSAGE(glyphs[j].font_size != 16, "Incorrect glyph font size."); } ts->free_rid(ctx); @@ -113,7 +113,7 @@ TEST_SUITE("[[TextServer]") { SUBCASE("[TextServer] Text layout: BiDi") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_BIDI_LAYOUT)) { continue; @@ -132,23 +132,23 @@ TEST_SUITE("[[TextServer]") { // 7^ 26^ RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size == 0, "Shaping failed"); + CHECK_FALSE_MESSAGE(gl_size == 0, "Shaping failed"); for (int j = 0; j < gl_size; j++) { if (glyphs[j].count > 0) { if (glyphs[j].start < 7) { - TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); + CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); } if ((glyphs[j].start > 8) && (glyphs[j].start < 23)) { - TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) != TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); + CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) != TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); } if (glyphs[j].start > 26) { - TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); + CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); } } } @@ -165,7 +165,7 @@ TEST_SUITE("[[TextServer]") { SUBCASE("[TextServer] Text layout: Line break and align points") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -186,16 +186,16 @@ TEST_SUITE("[[TextServer]") { { String test = U"Test test long text long text\n"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); ts->shaped_text_update_justification_ops(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 30, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 30, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -203,11 +203,11 @@ TEST_SUITE("[[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 4 || j == 9 || j == 14 || j == 19 || j == 24) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else if (j == 29) { - TEST_FAIL_COND((soft || !space || !hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || !space || !hard || virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } ts->free_rid(ctx); @@ -216,21 +216,63 @@ TEST_SUITE("[[TextServer]") { { String test = U"الحمـد"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 6, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { + ts->shaped_text_update_justification_ops(ctx); + + glyphs = ts->shaped_text_get_glyphs(ctx); + gl_size = ts->shaped_text_get_glyph_count(ctx); + + CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + if (j == 1) { + CHECK_FALSE_MESSAGE((soft || space || hard || virt || !elo), "Invalid glyph flags."); + } else { + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + } + } + ts->free_rid(ctx); + } + + { + String test = U"الحمد"; + RID ctx = ts->create_shaped_text(); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); + bool ok = ts->shaped_text_add_string(ctx, test, font, 16); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); + ts->shaped_text_update_breaks(ctx); + + const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); + int gl_size = ts->shaped_text_get_glyph_count(ctx); + CHECK_FALSE_MESSAGE(gl_size != 5, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { @@ -239,7 +281,7 @@ TEST_SUITE("[[TextServer]") { glyphs = ts->shaped_text_get_glyphs(ctx); gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 6, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -247,9 +289,9 @@ TEST_SUITE("[[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 1) { - TEST_FAIL_COND((soft || space || hard || virt || !elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || !virt || !elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } } @@ -259,15 +301,15 @@ TEST_SUITE("[[TextServer]") { { String test = U"الحمـد الرياضي العربي"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 21, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 21, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -275,9 +317,9 @@ TEST_SUITE("[[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 6 || j == 14) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } @@ -287,7 +329,7 @@ TEST_SUITE("[[TextServer]") { glyphs = ts->shaped_text_get_glyphs(ctx); gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 23, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 23, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -295,13 +337,13 @@ TEST_SUITE("[[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 7 || j == 16) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else if (j == 3 || j == 9) { - TEST_FAIL_COND((soft || space || hard || !virt || !elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || !virt || !elo), "Invalid glyph flags."); } else if (j == 18) { - TEST_FAIL_COND((soft || space || hard || virt || !elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || !elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } } @@ -312,16 +354,16 @@ TEST_SUITE("[[TextServer]") { { String test = U"เป็น ภาษา ราชการ และ ภาษา"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); ts->shaped_text_update_justification_ops(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 25, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 25, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -329,9 +371,9 @@ TEST_SUITE("[[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 4 || j == 9 || j == 16 || j == 20) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } ts->free_rid(ctx); @@ -340,16 +382,16 @@ TEST_SUITE("[[TextServer]") { if (ts->has_feature(TextServer::FEATURE_BREAK_ITERATORS)) { String test = U"เป็นภาษาราชการและภาษา"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); ts->shaped_text_update_justification_ops(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 25, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 25, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -357,9 +399,9 @@ TEST_SUITE("[[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 4 || j == 9 || j == 16 || j == 20) { - TEST_FAIL_COND((!soft || !space || hard || !virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || !virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } ts->free_rid(ctx); @@ -375,7 +417,7 @@ TEST_SUITE("[[TextServer]") { SUBCASE("[TextServer] Text layout: Line breaking") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -394,21 +436,21 @@ TEST_SUITE("[[TextServer]") { font.push_back(font2); RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test_1, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); PackedInt32Array brks = ts->shaped_text_get_line_breaks(ctx, 1); - TEST_FAIL_COND(brks.size() != 6, "Invalid line breaks number."); + CHECK_FALSE_MESSAGE(brks.size() != 6, "Invalid line breaks number."); if (brks.size() == 6) { - TEST_FAIL_COND(brks[0] != 0, "Invalid line break position."); - TEST_FAIL_COND(brks[1] != 5, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[0] != 0, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[1] != 5, "Invalid line break position."); - TEST_FAIL_COND(brks[2] != 5, "Invalid line break position."); - TEST_FAIL_COND(brks[3] != 10, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[2] != 5, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[3] != 10, "Invalid line break position."); - TEST_FAIL_COND(brks[4] != 10, "Invalid line break position."); - TEST_FAIL_COND(brks[5] != 14, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[4] != 10, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[5] != 14, "Invalid line break position."); } ts->free_rid(ctx); @@ -423,7 +465,7 @@ TEST_SUITE("[[TextServer]") { SUBCASE("[TextServer] Text layout: Justification") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -448,40 +490,40 @@ TEST_SUITE("[[TextServer]") { float width_old, width; if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); ok = ts->shaped_text_add_string(ctx, test_1, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); width_old = ts->shaped_text_get_width(ctx); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND); - TEST_FAIL_COND((width != width_old), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width != width_old), "Invalid fill width."); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); ts->free_rid(ctx); ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); ok = ts->shaped_text_add_string(ctx, test_2, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); width_old = ts->shaped_text_get_width(ctx); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); ts->free_rid(ctx); } ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); ok = ts->shaped_text_add_string(ctx, test_3, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); width_old = ts->shaped_text_get_width(ctx); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); ts->free_rid(ctx); @@ -492,10 +534,31 @@ TEST_SUITE("[[TextServer]") { } } + SUBCASE("[TextServer] Unicode identifiers") { + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); + + static const char32_t *data[19] = { U"-30", U"100", U"10.1", U"10,1", U"1e2", U"1e-2", U"1e2e3", U"0xAB", U"AB", U"Test1", U"1Test", U"Test*1", U"test_testeT", U"test_tes teT", U"عَلَيْكُمْ", U"عَلَيْكُمْTest", U"ӒӖӚӜ", U"_test", U"ÂÃÄÅĀĂĄÇĆĈĊ" }; + static bool isid[19] = { false, false, false, false, false, false, false, false, true, true, false, false, true, false, true, true, true, true, true }; + for (int j = 0; j < 19; j++) { + String s = String(data[j]); + CHECK(ts->is_valid_identifier(s) == isid[j]); + } + + if (ts->has_feature(TextServer::FEATURE_UNICODE_IDENTIFIERS)) { + // Test UAX 3.2 ZW(N)J usage. + CHECK(ts->is_valid_identifier(U"\u0646\u0627\u0645\u0647\u200C\u0627\u06CC")); + CHECK(ts->is_valid_identifier(U"\u0D26\u0D43\u0D15\u0D4D\u200C\u0D38\u0D3E\u0D15\u0D4D\u0D37\u0D3F")); + CHECK(ts->is_valid_identifier(U"\u0DC1\u0DCA\u200D\u0DBB\u0DD3")); + } + } + } + SUBCASE("[TextServer] Strip Diacritics") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (ts->has_feature(TextServer::FEATURE_SHAPING)) { CHECK(ts->strip_diacritics(U"ٱلسَّلَامُ عَلَيْكُمْ") == U"ٱلسلام عليكم"); @@ -523,7 +586,7 @@ TEST_SUITE("[[TextServer]") { continue; } - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); { String text1 = U"linguistically similar and effectively form"; // 14^ 22^ 26^ 38^ diff --git a/tests/test_macros.h b/tests/test_macros.h index 6029a9cfc7..69ae0d3124 100644 --- a/tests/test_macros.h +++ b/tests/test_macros.h @@ -31,6 +31,7 @@ #ifndef TEST_MACROS_H #define TEST_MACROS_H +#include "core/core_globals.h" #include "core/input/input_map.h" #include "core/object/message_queue.h" #include "core/variant/variant.h" @@ -53,12 +54,12 @@ // Temporarily disable error prints to test failure paths. // This allows to avoid polluting the test summary with error messages. -// The `_print_error_enabled` boolean is defined in `core/print_string.cpp` and +// The `print_error_enabled` boolean is defined in `core/core_globals.cpp` and // works at global scope. It's used by various loggers in `should_log()` method, // which are used by error macros which call into `OS::print_error`, effectively // disabling any error messages to be printed from the engine side (not tests). -#define ERR_PRINT_OFF _print_error_enabled = false; -#define ERR_PRINT_ON _print_error_enabled = true; +#define ERR_PRINT_OFF CoreGlobals::print_error_enabled = false; +#define ERR_PRINT_ON CoreGlobals::print_error_enabled = true; // Stringify all `Variant` compatible types for doctest output by default. // https://github.com/onqtam/doctest/blob/master/doc/markdown/stringification.md @@ -199,8 +200,8 @@ int register_test_command(String p_command, TestFunc p_function); // We toggle _print_error_enabled to prevent display server not supported warnings. #define SEND_GUI_MOUSE_MOTION_EVENT(m_object, m_local_pos, m_mask, m_modifers) \ { \ - bool errors_enabled = _print_error_enabled; \ - _print_error_enabled = false; \ + bool errors_enabled = CoreGlobals::print_error_enabled; \ + CoreGlobals::print_error_enabled = false; \ Ref<InputEventMouseMotion> event; \ event.instantiate(); \ event->set_position(m_local_pos); \ @@ -209,7 +210,7 @@ int register_test_command(String p_command, TestFunc p_function); _UPDATE_EVENT_MODIFERS(event, m_modifers); \ m_object->get_viewport()->push_input(event); \ MessageQueue::get_singleton()->flush(); \ - _print_error_enabled = errors_enabled; \ + CoreGlobals::print_error_enabled = errors_enabled; \ } // Utility class / macros for testing signals @@ -271,22 +272,20 @@ public: static SignalWatcher *get_singleton() { return singleton; } void watch_signal(Object *p_object, const String &p_signal) { - Vector<Variant> args; - args.push_back(p_signal); MethodInfo method_info; ClassDB::get_signal(p_object->get_class(), p_signal, &method_info); switch (method_info.arguments.size()) { case 0: { - p_object->connect(p_signal, callable_mp(this, &SignalWatcher::_signal_callback_zero), args); + p_object->connect(p_signal, callable_mp(this, &SignalWatcher::_signal_callback_zero).bind(p_signal)); } break; case 1: { - p_object->connect(p_signal, callable_mp(this, &SignalWatcher::_signal_callback_one), args); + p_object->connect(p_signal, callable_mp(this, &SignalWatcher::_signal_callback_one).bind(p_signal)); } break; case 2: { - p_object->connect(p_signal, callable_mp(this, &SignalWatcher::_signal_callback_two), args); + p_object->connect(p_signal, callable_mp(this, &SignalWatcher::_signal_callback_two).bind(p_signal)); } break; case 3: { - p_object->connect(p_signal, callable_mp(this, &SignalWatcher::_signal_callback_three), args); + p_object->connect(p_signal, callable_mp(this, &SignalWatcher::_signal_callback_three).bind(p_signal)); } break; default: { MESSAGE("Signal ", p_signal, " arg count not supported."); diff --git a/tests/test_main.cpp b/tests/test_main.cpp index e71f2edba3..3d186711cb 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -30,6 +30,8 @@ #include "test_main.h" +#include "tests/core/input/test_input_event_key.h" +#include "tests/core/input/test_shortcut.h" #include "tests/core/io/test_config_file.h" #include "tests/core/io/test_file_access.h" #include "tests/core/io/test_image.h" @@ -46,16 +48,22 @@ #include "tests/core/math/test_geometry_2d.h" #include "tests/core/math/test_geometry_3d.h" #include "tests/core/math/test_plane.h" +#include "tests/core/math/test_quaternion.h" #include "tests/core/math/test_random_number_generator.h" #include "tests/core/math/test_rect2.h" #include "tests/core/math/test_rect2i.h" +#include "tests/core/math/test_transform_2d.h" +#include "tests/core/math/test_transform_3d.h" #include "tests/core/math/test_vector2.h" #include "tests/core/math/test_vector2i.h" #include "tests/core/math/test_vector3.h" #include "tests/core/math/test_vector3i.h" +#include "tests/core/math/test_vector4.h" +#include "tests/core/math/test_vector4i.h" #include "tests/core/object/test_class_db.h" #include "tests/core/object/test_method_bind.h" #include "tests/core/object/test_object.h" +#include "tests/core/os/test_os.h" #include "tests/core/string/test_node_path.h" #include "tests/core/string/test_string.h" #include "tests/core/string/test_translation.h" @@ -66,6 +74,7 @@ #include "tests/core/templates/test_local_vector.h" #include "tests/core/templates/test_lru.h" #include "tests/core/templates/test_paged_array.h" +#include "tests/core/templates/test_rid.h" #include "tests/core/templates/test_vector.h" #include "tests/core/test_crypto.h" #include "tests/core/test_hashing_context.h" @@ -75,10 +84,12 @@ #include "tests/core/variant/test_dictionary.h" #include "tests/core/variant/test_variant.h" #include "tests/scene/test_animation.h" +#include "tests/scene/test_audio_stream_wav.h" #include "tests/scene/test_code_edit.h" #include "tests/scene/test_curve.h" #include "tests/scene/test_gradient.h" #include "tests/scene/test_path_3d.h" +#include "tests/scene/test_sprite_frames.h" #include "tests/scene/test_text_edit.h" #include "tests/scene/test_theme.h" #include "tests/servers/test_text_server.h" @@ -104,7 +115,7 @@ int test_main(int argc, char *argv[]) { for (int i = 0; i < argc; i++) { args.push_back(String::utf8(argv[i])); } - OS::get_singleton()->set_cmdline("", args); + OS::get_singleton()->set_cmdline("", args, List<String>()); // Run custom test tools. if (test_commands) { @@ -212,6 +223,15 @@ struct GodotTestCaseListener : public doctest::IReporter { SceneTree::get_singleton()->initialize(); return; } + + if (name.find("Audio") != -1) { + // The last driver index should always be the dummy driver. + int dummy_idx = AudioDriverManager::get_driver_count() - 1; + AudioDriverManager::initialize(dummy_idx); + AudioServer *audio_server = memnew(AudioServer); + audio_server->init(); + return; + } } void test_case_end(const doctest::CurrentTestCaseStats &) override { @@ -257,7 +277,7 @@ struct GodotTestCaseListener : public doctest::IReporter { if (RenderingServer::get_singleton()) { RenderingServer::get_singleton()->sync(); - RenderingServer::get_singleton()->global_variables_clear(); + RenderingServer::get_singleton()->global_shader_uniforms_clear(); RenderingServer::get_singleton()->finish(); memdelete(RenderingServer::get_singleton()); } @@ -274,6 +294,11 @@ struct GodotTestCaseListener : public doctest::IReporter { MessageQueue::get_singleton()->flush(); memdelete(MessageQueue::get_singleton()); } + + if (AudioServer::get_singleton()) { + AudioServer::get_singleton()->finish(); + memdelete(AudioServer::get_singleton()); + } } void test_run_start() override { diff --git a/tests/test_validate_testing.h b/tests/test_validate_testing.h index 413a7e351d..1471a952cd 100644 --- a/tests/test_validate_testing.h +++ b/tests/test_validate_testing.h @@ -31,6 +31,7 @@ #ifndef TEST_VALIDATE_TESTING_H #define TEST_VALIDATE_TESTING_H +#include "core/core_globals.h" #include "core/os/os.h" #include "tests/test_macros.h" @@ -49,10 +50,10 @@ TEST_SUITE("Validate tests") { } TEST_CASE("Muting Godot error messages") { ERR_PRINT_OFF; - CHECK_MESSAGE(!_print_error_enabled, "Error printing should be disabled."); + CHECK_MESSAGE(!CoreGlobals::print_error_enabled, "Error printing should be disabled."); ERR_PRINT("Still waiting for Godot!"); // This should never get printed! ERR_PRINT_ON; - CHECK_MESSAGE(_print_error_enabled, "Error printing should be re-enabled."); + CHECK_MESSAGE(CoreGlobals::print_error_enabled, "Error printing should be re-enabled."); } TEST_CASE("Stringify Variant types") { Variant var; diff --git a/thirdparty/README.md b/thirdparty/README.md index b06d9cec81..664401fca6 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -44,7 +44,7 @@ Files extracted from upstream source: ## certs - Upstream: Mozilla, via https://github.com/bagder/ca-bundle -- Version: git (8b263a18fca98ea371e54227837321c5cdaa1ba7, 2021) +- Version: git (7f33e7eb8472dbcf31fdcf50cd216c89a282825d, 2022) - License: MPL 2.0 @@ -213,7 +213,7 @@ Files extracted from upstream source: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 5.0.1 (cbccadba8d1e51d6cc03a891b7c3a17f598e774c, 2022) +- Version: 5.1.0 (f1f2be776bcd994fa9262622e1a7098a066e5cf7, 2022) - License: MIT Files extracted from upstream source: @@ -231,6 +231,8 @@ Files extracted from upstream source: Files extracted from upstream source: - the `common` folder +- `scriptset.*`, `ucln_in.*`, `uspoof.cpp"` and `uspoof_impl.cpp` from the `i18n` folder +- `uspoof.h` from the `i18n/unicode` folder - `LICENSE` Files generated from upstream source: @@ -597,7 +599,7 @@ Godot. See the patch in the `patches` folder for details. ## spirv-reflect - Upstream: https://github.com/KhronosGroup/SPIRV-Reflect -- Version: git (1aceb6af56e74b92a00378842dda5c5a73f49a4b, 2022) +- Version: git (1ef99b09fa7ce5aee2c5cf70c61a4f7458d27e09, 2022) - License: Apache 2.0 Does not track Vulkan SDK releases closely, but try to package a commit newer diff --git a/thirdparty/certs/ca-certificates.crt b/thirdparty/certs/ca-certificates.crt index e218b024d0..036f630d5b 100644 --- a/thirdparty/certs/ca-certificates.crt +++ b/thirdparty/certs/ca-certificates.crt @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Thu Mar 31 08:10:21 2022 GMT +## Certificate data from Mozilla as of: Tue Jul 19 14:20:01 2022 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: d59c5c83ce7a7635fa95521d8d245677949b86d5574bfcc6f855b6a48f2d5566 +## SHA256: 9bf3799611fb58197f61d45e71ce3dc19f30e7dd73731915872ce5108a7bb066 ## @@ -993,30 +993,6 @@ tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- -Hellenic Academic and Research Institutions RootCA 2011 -======================================================= ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT -O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y -aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z -IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT -AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z -IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo -IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI -1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa -71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u -8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH -3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ -MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 -MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu -b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt -XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD -/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N -7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 ------END CERTIFICATE----- - Actalis Authentication Root CA ============================== -----BEGIN CERTIFICATE----- @@ -3279,3 +3255,206 @@ PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/C r8deVl5c1RxYIigL9zC2L7F8AjEA8GE8p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh 4rsUecrNIdSUtUlD -----END CERTIFICATE----- + +Telia Root CA v2 +================ +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQxCzAJBgNVBAYT +AkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2 +MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQK +DBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ7 +6zBqAMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9vVYiQJ3q +9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9lRdU2HhE8Qx3FZLgmEKn +pNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTODn3WhUidhOPFZPY5Q4L15POdslv5e2QJl +tI5c0BE0312/UqeBAMN/mUWZFdUXyApT7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW +5olWK8jjfN7j/4nlNW4o6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNr +RBH0pUPCTEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6WT0E +BXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63RDolUK5X6wK0dmBR4 +M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZIpEYslOqodmJHixBTB0hXbOKSTbau +BcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGjYzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7W +xy+G2CQ5MB0GA1UdDgQWBBRyrOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi0f6X+J8wfBj5 +tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMMA8iZGok1GTzTyVR8qPAs5m4H +eW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBSSRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+C +y748fdHif64W1lZYudogsYMVoe+KTTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygC +QMez2P2ccGrGKMOF6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15 +h2Er3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMtTy3EHD70 +sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pTVmBds9hCG1xLEooc6+t9 +xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAWysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQ +raVplI/owd8k+BsHMYeB2F326CjYSlKArBPuUBQemMc= +-----END CERTIFICATE----- + +D-TRUST BR Root CA 1 2020 +========================= +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE +RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJvb3QgQ0EgMSAy +MDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNV +BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7 +dPYSzuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0QVK5buXu +QqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/VbNafAkl1bK6CKBrqx9t +MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu +bmV0L2NybC9kLXRydXN0X2JyX3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP +PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD +AwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFWwKrY7RjEsK70Pvom +AjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHVdWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +D-TRUST EV Root CA 1 2020 +========================= +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE +RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJvb3QgQ0EgMSAy +MDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNV +BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8 +ZRCC/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rDwpdhQntJ +raOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3OqQo5FD4pPfsazK2/umL +MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu +bmV0L2NybC9kLXRydXN0X2V2X3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP +PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD +AwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CAy/m0sRtW9XLS/BnR +AjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJbgfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +DigiCert TLS ECC P384 Root G5 +============================= +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURpZ2lDZXJ0IFRMUyBFQ0MgUDM4 +NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQg +Um9vdCBHNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1Tzvd +lHJS7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp0zVozptj +n4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICISB4CIfBFqMA4GA1UdDwEB +/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQCJao1H5+z8blUD2Wds +Jk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQLgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIx +AJSdYsiJvRmEFOml+wG4DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +DigiCert TLS RSA4096 Root G5 +============================ +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBNMQswCQYDVQQG +EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0 +MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2 +IFJvb3QgRzUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS8 +7IE+ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG02C+JFvuU +AT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgpwgscONyfMXdcvyej/Ces +tyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZMpG2T6T867jp8nVid9E6P/DsjyG244gXa +zOvswzH016cpVIDPRFtMbzCe88zdH5RDnU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnV +DdXifBBiqmvwPXbzP6PosMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9q +TXeXAaDxZre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cdLvvy +z6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvXKyY//SovcfXWJL5/ +MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNeXoVPzthwiHvOAbWWl9fNff2C+MIk +wcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPLtgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4E +FgQUUTMc7TZArxfTJc1paPKvTiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7HPNtQOa27PShN +lnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLFO4uJ+DQtpBflF+aZfTCIITfN +MBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQREtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/ +u4cnYiWB39yhL/btp/96j1EuMPikAdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9G +OUrYU9DzLjtxpdRv/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh +47a+p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilwMUc/dNAU +FvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WFqUITVuwhd4GTWgzqltlJ +yqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCKovfepEWFJqgejF0pW8hL2JpqA15w8oVP +bEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +Certainly Root R1 +================= +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAwPTELMAkGA1UE +BhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2VydGFpbmx5IFJvb3QgUjEwHhcN +MjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2Vy +dGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBANA21B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O +5MQTvqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbedaFySpvXl +8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b01C7jcvk2xusVtyWMOvwl +DbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGI +XsXwClTNSaa/ApzSRKft43jvRl5tcdF5cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkN +KPl6I7ENPT2a/Z2B7yyQwHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQ +AjeZjOVJ6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA2Cnb +rlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyHWyf5QBGenDPBt+U1 +VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMReiFPCyEQtkA6qyI6BJyLm4SGcprS +p6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTgqj8ljZ9EXME66C6ud0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAsz +HQNTVfSVcOQrPbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi1wrykXprOQ4v +MMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrdrRT90+7iIgXr0PK3aBLXWopB +GsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9ditaY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+ +gjwN/KUD+nsa2UUeYNrEjvn8K8l7lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgH +JBu6haEaBQmAupVjyTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7 +fpYnKx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLyyCwzk5Iw +x06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5nwXARPbv0+Em34yaXOp/S +X3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +Certainly Root E1 +================= +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQswCQYDVQQGEwJV +UzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBFMTAeFw0yMTA0 +MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlu +bHkxGjAYBgNVBAMTEUNlcnRhaW5seSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4 +fxzf7flHh4axpMCK+IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9 +YBk2QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4hevIIgcwCgYIKoZIzj0E +AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8 +rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +E-Tugra Global Root CA RSA v3 +============================= +-----BEGIN CERTIFICATE----- +MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQELBQAwgYAxCzAJ +BgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAb +BgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290 +IENBIFJTQSB2MzAeFw0yMDAzMTgwOTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJU +UjEPMA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRF +LVR1Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBSU0Eg +djMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J77gnJY9LTQ91ew6aEOErx +jYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscxuj7X/iWpKo429NEvx7epXTPcMHD4QGxL +sqYxYdE0PD0xesevxKenhOGXpOhL9hd87jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF +/YP9f4RtNGx/ardLAQO/rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8q +QedmCeFLl+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bGwzrw +bMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4znKS4iicvObpCdg6 +04nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBOM/J+JjKsBY04pOZ2PJ8QaQ5tndLB +eSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiM +bIedBi3x7+PmBvrFZhNb/FAHnnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbg +h3cXTJ2w2AmoDVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSytK7mLfcm1ap1 +LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAImocn+M684uGMQQ +gC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN4 +38o2Fi+CiJ+8EUdPdk3ILY7r3y18Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/q +ln0F7psTpURs+APQ3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3s +SdPkvmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn99t2HVhjY +sCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQmhty3QUBjYZgv6Rn7rWl +DdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YAVSgU7NbHEqIbZULpkejLPoeJVF3Zr52X +nGnnCv8PWniLYypMfUeUP95L6VPQMPHF9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFH +IK+WEj5jlB0E5y67hscMmoi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiX +YY60MGo8bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ +-----END CERTIFICATE----- + +E-Tugra Global Root CA ECC v3 +============================= +-----BEGIN CERTIFICATE----- +MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAbBgNV +BAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENB +IEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEP +MA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 +Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBFQ0MgdjMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQKczLWYHMjLiSF4mDKpL2 +w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YKfWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31 +Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQ +zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO +PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W +Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 +-----END CERTIFICATE----- diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh index 7c34bb3c93..7f58fac8b8 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -140,6 +140,13 @@ struct CursivePosFormat1 unsigned int i = skippy_iter.idx; unsigned int j = buffer->idx; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "cursive attaching glyph at %d to glyph at %d", + i, j); + } + buffer->unsafe_to_break (i, j + 1); float entry_x, entry_y, exit_x, exit_y; (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y); @@ -231,6 +238,13 @@ struct CursivePosFormat1 pos[parent].x_offset = 0; } + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "cursive attached glyph at %d to glyph at %d", + i, j); + } + buffer->idx++; return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh index f8cddd1991..cb5e8b2689 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh @@ -39,6 +39,13 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y); glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "attaching mark glyph at %d to glyph at %d", + c->buffer->idx, glyph_pos); + } + hb_glyph_position_t &o = buffer->cur_pos(); o.x_offset = roundf (base_x - mark_x); o.y_offset = roundf (base_y - mark_y); @@ -46,6 +53,13 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove o.attach_chain() = (int) glyph_pos - (int) buffer->idx; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "attached mark glyph at %d to glyph at %d", + c->buffer->idx, glyph_pos); + } + buffer->idx++; return_trace (true); } @@ -83,10 +97,11 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove } }; -static void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage, - const MarkArray &mark_array, - const hb_set_t &glyphset, - hb_map_t* klass_mapping /* INOUT */) +HB_INTERNAL inline +void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage, + const MarkArray &mark_array, + const hb_set_t &glyphset, + hb_map_t* klass_mapping /* INOUT */) { hb_set_t orig_classes; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh index f58bcb1b30..a80fe0c226 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -217,10 +217,23 @@ struct PairPosFormat2_4 } bail: + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerning glyphs at %d,%d", + c->buffer->idx, skippy_iter.idx); + } applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos()); applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerned glyphs at %d,%d", + c->buffer->idx, skippy_iter.idx); + } + success: if (applied_first || applied_second) buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh index 58ba4de6c1..4578fbd1d6 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh @@ -109,12 +109,28 @@ struct PairSet record_size); if (record) { + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerning glyphs at %d,%d", + c->buffer->idx, pos); + } + bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "kerned glyphs at %d,%d", + c->buffer->idx, pos); + } + if (applied_first || applied_second) buffer->unsafe_to_break (buffer->idx, pos + 1); if (len2) pos++; + buffer->idx = pos; return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh index 55de5abebf..bd95abde16 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh @@ -1,6 +1,8 @@ #ifndef OT_LAYOUT_GPOS_PAIRVALUERECORD_HH #define OT_LAYOUT_GPOS_PAIRVALUERECORD_HH +#include "ValueFormat.hh" + namespace OT { namespace Layout { namespace GPOS_impl { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh index c0e7d29cea..7cbdf6dc6c 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -39,12 +39,10 @@ struct SinglePosFormat1 { if (!valueFormat.has_device ()) return; - auto it = - + hb_iter (this+coverage) - | hb_filter (c->glyph_set) - ; + hb_set_t intersection; + (this+coverage).intersect_set (*c->glyph_set, intersection); + if (!intersection) return; - if (!it) return; valueFormat.collect_variation_indices (c, this, values.as_array (valueFormat.get_len ())); } @@ -62,8 +60,22 @@ struct SinglePosFormat1 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioning glyph at %d", + c->buffer->idx); + } + valueFormat.apply_value (c, this, values, buffer->cur_pos()); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioned glyph at %d", + c->buffer->idx); + } + buffer->idx++; return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh index 0d038b4422..518fa9dcb0 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh @@ -70,10 +70,24 @@ struct SinglePosFormat2 if (likely (index >= valueCount)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioning glyph at %d", + c->buffer->idx); + } + valueFormat.apply_value (c, this, &values[index * valueFormat.get_len ()], buffer->cur_pos()); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "positioned glyph at %d", + c->buffer->idx); + } + buffer->idx++; return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh index a5dcb65359..4a9e9672eb 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh @@ -57,8 +57,23 @@ struct AlternateSet if (unlikely (alt_index > count || alt_index == 0)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %d (alternate substitution)", + c->buffer->idx); + } + c->replace_glyph (alternates[alt_index - 1]); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (alternate substitution)", + c->buffer->idx - 1); + } + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh index 22ed65f858..f373d921b5 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh @@ -64,7 +64,24 @@ struct Ligature * as a "ligated" substitution. */ if (unlikely (count == 1)) { + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %d (ligature substitution)", + c->buffer->idx); + } + c->replace_glyph (ligGlyph); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (ligature substitution)", + c->buffer->idx - 1); + } + return_trace (true); } @@ -85,6 +102,31 @@ struct Ligature return_trace (false); } + unsigned pos = 0; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + unsigned delta = c->buffer->sync_so_far (); + + pos = c->buffer->idx; + + char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0}; + char *p = buf; + + match_end += delta; + for (unsigned i = 0; i < count; i++) + { + match_positions[i] += delta; + if (i) + *p++ = ','; + sprintf (p, "%u", match_positions[i]); + p += strlen(p); + } + + c->buffer->message (c->font, + "ligating glyphs at %s", + buf); + } + ligate_input (c, count, match_positions, @@ -92,6 +134,14 @@ struct Ligature ligGlyph, total_component_count); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "ligated glyph at %d", + pos); + } + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index 1d27df95dd..a23e92028e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -131,7 +131,23 @@ struct ReverseChainSingleSubstFormat1 c->buffer->idx + 1, &end_index)) { c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replacing glyph at %d (reverse chaining substitution)", + c->buffer->idx); + } + c->replace_glyph_inplace (substitute[index]); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (reverse chaining substitution)", + c->buffer->idx); + } + /* Note: We DON'T decrease buffer->idx. The main loop does it * for us. This is useful for preventing surprises if someone * calls us through a Context lookup. */ diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh index c5cd15bb23..3d84a5e6ea 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh @@ -40,17 +40,58 @@ struct Sequence * as a "multiplied" substitution. */ if (unlikely (count == 1)) { + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %d (multiple substitution)", + c->buffer->idx); + } + c->replace_glyph (substitute.arrayZ[0]); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (multiple subtitution)", + c->buffer->idx - 1); + } + return_trace (true); } /* Spec disallows this, but Uniscribe allows it. * https://github.com/harfbuzz/harfbuzz/issues/253 */ else if (unlikely (count == 0)) { + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "deleting glyph at %d (multiple substitution)", + c->buffer->idx); + } + c->buffer->delete_glyph (); + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "deleted glyph at %d (multiple substitution)", + c->buffer->idx); + } + return_trace (true); } + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "multiplying glyph at %d", + c->buffer->idx); + } + unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur()); @@ -65,6 +106,26 @@ struct Sequence } c->buffer->skip_glyph (); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + + char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0}; + char *p = buf; + + for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++) + { + if (buf < p) + *p++ = ','; + sprintf (p, "%u", i); + p += strlen(p); + } + + c->buffer->message (c->font, + "multiplied glyphs at %s", + buf); + } + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh index dd44595741..4b17243d81 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -45,6 +45,18 @@ struct SingleSubstFormat1_3 hb_set_t intersection; (this+coverage).intersect_set (c->parent_active_glyphs (), intersection); + /* In degenerate fuzzer-found fonts, but not real fonts, + * this table can keep adding new glyphs in each round of closure. + * Refuse to close-over, if it maps glyph range to overlapping range. */ + hb_codepoint_t min_before = intersection.get_min (); + hb_codepoint_t max_before = intersection.get_max (); + hb_codepoint_t min_after = (min_before + d) & mask; + hb_codepoint_t max_after = (max_before + d) & mask; + if ((this+coverage).get_population () >= max_before - min_before && + ((min_before <= min_after && min_after <= max_before) || + (min_before <= max_after && max_after <= max_before))) + return; + + hb_iter (intersection) | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; }) | hb_sink (c->output) @@ -82,8 +94,23 @@ struct SingleSubstFormat1_3 glyph_id = (glyph_id + d) & mask; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %d (single substitution)", + c->buffer->idx); + } + c->replace_glyph (glyph_id); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (single substitution)", + c->buffer->idx - 1); + } + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh index 386419a2a5..fb1e90d03e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -68,8 +68,23 @@ struct SingleSubstFormat2_4 if (unlikely (index >= substitute.len)) return_trace (false); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "replacing glyph at %d (single substitution)", + c->buffer->idx); + } + c->replace_glyph (substitute[index]); + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + c->buffer->message (c->font, + "replaced glyph at %d (single substitution)", + c->buffer->idx - 1); + } + return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh index abe4c8330c..98c2ee4e73 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh @@ -26,7 +26,9 @@ struct CompositeGlyphRecord OVERLAP_COMPOUND = 0x0400, SCALED_COMPONENT_OFFSET = 0x0800, UNSCALED_COMPONENT_OFFSET = 0x1000, +#ifndef HB_NO_BEYOND_64K GID_IS_24BIT = 0x2000 +#endif }; public: @@ -34,7 +36,9 @@ struct CompositeGlyphRecord { unsigned int size = min_size; /* glyphIndex is 24bit instead of 16bit */ +#ifndef HB_NO_BEYOND_64K if (flags & GID_IS_24BIT) size += HBGlyphID24::static_size - HBGlyphID16::static_size; +#endif /* arg1 and 2 are int16 */ if (flags & ARG_1_AND_2_ARE_WORDS) size += 4; /* arg1 and 2 are int8 */ @@ -64,9 +68,11 @@ struct CompositeGlyphRecord void get_anchor_points (unsigned int &point1, unsigned int &point2) const { const auto *p = &StructAfter<const HBUINT8> (flags); +#ifndef HB_NO_BEYOND_64K if (flags & GID_IS_24BIT) p += HBGlyphID24::static_size; else +#endif p += HBGlyphID16::static_size; if (flags & ARG_1_AND_2_ARE_WORDS) { @@ -109,9 +115,11 @@ struct CompositeGlyphRecord matrix[1] = matrix[2] = 0.f; const auto *p = &StructAfter<const HBINT8> (flags); +#ifndef HB_NO_BEYOND_64K if (flags & GID_IS_24BIT) p += HBGlyphID24::static_size; else +#endif p += HBGlyphID16::static_size; int tx, ty; if (flags & ARG_1_AND_2_ARE_WORDS) @@ -158,16 +166,20 @@ struct CompositeGlyphRecord public: hb_codepoint_t get_gid () const { +#ifndef HB_NO_BEYOND_64K if (flags & GID_IS_24BIT) return StructAfter<const HBGlyphID24> (flags); else +#endif return StructAfter<const HBGlyphID16> (flags); } void set_gid (hb_codepoint_t gid) { +#ifndef HB_NO_BEYOND_64K if (flags & GID_IS_24BIT) StructAfter<HBGlyphID24> (flags) = gid; else +#endif /* TODO assert? */ StructAfter<HBGlyphID16> (flags) = gid; } diff --git a/thirdparty/harfbuzz/src/graph/coverage-graph.hh b/thirdparty/harfbuzz/src/graph/coverage-graph.hh new file mode 100644 index 0000000000..1d9fd0eb5b --- /dev/null +++ b/thirdparty/harfbuzz/src/graph/coverage-graph.hh @@ -0,0 +1,80 @@ +/* + * Copyright © 2022 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#include "graph.hh" +#include "../OT/Layout/Common/Coverage.hh" + +#ifndef GRAPH_COVERAGE_GRAPH_HH +#define GRAPH_COVERAGE_GRAPH_HH + +namespace graph { + +struct CoverageFormat1 : public OT::Layout::Common::CoverageFormat1_3<SmallTypes> +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + constexpr unsigned min_size = OT::Layout::Common::CoverageFormat1_3<SmallTypes>::min_size; + if (vertex_len < min_size) return false; + return vertex_len >= min_size + glyphArray.get_size () - glyphArray.len.get_size (); + } +}; + +struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4<SmallTypes> +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + constexpr unsigned min_size = OT::Layout::Common::CoverageFormat2_4<SmallTypes>::min_size; + if (vertex_len < min_size) return false; + return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); + } +}; + +struct Coverage : public OT::Layout::Common::Coverage +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::Layout::Common::Coverage::min_size) return false; + switch (u.format) + { + case 1: return ((CoverageFormat1*)this)->sanitize (vertex); + case 2: return ((CoverageFormat2*)this)->sanitize (vertex); +#ifndef HB_NO_BORING_EXPANSION + // Not currently supported + case 3: + case 4: +#endif + default: return false; + } + } +}; + + +} + +#endif // GRAPH_COVERAGE_GRAPH_HH diff --git a/thirdparty/harfbuzz/src/graph/graph.hh b/thirdparty/harfbuzz/src/graph/graph.hh index 49638f34a7..b3aef558a2 100644 --- a/thirdparty/harfbuzz/src/graph/graph.hh +++ b/thirdparty/harfbuzz/src/graph/graph.hh @@ -24,6 +24,10 @@ * Google Author(s): Garret Rieger */ +#include "../hb-set.hh" +#include "../hb-priority-queue.hh" +#include "../hb-serialize.hh" + #ifndef GRAPH_GRAPH_HH #define GRAPH_GRAPH_HH @@ -76,6 +80,22 @@ struct graph_t } } + void remove_real_link (unsigned child_index, const void* offset) + { + for (unsigned i = 0; i < obj.real_links.length; i++) + { + auto& link = obj.real_links[i]; + if (link.objidx != child_index) + continue; + + if ((obj.head + link.position) != offset) + continue; + + obj.real_links.remove (i); + return; + } + } + void remap_parents (const hb_vector_t<unsigned>& id_map) { for (unsigned i = 0; i < parents.length; i++) @@ -107,6 +127,10 @@ struct graph_t return priority >= 3; } + size_t table_size () const { + return obj.tail - obj.head; + } + int64_t modified_distance (unsigned order) const { // TODO(garretrieger): once priority is high enough, should try @@ -199,13 +223,24 @@ struct graph_t return vertices_.length - 1; } - const hb_serialize_context_t::object_t& object(unsigned i) const + const hb_serialize_context_t::object_t& object (unsigned i) const { return vertices_[i].obj; } /* * Generates a new topological sorting of graph ordered by the shortest + * distance to each node if positions are marked as invalid. + */ + void sort_shortest_distance_if_needed () + { + if (!positions_invalid) return; + sort_shortest_distance (); + } + + + /* + * Generates a new topological sorting of graph ordered by the shortest * distance to each node. */ void sort_shortest_distance () @@ -256,12 +291,12 @@ struct graph_t check_success (!queue.in_error ()); check_success (!sorted_graph.in_error ()); - if (!check_success (new_id == -1)) - print_orphaned_nodes (); remap_all_obj_indices (id_map, &sorted_graph); - hb_swap (vertices_, sorted_graph); + + if (!check_success (new_id == -1)) + print_orphaned_nodes (); } /* @@ -310,6 +345,22 @@ struct graph_t } } + unsigned index_for_offset(unsigned node_idx, const void* offset) const + { + const auto& node = object (node_idx); + if (offset < node.head || offset >= node.tail) return -1; + + for (const auto& link : node.real_links) + { + if (offset != node.head + link.position) + continue; + return link.objidx; + } + + return -1; + } + + /* * Assign unique space numbers to each connected subgraph of 24 bit and/or 32 bit offset(s). * Currently, this is implemented specifically tailored to the structure of a GPOS/GSUB @@ -317,6 +368,8 @@ struct graph_t */ bool assign_spaces () { + update_parents (); + hb_set_t visited; hb_set_t roots; find_space_roots (visited, roots); @@ -458,6 +511,21 @@ struct graph_t find_subgraph (link.objidx, subgraph); } + size_t find_subgraph_size (unsigned node_idx, hb_set_t& subgraph, unsigned max_depth = -1) + { + if (subgraph.has (node_idx)) return 0; + subgraph.add (node_idx); + + const auto& o = vertices_[node_idx].obj; + size_t size = o.tail - o.head; + if (max_depth == 0) + return size; + + for (const auto& link : o.all_links ()) + size += find_subgraph_size (link.objidx, subgraph, max_depth - 1); + return size; + } + /* * Finds the topmost children of 32bit offsets in the subgraph starting * at node_idx. Found indices are placed into 'found'. @@ -475,6 +543,37 @@ struct graph_t } /* + * Moves the child of old_parent_idx pointed to by old_offset to a new + * vertex at the new_offset. + */ + template<typename O> + void move_child (unsigned old_parent_idx, + const O* old_offset, + unsigned new_parent_idx, + const O* new_offset) + { + distance_invalid = true; + positions_invalid = true; + + auto& old_v = vertices_[old_parent_idx]; + auto& new_v = vertices_[new_parent_idx]; + + unsigned child_id = index_for_offset (old_parent_idx, + old_offset); + + auto* new_link = new_v.obj.real_links.push (); + new_link->width = O::static_size; + new_link->objidx = child_id; + new_link->position = (const char*) new_offset - (const char*) new_v.obj.head; + + auto& child = vertices_[child_id]; + child.parents.push (new_parent_idx); + + old_v.remove_real_link (child_id, old_offset); + child.remove_parent (old_parent_idx); + } + + /* * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign * links. index_map is updated with mappings from old id to new id. If a duplication has already * been performed for a given index, then it will be skipped. @@ -581,6 +680,39 @@ struct graph_t return true; } + + /* + * Adds a new node to the graph, not connected to anything. + */ + unsigned new_node (char* head, char* tail) + { + positions_invalid = true; + distance_invalid = true; + + auto* clone = vertices_.push (); + if (vertices_.in_error ()) { + return -1; + } + + clone->obj.head = head; + clone->obj.tail = tail; + clone->distance = 0; + clone->space = 0; + + unsigned clone_idx = vertices_.length - 2; + + // The last object is the root of the graph, so swap back the root to the end. + // The root's obj idx does change, however since it's root nothing else refers to it. + // all other obj idx's will be unaffected. + hb_swap (vertices_[vertices_.length - 2], *clone); + + // Since the root moved, update the parents arrays of all children on the root. + for (const auto& l : root ().obj.all_links ()) + vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); + + return clone_idx; + } + /* * Raises the sorting priority of all children. */ diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-context.cc b/thirdparty/harfbuzz/src/graph/gsubgpos-context.cc new file mode 100644 index 0000000000..e0ff6ff85f --- /dev/null +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-context.cc @@ -0,0 +1,71 @@ +/* + * Copyright © 2022 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#include "gsubgpos-graph.hh" + +namespace graph { + +gsubgpos_graph_context_t::gsubgpos_graph_context_t (hb_tag_t table_tag_, + graph_t& graph_) + : table_tag (table_tag_), + graph (graph_), + lookup_list_index (0), + lookups (), + buffers () +{ + if (table_tag_ != HB_OT_TAG_GPOS + && table_tag_ != HB_OT_TAG_GSUB) + return; + + GSTAR* gstar = graph::GSTAR::graph_to_gstar (graph_); + if (gstar) { + gstar->find_lookups (graph, lookups); + lookup_list_index = gstar->get_lookup_list_index (graph_); + } +} + +unsigned gsubgpos_graph_context_t::create_node (unsigned size) +{ + char* buffer = (char*) hb_calloc (1, size); + if (!buffer) + return -1; + + buffers.push (buffer); + + return graph.new_node (buffer, buffer + size); +} + +unsigned gsubgpos_graph_context_t::num_non_ext_subtables () { + unsigned count = 0; + for (auto l : lookups.values ()) + { + if (l->is_extension (table_tag)) continue; + count += l->number_of_subtables (); + } + return count; +} + +} diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh b/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh new file mode 100644 index 0000000000..49b24198ff --- /dev/null +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh @@ -0,0 +1,67 @@ +/* + * Copyright © 2022 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#include "graph.hh" +#include "../hb-ot-layout-gsubgpos.hh" + +#ifndef GRAPH_GSUBGPOS_CONTEXT_HH +#define GRAPH_GSUBGPOS_CONTEXT_HH + +namespace graph { + +struct Lookup; + +struct gsubgpos_graph_context_t +{ + hb_tag_t table_tag; + graph_t& graph; + unsigned lookup_list_index; + hb_hashmap_t<unsigned, graph::Lookup*> lookups; + hb_vector_t<char*> buffers; + + HB_INTERNAL gsubgpos_graph_context_t (hb_tag_t table_tag_, + graph_t& graph_); + + ~gsubgpos_graph_context_t () + { + for (char* b : buffers) + hb_free (b); + } + + HB_INTERNAL unsigned create_node (unsigned size); + + void add_buffer (char* buffer) + { + buffers.push (buffer); + } + + private: + HB_INTERNAL unsigned num_non_ext_subtables (); +}; + +} + +#endif // GRAPH_GSUBGPOS_CONTEXT diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh new file mode 100644 index 0000000000..afa1152c44 --- /dev/null +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh @@ -0,0 +1,351 @@ +/* + * Copyright © 2022 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#include "graph.hh" +#include "../hb-ot-layout-gsubgpos.hh" +#include "../OT/Layout/GSUB/ExtensionSubst.hh" +#include "gsubgpos-context.hh" +#include "pairpos-graph.hh" + +#ifndef GRAPH_GSUBGPOS_GRAPH_HH +#define GRAPH_GSUBGPOS_GRAPH_HH + +namespace graph { + +struct Lookup; + +template<typename T> +struct ExtensionFormat1 : public OT::ExtensionFormat1<T> +{ + void reset(unsigned type) + { + this->format = 1; + this->extensionLookupType = type; + this->extensionOffset = 0; + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + return vertex_len >= OT::ExtensionFormat1<T>::static_size; + } + + unsigned get_lookup_type () const + { + return this->extensionLookupType; + } + + unsigned get_subtable_index (graph_t& graph, unsigned this_index) const + { + return graph.index_for_offset (this_index, &this->extensionOffset); + } +}; + +struct Lookup : public OT::Lookup +{ + unsigned number_of_subtables () const + { + return subTable.len; + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::Lookup::min_size) return false; + return vertex_len >= this->get_size (); + } + + bool is_extension (hb_tag_t table_tag) const + { + return lookupType == extension_type (table_tag); + } + + bool make_extension (gsubgpos_graph_context_t& c, + unsigned this_index) + { + unsigned type = lookupType; + unsigned ext_type = extension_type (c.table_tag); + if (!ext_type || is_extension (c.table_tag)) + { + // NOOP + return true; + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Promoting lookup type %u (obj %u) to extension.", + type, + this_index); + + for (unsigned i = 0; i < subTable.len; i++) + { + unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]); + if (!make_subtable_extension (c, + this_index, + subtable_index)) + return false; + } + + lookupType = ext_type; + return true; + } + + bool split_subtables_if_needed (gsubgpos_graph_context_t& c, + unsigned this_index) + { + unsigned type = lookupType; + bool is_ext = is_extension (c.table_tag); + + if (c.table_tag != HB_OT_TAG_GPOS) + return true; + + if (!is_ext && type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair) + return true; + + hb_vector_t<unsigned> all_new_subtables; + for (unsigned i = 0; i < subTable.len; i++) + { + unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]); + if (is_ext) { + unsigned ext_subtable_index = subtable_index; + ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>* extension = + (ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*) + c.graph.object (ext_subtable_index).head; + if (!extension->sanitize (c.graph.vertices_[ext_subtable_index])) + continue; + + subtable_index = extension->get_subtable_index (c.graph, ext_subtable_index); + type = extension->get_lookup_type (); + if (type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair) + continue; + } + + PairPos* pairPos = (PairPos*) c.graph.object (subtable_index).head; + if (!pairPos->sanitize (c.graph.vertices_[subtable_index])) continue; + + hb_vector_t<unsigned> new_sub_tables = pairPos->split_subtables (c, subtable_index); + if (new_sub_tables.in_error ()) return false; + + new_sub_tables.iter() | hb_sink (all_new_subtables); + } + + if (all_new_subtables) + add_sub_tables (c, this_index, type, all_new_subtables); + + return true; + } + + void add_sub_tables (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned type, + hb_vector_t<unsigned>& subtable_indices) + { + bool is_ext = is_extension (c.table_tag); + auto& v = c.graph.vertices_[this_index]; + + size_t new_size = v.table_size () + + subtable_indices.length * OT::Offset16::static_size; + char* buffer = (char*) hb_calloc (1, new_size); + c.add_buffer (buffer); + memcpy (buffer, v.obj.head, v.table_size()); + + v.obj.head = buffer; + v.obj.tail = buffer + new_size; + + Lookup* new_lookup = (Lookup*) buffer; + + new_lookup->subTable.len = subTable.len + subtable_indices.length; + unsigned offset_index = subTable.len; + for (unsigned subtable_id : subtable_indices) + { + if (is_ext) + { + unsigned ext_id = create_extension_subtable (c, subtable_id, type); + c.graph.vertices_[subtable_id].parents.push (ext_id); + subtable_id = ext_id; + } + + auto* link = v.obj.real_links.push (); + link->width = 2; + link->objidx = subtable_id; + link->position = (char*) &new_lookup->subTable[offset_index++] - + (char*) new_lookup; + c.graph.vertices_[subtable_id].parents.push (this_index); + } + + // The head location of the lookup has changed, invalidating the lookups map entry + // in the context. Update the map. + c.lookups.set (this_index, new_lookup); + } + + unsigned create_extension_subtable (gsubgpos_graph_context_t& c, + unsigned subtable_index, + unsigned type) + { + unsigned extension_size = OT::ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>::static_size; + + unsigned ext_index = c.create_node (extension_size); + if (ext_index == (unsigned) -1) + return -1; + + auto& ext_vertex = c.graph.vertices_[ext_index]; + ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>* extension = + (ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*) ext_vertex.obj.head; + extension->reset (type); + + // Make extension point at the subtable. + auto* l = ext_vertex.obj.real_links.push (); + + l->width = 4; + l->objidx = subtable_index; + l->position = 4; + + return ext_index; + } + + bool make_subtable_extension (gsubgpos_graph_context_t& c, + unsigned lookup_index, + unsigned subtable_index) + { + unsigned type = lookupType; + + unsigned ext_index = create_extension_subtable(c, subtable_index, type); + if (ext_index == (unsigned) -1) + return false; + + auto& lookup_vertex = c.graph.vertices_[lookup_index]; + for (auto& l : lookup_vertex.obj.real_links.writer ()) + { + if (l.objidx == subtable_index) + // Change lookup to point at the extension. + l.objidx = ext_index; + } + + // Make extension point at the subtable. + auto& ext_vertex = c.graph.vertices_[ext_index]; + auto& subtable_vertex = c.graph.vertices_[subtable_index]; + ext_vertex.parents.push (lookup_index); + subtable_vertex.remap_parent (lookup_index, ext_index); + + return true; + } + + private: + unsigned extension_type (hb_tag_t table_tag) const + { + switch (table_tag) + { + case HB_OT_TAG_GPOS: return 9; + case HB_OT_TAG_GSUB: return 7; + default: return 0; + } + } +}; + +template <typename T> +struct LookupList : public OT::LookupList<T> +{ + bool sanitize (const graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::LookupList<T>::min_size) return false; + return vertex_len >= OT::LookupList<T>::item_size * this->len; + } +}; + +struct GSTAR : public OT::GSUBGPOS +{ + static GSTAR* graph_to_gstar (graph_t& graph) + { + const auto& r = graph.root (); + + GSTAR* gstar = (GSTAR*) r.obj.head; + if (!gstar->sanitize (r)) + return nullptr; + + return gstar; + } + + const void* get_lookup_list_field_offset () const + { + switch (u.version.major) { + case 1: return u.version1.get_lookup_list_offset (); +#ifndef HB_NO_BORING_EXPANSION + case 2: return u.version2.get_lookup_list_offset (); +#endif + default: return 0; + } + } + + bool sanitize (const graph_t::vertex_t& vertex) + { + int64_t len = vertex.obj.tail - vertex.obj.head; + if (len < OT::GSUBGPOS::min_size) return false; + return len >= get_size (); + } + + void find_lookups (graph_t& graph, + hb_hashmap_t<unsigned, Lookup*>& lookups /* OUT */) + { + switch (u.version.major) { + case 1: find_lookups<SmallTypes> (graph, lookups); break; +#ifndef HB_NO_BORING_EXPANSION + case 2: find_lookups<MediumTypes> (graph, lookups); break; +#endif + } + } + + unsigned get_lookup_list_index (graph_t& graph) + { + return graph.index_for_offset (graph.root_idx (), + get_lookup_list_field_offset()); + } + + template<typename Types> + void find_lookups (graph_t& graph, + hb_hashmap_t<unsigned, Lookup*>& lookups /* OUT */) + { + unsigned lookup_list_idx = get_lookup_list_index (graph); + + const LookupList<Types>* lookupList = + (const LookupList<Types>*) graph.object (lookup_list_idx).head; + if (!lookupList->sanitize (graph.vertices_[lookup_list_idx])) + return; + + for (unsigned i = 0; i < lookupList->len; i++) + { + unsigned lookup_idx = graph.index_for_offset (lookup_list_idx, &(lookupList->arrayZ[i])); + Lookup* lookup = (Lookup*) graph.object (lookup_idx).head; + if (!lookup->sanitize (graph.vertices_[lookup_idx])) continue; + lookups.set (lookup_idx, lookup); + } + } +}; + + + + +} + +#endif /* GRAPH_GSUBGPOS_GRAPH_HH */ diff --git a/thirdparty/harfbuzz/src/graph/pairpos-graph.hh b/thirdparty/harfbuzz/src/graph/pairpos-graph.hh new file mode 100644 index 0000000000..3ca4fc701c --- /dev/null +++ b/thirdparty/harfbuzz/src/graph/pairpos-graph.hh @@ -0,0 +1,299 @@ +/* + * Copyright © 2022 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#ifndef GRAPH_PAIRPOS_GRAPH_HH +#define GRAPH_PAIRPOS_GRAPH_HH + +#include "coverage-graph.hh" +#include "../OT/Layout/GPOS/PairPos.hh" +#include "../OT/Layout/GPOS/PosLookupSubTable.hh" + +namespace graph { + +struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes> +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + unsigned min_size = OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size; + if (vertex_len < min_size) return false; + + return vertex_len >= + min_size + pairSet.get_size () - pairSet.len.get_size(); + } + + hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index) + { + hb_set_t visited; + + const unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage); + const unsigned coverage_size = c.graph.vertices_[coverage_id].table_size (); + const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size + + coverage_size; + + unsigned accumulated = base_size; + hb_vector_t<unsigned> split_points; + for (unsigned i = 0; i < pairSet.len; i++) + { + unsigned pair_set_index = pair_set_graph_index (c, this_index, i); + accumulated += c.graph.find_subgraph_size (pair_set_index, visited); + accumulated += SmallTypes::size; // for PairSet offset. + + // TODO(garretrieger): don't count the size of the largest pairset against the limit, since + // it will be packed last in the order and does not contribute to + // the 64kb limit. + + if (accumulated > (1 << 16)) + { + split_points.push (i); + accumulated = base_size; + visited.clear (); // Pretend node sharing isn't allowed between splits. + } + } + + return do_split (c, this_index, split_points); + } + + private: + + // Split this PairPos into two or more PairPos's. split_points defines + // the indices (first index to include in the new table) to split at. + // Returns the object id's of the newly created PairPos subtables. + hb_vector_t<unsigned> do_split (gsubgpos_graph_context_t& c, + unsigned this_index, + const hb_vector_t<unsigned> split_points) + { + hb_vector_t<unsigned> new_objects; + if (!split_points) + return new_objects; + + for (unsigned i = 0; i < split_points.length; i++) + { + unsigned start = split_points[i]; + unsigned end = (i < split_points.length - 1) ? split_points[i + 1] : pairSet.len; + unsigned id = clone_range (c, this_index, start, end); + + if (id == (unsigned) -1) + { + new_objects.reset (); + new_objects.allocated = -1; // mark error + return new_objects; + } + new_objects.push (id); + } + + if (!shrink (c, this_index, split_points[0])) + { + new_objects.reset (); + new_objects.allocated = -1; // mark error + } + + return new_objects; + } + + bool shrink (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned count) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Shrinking PairPosFormat1 (%u) to [0, %u).", + this_index, + count); + unsigned old_count = pairSet.len; + if (count >= old_count) + return true; + + pairSet.len = count; + c.graph.vertices_[this_index].obj.tail -= (old_count - count) * SmallTypes::size; + + unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage); + unsigned coverage_size = c.graph.vertices_[coverage_id].table_size (); + auto& coverage_v = c.graph.vertices_[coverage_id]; + Coverage* coverage_table = (Coverage*) coverage_v.obj.head; + if (!coverage_table->sanitize (coverage_v)) + return false; + + auto new_coverage = + + hb_zip (coverage_table->iter (), hb_range ()) + | hb_filter ([&] (hb_pair_t<unsigned, unsigned> p) { + return p.second < count; + }) + | hb_map_retains_sorting (hb_first) + ; + + return make_coverage (c, new_coverage, coverage_id, coverage_size); + } + + // Create a new PairPos including PairSet's from start (inclusive) to end (exclusive). + // Returns object id of the new object. + unsigned clone_range (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned start, unsigned end) const + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Cloning PairPosFormat1 (%u) range [%u, %u).", this_index, start, end); + + unsigned num_pair_sets = end - start; + unsigned prime_size = OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size + + num_pair_sets * SmallTypes::size; + + unsigned pair_pos_prime_id = c.create_node (prime_size); + if (pair_pos_prime_id == (unsigned) -1) return -1; + + PairPosFormat1* pair_pos_prime = (PairPosFormat1*) c.graph.object (pair_pos_prime_id).head; + pair_pos_prime->format = this->format; + pair_pos_prime->valueFormat[0] = this->valueFormat[0]; + pair_pos_prime->valueFormat[1] = this->valueFormat[1]; + pair_pos_prime->pairSet.len = num_pair_sets; + + for (unsigned i = start; i < end; i++) + { + c.graph.move_child<> (this_index, + &pairSet[i], + pair_pos_prime_id, + &pair_pos_prime->pairSet[i - start]); + } + + unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage); + unsigned coverage_size = c.graph.vertices_[coverage_id].table_size (); + auto& coverage_v = c.graph.vertices_[coverage_id]; + Coverage* coverage_table = (Coverage*) coverage_v.obj.head; + if (!coverage_table->sanitize (coverage_v)) + return false; + + auto new_coverage = + + hb_zip (coverage_table->iter (), hb_range ()) + | hb_filter ([&] (hb_pair_t<unsigned, unsigned> p) { + return p.second >= start && p.second < end; + }) + | hb_map_retains_sorting (hb_first) + ; + + unsigned coverage_prime_id = c.graph.new_node (nullptr, nullptr); + auto& coverage_prime_vertex = c.graph.vertices_[coverage_prime_id]; + if (!make_coverage (c, new_coverage, coverage_prime_id, coverage_size)) + return -1; + + auto* coverage_link = c.graph.vertices_[pair_pos_prime_id].obj.real_links.push (); + coverage_link->width = SmallTypes::size; + coverage_link->objidx = coverage_prime_id; + coverage_link->position = 2; + coverage_prime_vertex.parents.push (pair_pos_prime_id); + + return pair_pos_prime_id; + } + + template<typename It> + bool make_coverage (gsubgpos_graph_context_t& c, + It glyphs, + unsigned dest_obj, + unsigned max_size) const + { + char* buffer = (char*) hb_calloc (1, max_size); + hb_serialize_context_t serializer (buffer, max_size); + Coverage_serialize (&serializer, glyphs); + serializer.end_serialize (); + if (serializer.in_error ()) + { + hb_free (buffer); + return false; + } + + hb_bytes_t coverage_copy = serializer.copy_bytes (); + c.add_buffer ((char *) coverage_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer. + + auto& obj = c.graph.vertices_[dest_obj].obj; + obj.head = (char *) coverage_copy.arrayZ; + obj.tail = obj.head + coverage_copy.length; + + hb_free (buffer); + return true; + } + + unsigned pair_set_graph_index (gsubgpos_graph_context_t& c, unsigned this_index, unsigned i) const + { + return c.graph.index_for_offset (this_index, &pairSet[i]); + } +}; + +struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes> +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + // TODO(garretrieger): implement me! + return true; + } + + hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index) + { + // TODO(garretrieger): implement me! + return hb_vector_t<unsigned> (); + } +}; + +struct PairPos : public OT::Layout::GPOS_impl::PairPos +{ + hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index) + { + switch (u.format) { + case 1: + return ((PairPosFormat1*)(&u.format1))->split_subtables (c, this_index); + case 2: + return ((PairPosFormat2*)(&u.format2))->split_subtables (c, this_index); +#ifndef HB_NO_BORING_EXPANSION + case 3: HB_FALLTHROUGH; + case 4: HB_FALLTHROUGH; + // Don't split 24bit PairPos's. +#endif + default: + return hb_vector_t<unsigned> (); + } + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < u.format.get_size ()) return false; + + switch (u.format) { + case 1: + return ((PairPosFormat1*)(&u.format1))->sanitize (vertex); + case 2: + return ((PairPosFormat2*)(&u.format2))->sanitize (vertex); +#ifndef HB_NO_BORING_EXPANSION + case 3: HB_FALLTHROUGH; + case 4: HB_FALLTHROUGH; +#endif + default: + // We don't handle format 3 and 4 here. + return false; + } + } +}; + +} + +#endif // GRAPH_PAIRPOS_GRAPH_HH diff --git a/thirdparty/harfbuzz/src/hb-blob.cc b/thirdparty/harfbuzz/src/hb-blob.cc index 47062eab9a..9bc12ea3fa 100644 --- a/thirdparty/harfbuzz/src/hb-blob.cc +++ b/thirdparty/harfbuzz/src/hb-blob.cc @@ -303,7 +303,7 @@ hb_blob_set_user_data (hb_blob_t *blob, * Since: 0.9.2 **/ void * -hb_blob_get_user_data (hb_blob_t *blob, +hb_blob_get_user_data (const hb_blob_t *blob, hb_user_data_key_t *key) { return hb_object_get_user_data (blob, key); diff --git a/thirdparty/harfbuzz/src/hb-blob.h b/thirdparty/harfbuzz/src/hb-blob.h index 203f9e19dd..4eb42314da 100644 --- a/thirdparty/harfbuzz/src/hb-blob.h +++ b/thirdparty/harfbuzz/src/hb-blob.h @@ -135,7 +135,7 @@ hb_blob_set_user_data (hb_blob_t *blob, HB_EXTERN void * -hb_blob_get_user_data (hb_blob_t *blob, +hb_blob_get_user_data (const hb_blob_t *blob, hb_user_data_key_t *key); diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc index fddda23304..57a5ae03ed 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.cc +++ b/thirdparty/harfbuzz/src/hb-buffer.cc @@ -387,9 +387,11 @@ hb_buffer_t::clear_positions () hb_memset (pos, 0, sizeof (pos[0]) * len); } -void +bool hb_buffer_t::sync () { + bool ret = false; + assert (have_output); assert (idx <= len); @@ -403,12 +405,39 @@ hb_buffer_t::sync () info = out_info; } len = out_len; + ret = true; reset: have_output = false; out_len = 0; out_info = info; idx = 0; + + return ret; +} + +int +hb_buffer_t::sync_so_far () +{ + bool had_output = have_output; + unsigned out_i = out_len; + unsigned i = idx; + unsigned old_idx = idx; + + if (sync ()) + idx = out_i; + else + idx = i; + + if (had_output) + { + have_output = true; + out_len = idx; + } + + assert (idx <= len); + + return idx - old_idx; } bool @@ -802,7 +831,7 @@ hb_buffer_set_user_data (hb_buffer_t *buffer, * Since: 0.9.2 **/ void * -hb_buffer_get_user_data (hb_buffer_t *buffer, +hb_buffer_get_user_data (const hb_buffer_t *buffer, hb_user_data_key_t *key) { return hb_object_get_user_data (buffer, key); @@ -2090,8 +2119,16 @@ hb_buffer_set_message_func (hb_buffer_t *buffer, bool hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap) { + assert (!have_output || (out_info == info && out_len == idx)); + + message_depth++; + char buf[100]; vsnprintf (buf, sizeof (buf), fmt, ap); - return (bool) this->message_func (this, font, buf, this->message_data); + bool ret = (bool) this->message_func (this, font, buf, this->message_data); + + message_depth--; + + return ret; } #endif diff --git a/thirdparty/harfbuzz/src/hb-buffer.h b/thirdparty/harfbuzz/src/hb-buffer.h index e095c5344c..c6af759fb9 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.h +++ b/thirdparty/harfbuzz/src/hb-buffer.h @@ -142,6 +142,15 @@ typedef struct hb_glyph_info_t { * shaping, otherwise the buffer flag will not be * reliably produced. * Since: 4.0.0 + * @HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL: In scripts that use elongation (Arabic, + Mongolian, Syriac, etc.), this flag signifies + that it is safe to insert a U+0640 TATWEEL + character *before* this cluster for elongation. + This flag does not determine the + script-specific elongation places, but only + when it is safe to do the elongation without + interrupting text shaping. + Since: 5.1.0 * @HB_GLYPH_FLAG_DEFINED: All the currently defined flags. * * Flags for #hb_glyph_info_t. @@ -149,10 +158,11 @@ typedef struct hb_glyph_info_t { * Since: 1.5.0 */ typedef enum { /*< flags >*/ - HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001, - HB_GLYPH_FLAG_UNSAFE_TO_CONCAT = 0x00000002, + HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001, + HB_GLYPH_FLAG_UNSAFE_TO_CONCAT = 0x00000002, + HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL = 0x00000004, - HB_GLYPH_FLAG_DEFINED = 0x00000003 /* OR of all defined flags */ + HB_GLYPH_FLAG_DEFINED = 0x00000007 /* OR of all defined flags */ } hb_glyph_flags_t; HB_EXTERN hb_glyph_flags_t @@ -266,7 +276,7 @@ hb_buffer_set_user_data (hb_buffer_t *buffer, hb_bool_t replace); HB_EXTERN void * -hb_buffer_get_user_data (hb_buffer_t *buffer, +hb_buffer_get_user_data (const hb_buffer_t *buffer, hb_user_data_key_t *key); @@ -373,6 +383,10 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer); * flag indicating that the @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT * glyph-flag should be produced by the shaper. By default * it will not be produced since it incurs a cost. Since: 4.0.0 + * @HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL: + * flag indicating that the @HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL + * glyph-flag should be produced by the shaper. By default + * it will not be produced. Since: 5.1.0 * @HB_BUFFER_FLAG_DEFINED: All currently defined flags: Since: 4.4.0 * * Flags for #hb_buffer_t. @@ -388,8 +402,9 @@ typedef enum { /*< flags >*/ HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u, HB_BUFFER_FLAG_VERIFY = 0x00000020u, HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u, + HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL = 0x00000080u, - HB_BUFFER_FLAG_DEFINED = 0x0000007Fu + HB_BUFFER_FLAG_DEFINED = 0x000000FFu } hb_buffer_flags_t; HB_EXTERN void diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh index 6ca78f28d4..26c3f0fac8 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.hh +++ b/thirdparty/harfbuzz/src/hb-buffer.hh @@ -288,7 +288,8 @@ struct hb_buffer_t HB_INTERNAL void guess_segment_properties (); - HB_INTERNAL void sync (); + HB_INTERNAL bool sync (); + HB_INTERNAL int sync_so_far (); HB_INTERNAL void clear_output (); HB_INTERNAL void clear_positions (); @@ -461,6 +462,17 @@ struct hb_buffer_t start, end, true); } + void safe_to_insert_tatweel (unsigned int start = 0, unsigned int end = -1) + { + if ((flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL) == 0) + { + unsafe_to_break (start, end); + return; + } + _set_glyph_flags (HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL, + start, end, + true); + } void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1) { if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0)) @@ -555,15 +567,11 @@ struct hb_buffer_t if (likely (!messaging ())) return true; - message_depth++; - va_list ap; va_start (ap, fmt); bool ret = message_impl (font, fmt, ap); va_end (ap); - message_depth--; - return ret; #endif } diff --git a/thirdparty/harfbuzz/src/hb-cplusplus.hh b/thirdparty/harfbuzz/src/hb-cplusplus.hh index f06a32d912..c4d9d29e23 100644 --- a/thirdparty/harfbuzz/src/hb-cplusplus.hh +++ b/thirdparty/harfbuzz/src/hb-cplusplus.hh @@ -130,7 +130,7 @@ template <typename T, void *, hb_destroy_func_t, hb_bool_t), - void * (*_get_user_data) (T *, + void * (*_get_user_data) (const T *, hb_user_data_key_t *)> struct vtable_t { @@ -164,6 +164,27 @@ HB_DEFINE_VTABLE (unicode_funcs); #undef HB_DEFINE_VTABLE +#ifdef HB_SUBSET_H + +#define HB_DEFINE_VTABLE(name) \ + template<> \ + struct vtable<hb_##name##_t> \ + : vtable_t<hb_##name##_t, \ + nullptr, \ + &hb_##name##_reference, \ + &hb_##name##_destroy, \ + &hb_##name##_set_user_data, \ + &hb_##name##_get_user_data> {} + + +HB_DEFINE_VTABLE (subset_input); +HB_DEFINE_VTABLE (subset_plan); + +#undef HB_DEFINE_VTABLE + +#endif + + } // namespace hb /* Workaround for GCC < 7, see: diff --git a/thirdparty/harfbuzz/src/hb-debug.hh b/thirdparty/harfbuzz/src/hb-debug.hh index 3ac7440e80..905a46a087 100644 --- a/thirdparty/harfbuzz/src/hb-debug.hh +++ b/thirdparty/harfbuzz/src/hb-debug.hh @@ -460,4 +460,9 @@ struct hb_no_trace_t { #endif +#ifndef HB_BUFFER_MESSAGE_MORE +#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+1) +#endif + + #endif /* HB_DEBUG_HH */ diff --git a/thirdparty/harfbuzz/src/hb-face.cc b/thirdparty/harfbuzz/src/hb-face.cc index 8f8b1a6d14..61adbdd503 100644 --- a/thirdparty/harfbuzz/src/hb-face.cc +++ b/thirdparty/harfbuzz/src/hb-face.cc @@ -342,7 +342,7 @@ hb_face_set_user_data (hb_face_t *face, * Since: 0.9.2 **/ void * -hb_face_get_user_data (hb_face_t *face, +hb_face_get_user_data (const hb_face_t *face, hb_user_data_key_t *key) { return hb_object_get_user_data (face, key); diff --git a/thirdparty/harfbuzz/src/hb-face.h b/thirdparty/harfbuzz/src/hb-face.h index 3b7477a76c..6ef2f8b886 100644 --- a/thirdparty/harfbuzz/src/hb-face.h +++ b/thirdparty/harfbuzz/src/hb-face.h @@ -96,7 +96,7 @@ hb_face_set_user_data (hb_face_t *face, hb_bool_t replace); HB_EXTERN void * -hb_face_get_user_data (hb_face_t *face, +hb_face_get_user_data (const hb_face_t *face, hb_user_data_key_t *key); HB_EXTERN void diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc index fd9073c33e..856bbdda32 100644 --- a/thirdparty/harfbuzz/src/hb-font.cc +++ b/thirdparty/harfbuzz/src/hb-font.cc @@ -781,8 +781,8 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, * Since: 0.9.2 **/ void * -hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, - hb_user_data_key_t *key) +hb_font_funcs_get_user_data (const hb_font_funcs_t *ffuncs, + hb_user_data_key_t *key) { return hb_object_get_user_data (ffuncs, key); } @@ -1897,7 +1897,7 @@ hb_font_set_user_data (hb_font_t *font, * Since: 0.9.2 **/ void * -hb_font_get_user_data (hb_font_t *font, +hb_font_get_user_data (const hb_font_t *font, hb_user_data_key_t *key) { return hb_object_get_user_data (font, key); diff --git a/thirdparty/harfbuzz/src/hb-font.h b/thirdparty/harfbuzz/src/hb-font.h index 3f27bca288..e2c3df4a5a 100644 --- a/thirdparty/harfbuzz/src/hb-font.h +++ b/thirdparty/harfbuzz/src/hb-font.h @@ -86,8 +86,8 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, HB_EXTERN void * -hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, - hb_user_data_key_t *key); +hb_font_funcs_get_user_data (const hb_font_funcs_t *ffuncs, + hb_user_data_key_t *key); HB_EXTERN void @@ -993,7 +993,7 @@ hb_font_set_user_data (hb_font_t *font, HB_EXTERN void * -hb_font_get_user_data (hb_font_t *font, +hb_font_get_user_data (const hb_font_t *font, hb_user_data_key_t *key); HB_EXTERN void diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc index 5c88a7f3bd..ef073475cb 100644 --- a/thirdparty/harfbuzz/src/hb-ft.cc +++ b/thirdparty/harfbuzz/src/hb-ft.cc @@ -1086,7 +1086,8 @@ hb_ft_font_changed (hb_font_t *font) } #endif - _hb_ft_hb_font_check_changed (font, ft_font); + ft_font->advance_cache.clear (); + ft_font->cached_serial = font->serial; } /** diff --git a/thirdparty/harfbuzz/src/hb-map.cc b/thirdparty/harfbuzz/src/hb-map.cc index a29fa1a313..5c5f5de59e 100644 --- a/thirdparty/harfbuzz/src/hb-map.cc +++ b/thirdparty/harfbuzz/src/hb-map.cc @@ -145,7 +145,7 @@ hb_map_set_user_data (hb_map_t *map, * Since: 1.7.7 **/ void * -hb_map_get_user_data (hb_map_t *map, +hb_map_get_user_data (const hb_map_t *map, hb_user_data_key_t *key) { return hb_object_get_user_data (map, key); diff --git a/thirdparty/harfbuzz/src/hb-map.h b/thirdparty/harfbuzz/src/hb-map.h index 41d877d6a1..3a067c5c73 100644 --- a/thirdparty/harfbuzz/src/hb-map.h +++ b/thirdparty/harfbuzz/src/hb-map.h @@ -74,7 +74,7 @@ hb_map_set_user_data (hb_map_t *map, hb_bool_t replace); HB_EXTERN void * -hb_map_get_user_data (hb_map_t *map, +hb_map_get_user_data (const hb_map_t *map, hb_user_data_key_t *key); diff --git a/thirdparty/harfbuzz/src/hb-number-parser.hh b/thirdparty/harfbuzz/src/hb-number-parser.hh index ec68c3a728..1a9dbba6dd 100644 --- a/thirdparty/harfbuzz/src/hb-number-parser.hh +++ b/thirdparty/harfbuzz/src/hb-number-parser.hh @@ -31,7 +31,7 @@ #include "hb.hh" -#line 32 "hb-number-parser.hh" +#line 35 "hb-number-parser.hh" static const unsigned char _double_parser_trans_keys[] = { 0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 46u, 101u, 0 @@ -135,12 +135,12 @@ strtod_rl (const char *p, const char **end_ptr /* IN/OUT */) int cs; -#line 132 "hb-number-parser.hh" +#line 139 "hb-number-parser.hh" { cs = double_parser_start; } -#line 135 "hb-number-parser.hh" +#line 144 "hb-number-parser.hh" { int _slen; int _trans; @@ -198,7 +198,7 @@ _resume: exp_overflow = true; } break; -#line 187 "hb-number-parser.hh" +#line 202 "hb-number-parser.hh" } _again: diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 9a4157b21f..0532039aad 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -72,10 +72,6 @@ using OT::Layout::MediumTypes; #define HB_MAX_LANGSYS_FEATURE_COUNT 50000 #endif -#ifndef HB_MAX_FEATURES -#define HB_MAX_FEATURES 750 -#endif - #ifndef HB_MAX_FEATURE_INDICES #define HB_MAX_FEATURE_INDICES 1500 #endif @@ -1337,7 +1333,7 @@ struct Lookup return_trace (true); } - private: + protected: HBUINT16 lookupType; /* Different enumerations for GSUB and GPOS */ HBUINT16 lookupFlag; /* Lookup qualifiers */ Array16Of<Offset16> diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index 5acd228b83..c77ec12fbe 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -1602,9 +1602,28 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, if (unlikely (buffer->max_ops <= 0)) break; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + if (buffer->have_output) + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "recursing to lookup %u at %d", + (unsigned) lookupRecord[i].lookupListIndex, + buffer->idx); + } + if (!c->recurse (lookupRecord[i].lookupListIndex)) continue; + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) + { + if (buffer->have_output) + c->buffer->sync_so_far (); + c->buffer->message (c->font, + "recursed to lookup %u", + (unsigned) lookupRecord[i].lookupListIndex); + } + unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len (); int delta = new_len - orig_len; @@ -4010,6 +4029,11 @@ struct GSUBGPOSVersion1_2 (version.to_int () >= 0x00010001u ? featureVars.static_size : 0); } + const typename Types::template OffsetTo<LookupList<Types>>* get_lookup_list_offset () const + { + return &lookupList; + } + template <typename TLookup> bool sanitize (hb_sanitize_context_t *c) const { diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 2ada84b8a3..7f679cfd39 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -1141,6 +1141,18 @@ hb_propagate_flags (hb_buffer_t *buffer) if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS)) return; + /* If we are producing SAFE_TO_INSERT_TATWEEL, then do two things: + * + * - If the places that the Arabic shaper marked as SAFE_TO_INSERT_TATWEEL, + * are UNSAFE_TO_BREAK, then clear the SAFE_TO_INSERT_TATWEEL, + * - Any place that is SAFE_TO_INSERT_TATWEEL, is also now UNSAFE_TO_BREAK. + * + * We couldn't make this interaction earlier. It has to be done here. + */ + bool flip_tatweel = buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL; + + bool clear_concat = (buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0; + hb_glyph_info_t *info = buffer->info; foreach_cluster (buffer, start, end) @@ -1148,9 +1160,20 @@ hb_propagate_flags (hb_buffer_t *buffer) unsigned int mask = 0; for (unsigned int i = start; i < end; i++) mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED; - if (mask) - for (unsigned int i = start; i < end; i++) - info[i].mask |= mask; + + if (flip_tatweel) + { + if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) + mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL; + if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL) + mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + } + + if (clear_concat) + mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + + for (unsigned int i = start; i < end; i++) + info[i].mask = mask; } } diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc index b331a048b6..ed2748b828 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc @@ -331,7 +331,7 @@ arabic_joining (hb_buffer_t *buffer) if (entry->prev_action != NONE && prev != UINT_MAX) { info[prev].arabic_shaping_action() = entry->prev_action; - buffer->unsafe_to_break (prev, i + 1); + buffer->safe_to_insert_tatweel (prev, i + 1); } else { @@ -365,7 +365,7 @@ arabic_joining (hb_buffer_t *buffer) if (entry->prev_action != NONE && prev != UINT_MAX) { info[prev].arabic_shaping_action() = entry->prev_action; - buffer->unsafe_to_break (prev, buffer->len); + buffer->safe_to_insert_tatweel (prev, buffer->len); } else if (2 <= state && state <= 5) /* States that have a possible prev_action. */ { diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh index 4f09fa805e..e45ea30e60 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh @@ -90,263 +90,264 @@ #pragma GCC diagnostic pop static const uint8_t -hb_use_u8[1842] = +hb_use_u8[3083] = { - 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 5, - 6, 7, 3, 8, 3, 3, 9, 3, 10, 3, 3, 11, 3, 12, 13, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 14, 0, 0, 1, 1, 2, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, - 1, 11, 12, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 19, - 1, 1, 20, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 22, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24, 25, 26, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 27, 28, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 30, 31, 1, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 1, 46, 47, - 48, 1, 49, 49, 49, 49, 50, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 51, 52, 1, 1, - 1, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 49, 54, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 55, 1, - 1, 1, 1, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 57, 58, 1, 1, 1, 1, 1, 1, 59, 1, 1, 1, 1, - 1, 1, 60, 61, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, O, O, O, O, O, GB, O, O, B, B, B, B, B, B, - O, O, GB, O, O, O, O, WJ, O, O, O, O,FMPst,FMPst, O, O, - O, GB, O, O, O, CGJ, B, O, O, O, O, O, B, B, B, B, - B,VMAbv,VMAbv,VMAbv,VMAbv,VMAbv, O, O, B, O, O,VMAbv, O, O, B,CMBlw, - CMBlw,CMBlw,VMAbv,VMAbv,VMAbv,VMPst, B, B, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, - VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VPst, VPst, VPst, VPst, H, VPre, VPst, O,VMAbv, - VMBlw, O, O, VAbv, VBlw, VBlw, B, B, VBlw, VBlw, GB,VMAbv,VMPst,VMPst, O, B, - B, B, B, O, O, B, B, O, B, B, B, O, B, O, VBlw, O, - O, VPre, VPre, O, O, VPre, VPre, H, O, O, O, O, O, VPst, B, B, - O, B, B, O,FMAbv, O, O,VMAbv,VMAbv,VMPst, B, B, B, O, O, O, - O, B, O, B, B, O,CMBlw, O, VPst, VPre, VPst, VBlw, VBlw, O, O, O, - O, VAbv, VAbv, O, O, VAbv, VAbv, H, O, O, O,VMBlw, O, O,VMAbv,CMAbv, - GB, GB, O, MBlw, O, O, VBlw, VAbv, O, VAbv, VAbv, VAbv, O, VPst, VPst, H, - O, O, O, B,VMAbv,VMAbv,VMAbv,CMAbv,CMAbv,CMAbv, O,VMAbv,VMPst,VMPst,CMBlw, B, - VPst, VAbv, O, VAbv, VAbv, VAbv, O, B, O, O, O, O,VMAbv, O, O, O, - VPst, VPst, VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre,VMAbv,VMPst, - VMPst,VMPst,VMAbv, B, B, B,CMBlw, B, VAbv, VAbv, VPst, O, VAbv, VAbv, VAbv, O, - VAbv, VAbv, O, VAbv, VBlw, O, B,VMAbv,VMPst,VMPst, O, VPst, VPst, O, O, CS, - CS, O,VMAbv,VMAbv,VMPst,VMPst, B, B, B, VAbv, VAbv, B, VPst, VPst, VPst, VPst, - VPst, VBlw, VBlw, O, VPre, VPre, VPre, H, R, O, O, O, HVM, O, VPst, VPst, - VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst, VBlw, VBlw, - O, O, O, FBlw, O, FBlw, O,CMAbv, O, O, O, O, VPst, VPre, O,CMBlw, - VBlw, VAbv, VAbv, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw,VMAbv, O, VBlw, VAbv, - VMAbv,VMAbv, VBlw, O,VMAbv,VMAbv, B, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, - SUB, SUB, SUB, O, O, O, O, O, FBlw, O, B, B, B, VPst, VPst, VAbv, - VAbv, VBlw, VBlw, VPre, VAbv, VAbv, VAbv, VAbv,VMAbv,VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, - MBlw, B, B, B, O, GB, O, O, GB, O, B, B, VPst, VPst, VBlw, VBlw, - B, B, B, B, MBlw, MBlw, MBlw, B, VPst,VMPst,VMPst, B, B, VPst, VPst,VMPst, - VMPst,VMPst,VMPst,VMPst, B, B, B, VAbv, VAbv, VAbv, VAbv, B, B, B, B, B, - MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMPst,VMPst,VMPst,VMPst,VMBlw, B,VMPst, B, B, - VMPst,VMPst, VPst, VAbv, O, O, B, B, VAbv, VBlw, VBlw, VPst, O, O, VPst, O, - O, O, B, O, VAbv, VBlw, CGJ, CGJ, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, - VPre, VPre, VPre, VPre, VPre, VPre, VPre, VPre,VMAbv,VMPst, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv, - FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, O, O, O, O, B, CGJ, CGJ, CGJ, - WJ, CGJ, GB, GB, GB, GB, GB,CMAbv,CMAbv, B, B,CMBlw, B, O, GB, B, - B, B, VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, FPst, FPst, - VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw,VMAbv,FMBlw,VMPst,VMPst, O, O, VAbv, VPre, - VPst, VAbv, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, SUB, SUB, SUB, O, Sk, VPst, - VAbv, VPst, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre, VPre, VPre, VPre, VAbv,VMAbv,VMAbv, - VAbv,VMAbv,VMAbv, O, O,VMBlw,VMAbv,VMAbv,VMAbv, FAbv,VMPst, B, B, B,CMAbv, VPst, - VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, VPre, VPre, VAbv, VAbv, H, B, - B, B, O, O, O,SMAbv,SMBlw,SMAbv,SMAbv,SMAbv,SMAbv,SMAbv,SMAbv,SMAbv,VMAbv, FAbv, - VMPst, B, VAbv, VBlw, VPre, VPst, VAbv, VAbv, VPst, IS, SUB, SUB, B, B, B, B, - CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv, FAbv, FAbv,CMBlw,CMBlw, SUB, SUB, - VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv, FAbv, FAbv, FAbv, FAbv,VMPre,VMPre, - FMAbv,CMBlw,VMAbv,VMAbv,VMAbv, O,VMBlw,VMBlw,VMBlw,VMBlw,VMBlw,VMBlw,VMAbv,VMAbv,VMAbv,VMPst, - VMBlw,VMBlw,VMBlw, O, O, O,VMAbv, CS, CS,VMPst,VMAbv,VMAbv, GB, O, O, O, - O,FMAbv, O, O, O, WJ, ZWNJ, CGJ, WJ, WJ, O, O, WJ, WJ, WJ, WJ, - WJ, O, WJ, WJ, WJ, WJ,FMPst, O, O, O,VMAbv, O, O, O, O, O, - O, H, B, B, VAbv, B, B, B, H, B, VPst, VBlw, VAbv, VPst, VBlw, O, - O, O, MPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, H,VMAbv, O, O,VMAbv,VMAbv, - B, B, O, O, B, VAbv, B, B, VAbv, VAbv, VAbv, VAbv, VAbv,VMBlw,VMBlw,VMBlw, - O, O, B, B, B, VBlw, VBlw, VBlw, VAbv, VBlw, VBlw, VBlw, VBlw, FAbv, FAbv, FAbv, - FPst, VPst,VMAbv,VMAbv, FAbv,VMPst, B, B, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, - O, O, B, VAbv, O, B, B,VMAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre, VPre, VAbv, - VBlw, MPst, MPre, MAbv, MBlw, O, B, B, B, FAbv, FAbv, FPst, O, O, GB, GB, - GB, O, O, O, B,VMPst,VMAbv,VMPst, B, B, VAbv, B, VAbv, VAbv, VBlw, B, - B, VAbv, B, B, VAbv,VMAbv, B,VMAbv, B, O, B, B, B, VPre, VBlw, VAbv, - VPre, VPst, O,VMPst, IS, O, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O,VMPst, VBlw, - O, O, CGJ, CGJ, CGJ, CGJ, WJ, O, O, O, B, VBlw, VBlw, VBlw, VPst,VMBlw, - VMBlw,VMAbv,CMBlw,CMBlw,CMBlw, O, O, O, O, IS, B,CMBlw,CMBlw, O,VMAbv,VMAbv, - VMAbv,CMAbv, B, B, O, VAbv, VAbv, O, O, O, B, B,VMBlw,VMBlw,VMBlw, B, - B, B, B, B,CMBlw,CMBlw,CMBlw,CMBlw, O, O,VMPst,VMAbv,VMPst, CS, CS, B, - B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, - N, N, N, N, N, N, N, N, B, B, VAbv, B, B, VAbv, VAbv, B, - O, O, O, O, O, HN,VMAbv,VMAbv,VMPst, B, VPst, VPre, VPst, VBlw, VBlw, VAbv, - VAbv, VPst, VPst, H,CMBlw, O, O, O, VBlw, O,VMAbv,VMAbv,VMAbv, B, VPre, VBlw, - VAbv, VAbv, VBlw, VAbv, VAbv, IS,CMAbv, O, B, B, B, VPst, VPst, B, B, B, - B,CMBlw, VPre, VPst, VBlw, VBlw, H, B, R, R, O,FMBlw,CMBlw, VAbv, VBlw, O, - VPre,VMAbv,VMAbv, H,CMAbv,CMAbv, VAbv,CMBlw, VBlw, O, B, B, O,CMBlw,CMBlw, B, - VPst, VPst, VPst, O, O, VPre, O, O,VMAbv,VMAbv, B, VPst, VPre, VPst, VPst, VPst, - H,VMAbv,VMAbv,VMPst,CMBlw, B, O, O,FMAbv, B, CS, CS, O, O, VBlw, VPre, - VAbv, VPre, VPre, VPst, VPre,VMAbv,VMAbv,VMAbv, H,CMBlw,VMAbv,VMAbv,VMPst, H,CMBlw, O, - O, O, VPst,VMAbv,VMPst, H,VMPst, VAbv, VPre, VPst, VAbv, VAbv, H,CMBlw, O, MBlw, - MPre, MAbv, VBlw, VBlw, VPre, VAbv, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv,VMAbv,VMPst, H, - CMBlw, O, VPst, VPre, O, VPre, VPre, O, O,VMAbv,VMAbv, VPst, IS, R, MPst, R, - MPst,CMBlw, O, O, VAbv, VAbv, VPst, VPst,VMPst,VMPst, H, B, O, O, VPre, O, - O, O, B, VAbv, VBlw, VBlw, VAbv, VAbv, VBlw, B, B, B, B,FMBlw, VBlw,VMAbv, - VMAbv,VMAbv,VMAbv,VMPst, R, MBlw, MBlw, MBlw, MBlw, GB, O, GB, O, IS, VAbv, VAbv, - VAbv, VPst, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, - VMAbv,VMPst,CMAbv, IS, O, O, VBlw, VBlw, VBlw, O, O, O, SUB, SUB, VBlw, VPre, - VBlw, VAbv, VPst,VMAbv,VMAbv, O, VAbv, VAbv, VBlw, O, O, O, VAbv, O, VAbv, VAbv, - O, VAbv,VMAbv,VMAbv,CMBlw, VAbv, VBlw, IS, R, MBlw, VPst, VPst, VPst, O, VPst,VMAbv, - VMPst, IS, B, B, GB, VAbv, VBlw, VPre, VPst, O, H, H, H, H, H, H, - H, B, O, O, O,CMBlw, O, VBlw, VBlw, VBlw, O, O, O,VMBlw,VMBlw,VMBlw, - VMBlw, O, O,CMBlw,CMBlw, O, B, B,VMAbv, O,CMAbv,CMAbv,CMAbv,CMAbv,CMAbv,CMAbv, - CMAbv, B, + 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 14, 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 4, 2, 2, + 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 2, 2, 17, + 18, 19, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 33, 2, 2, 2, + 2, 34, 35, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 37, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 38, 39, 40, 41, 42, 43, 2, 44, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 46, 2, + 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 48, 49, 2, 2, 2, + 2, 2, 2, 2, 2, 50, 51, 2, 52, 2, 2, 53, 2, 2, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 2, 64, 65, 2, 66, 67, 68, 69, + 2, 70, 2, 71, 72, 73, 74, 2, 2, 75, 76, 77, 78, 2, 79, 2, + 2, 80, 80, 80, 80, 80, 80, 80, 80, 81, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 82, 83, 2, 2, 2, 2, 2, 2, 2, 84, + 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 80, 80, 80, 86, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 87, 88, 2, 2, 2, 2, 2, + 2, 2, 2, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 90, 2, 2, 91, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 92, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 93, 93, 94, 95, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 2, 2, 2, 2, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, + 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 8, 9, 9, 9, 9, 0, 0, 0, 7, 10, + 0, 2, 2, 2, 2, 11, 12, 0, 0, 9, 13, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 14, 15, 16, 17, 18, 19, 20, 14, 21, 22, + 23, 10, 24, 25, 18, 2, 2, 2, 2, 2, 18, 0, 2, 2, 2, 2, + 2, 0, 2, 2, 2, 2, 2, 2, 2, 26, 27, 28, 2, 2, 2, 7, + 28, 7, 28, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, + 2, 7, 7, 0, 2, 2, 0, 15, 16, 17, 18, 29, 30, 31, 30, 32, + 0, 0, 0, 0, 33, 0, 0, 2, 28, 2, 0, 0, 0, 0, 0, 7, + 34, 10, 13, 28, 2, 2, 7, 0, 28, 7, 2, 28, 7, 2, 0, 35, + 16, 17, 29, 0, 25, 36, 25, 37, 0, 38, 0, 0, 0, 28, 2, 7, + 7, 0, 0, 0, 2, 2, 2, 2, 2, 39, 40, 41, 0, 0, 0, 0, + 0, 10, 13, 28, 2, 2, 2, 2, 28, 2, 28, 2, 2, 2, 2, 2, + 2, 7, 2, 28, 2, 2, 0, 15, 16, 17, 18, 19, 25, 20, 33, 22, + 0, 0, 0, 0, 0, 28, 9, 39, 42, 10, 27, 28, 2, 2, 2, 7, + 28, 7, 2, 28, 2, 2, 0, 15, 43, 0, 0, 25, 20, 0, 0, 2, + 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 44, 28, 2, 2, 7, 0, + 2, 7, 2, 2, 0, 28, 7, 7, 2, 0, 28, 7, 0, 2, 7, 0, + 2, 2, 2, 2, 2, 2, 0, 0, 21, 14, 45, 0, 46, 31, 46, 32, + 0, 0, 0, 0, 33, 0, 0, 0, 0, 13, 27, 47, 2, 2, 2, 7, + 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 15, + 20, 14, 21, 45, 20, 36, 20, 37, 0, 0, 0, 25, 29, 2, 7, 0, + 0, 8, 27, 28, 2, 2, 2, 7, 2, 2, 2, 28, 2, 2, 0, 15, + 43, 0, 0, 33, 45, 0, 0, 0, 7, 48, 49, 0, 0, 0, 0, 0, + 0, 9, 27, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 50, 51, + 21, 21, 17, 29, 46, 31, 46, 32, 52, 0, 0, 0, 33, 0, 0, 0, + 28, 10, 27, 28, 2, 2, 2, 2, 2, 2, 2, 2, 7, 0, 2, 2, + 2, 2, 28, 2, 2, 2, 2, 28, 0, 2, 2, 2, 7, 0, 53, 0, + 33, 21, 20, 29, 29, 16, 46, 46, 23, 0, 21, 0, 0, 0, 0, 0, + 0, 2, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, + 0, 2, 2, 54, 54, 55, 0, 0, 16, 2, 2, 2, 2, 28, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 7, 0, 56, 19, 57, 20, 20, 18, 18, + 44, 19, 9, 29, 9, 2, 2, 58, 59, 59, 59, 59, 59, 60, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, + 0, 0, 0, 0, 62, 0, 0, 0, 0, 2, 2, 2, 2, 2, 63, 43, + 57, 64, 20, 20, 65, 66, 67, 68, 69, 2, 2, 2, 2, 2, 1, 0, + 3, 2, 2, 2, 21, 18, 2, 2, 70, 69, 71, 72, 63, 71, 27, 27, + 2, 50, 20, 51, 2, 2, 2, 2, 2, 2, 73, 74, 75, 27, 27, 76, + 77, 2, 2, 2, 2, 2, 27, 43, 0, 2, 57, 78, 0, 0, 0, 0, + 28, 2, 57, 45, 0, 0, 0, 0, 0, 2, 57, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 7, 2, 7, 57, 0, 0, 0, 0, 0, + 0, 2, 2, 79, 43, 20, 57, 18, 46, 46, 46, 46, 13, 80, 81, 82, + 83, 84, 85, 0, 0, 0, 0, 86, 0, 7, 0, 0, 28, 0, 87, 79, + 88, 2, 2, 2, 2, 7, 0, 0, 0, 40, 40, 89, 90, 2, 2, 2, + 2, 2, 2, 2, 2, 11, 7, 0, 0, 91, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 7, 20, 78, 43, 20, 92, 59, 0, + 0, 93, 94, 93, 93, 95, 96, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, + 0, 2, 2, 2, 2, 27, 0, 0, 0, 2, 2, 2, 2, 2, 7, 0, + 0, 2, 2, 2, 50, 97, 43, 0, 0, 2, 2, 98, 99, 100, 101, 59, + 61, 102, 14, 43, 20, 57, 19, 78, 46, 46, 74, 9, 9, 9, 103, 44, + 38, 9, 104, 72, 2, 2, 2, 2, 2, 2, 2, 105, 20, 18, 18, 20, + 46, 46, 20, 106, 2, 2, 2, 7, 0, 0, 0, 0, 0, 0, 107, 108, + 109, 109, 109, 0, 0, 0, 0, 0, 0, 104, 72, 2, 2, 2, 2, 2, + 2, 58, 59, 57, 23, 20, 110, 59, 2, 2, 2, 2, 105, 20, 21, 43, + 43, 100, 12, 0, 0, 0, 0, 0, 0, 2, 2, 59, 16, 46, 21, 111, + 100, 100, 100, 112, 113, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 28, + 2, 9, 44, 114, 114, 114, 9, 114, 114, 13, 114, 114, 114, 24, 0, 38, + 0, 0, 0, 115, 116, 9, 3, 0, 0, 0, 0, 0, 0, 0, 117, 0, + 0, 0, 0, 0, 0, 0, 4, 118, 119, 40, 40, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 119, 119, 120, 119, 119, 119, 119, 119, 119, 119, + 119, 0, 0, 121, 0, 0, 0, 0, 0, 0, 5, 121, 0, 0, 0, 0, + 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 2, 2, 2, 2, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, + 122, 2, 51, 2, 106, 2, 8, 2, 2, 2, 63, 17, 14, 0, 0, 29, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 27, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 123, 21, 21, 21, 21, 21, 21, 21, 124, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0, + 50, 2, 2, 2, 20, 20, 125, 114, 0, 2, 2, 2, 126, 18, 57, 18, + 111, 100, 127, 0, 0, 0, 0, 0, 0, 9, 128, 2, 2, 2, 2, 2, + 2, 2, 129, 21, 20, 18, 46, 130, 131, 132, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 50, 28, 2, 2, 2, 2, 2, 2, 2, 2, 8, 20, 57, + 97, 74, 133, 134, 135, 0, 0, 0, 0, 2, 136, 2, 2, 2, 2, 137, + 0, 28, 2, 40, 3, 0, 77, 13, 2, 51, 20, 138, 50, 51, 2, 2, + 103, 8, 7, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 139, 19, + 23, 0, 0, 140, 141, 0, 0, 0, 0, 2, 63, 43, 21, 78, 45, 142, + 0, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 0, 0, 0, 0, 0, + 4, 119, 119, 119, 119, 120, 0, 0, 0, 2, 2, 2, 2, 2, 7, 2, + 2, 2, 7, 2, 28, 2, 2, 2, 2, 2, 28, 2, 2, 2, 28, 7, + 0, 126, 18, 25, 29, 0, 0, 143, 144, 2, 2, 28, 2, 28, 2, 2, + 2, 2, 2, 2, 0, 12, 35, 0, 145, 2, 2, 11, 35, 0, 28, 2, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 2, 2, + 7, 2, 2, 9, 39, 0, 0, 0, 0, 2, 2, 2, 2, 2, 25, 36, + 0, 2, 2, 2, 114, 114, 114, 114, 114, 146, 2, 7, 0, 0, 0, 0, + 0, 2, 12, 12, 0, 0, 0, 0, 0, 7, 2, 2, 7, 2, 2, 2, + 2, 28, 2, 7, 0, 28, 2, 0, 0, 147, 148, 149, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 20, 20, 18, 18, 18, 20, 20, 132, 0, 0, 0, + 0, 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 2, 2, 2, 2, + 2, 51, 50, 51, 0, 0, 0, 0, 151, 9, 72, 2, 2, 2, 2, 2, + 2, 16, 17, 19, 14, 22, 35, 0, 0, 0, 29, 0, 0, 0, 0, 0, + 0, 9, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 126, 18, 20, 152, + 20, 19, 153, 154, 2, 2, 2, 2, 2, 0, 0, 63, 155, 0, 0, 0, + 0, 2, 11, 0, 0, 0, 0, 0, 0, 2, 63, 23, 18, 18, 18, 20, + 20, 106, 156, 0, 0, 157, 158, 29, 159, 28, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 21, 17, 20, 20, 160, 42, 0, 0, 0, + 44, 2, 2, 2, 7, 7, 2, 2, 28, 2, 2, 2, 2, 2, 2, 2, + 28, 2, 2, 2, 2, 2, 2, 2, 8, 16, 17, 19, 20, 161, 29, 0, + 0, 9, 9, 28, 2, 2, 2, 7, 28, 7, 2, 28, 2, 2, 56, 15, + 21, 14, 21, 45, 30, 31, 30, 32, 0, 0, 0, 0, 33, 0, 0, 0, + 2, 2, 21, 0, 9, 9, 9, 44, 0, 9, 9, 44, 0, 0, 0, 0, + 0, 2, 2, 63, 23, 18, 18, 18, 20, 21, 124, 13, 15, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 0, 162, 163, 0, 0, 0, 0, 0, 0, + 0, 16, 17, 18, 18, 64, 97, 23, 159, 9, 164, 7, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 63, 23, 18, 18, 0, 46, 46, 9, + 165, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 18, + 0, 21, 17, 18, 18, 19, 14, 80, 165, 36, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 8, 166, 23, 18, 20, 20, 164, 7, 0, 0, + 0, 2, 2, 2, 2, 2, 7, 41, 134, 21, 20, 18, 74, 19, 20, 0, + 0, 2, 2, 2, 7, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 16, + 17, 18, 19, 20, 103, 165, 35, 0, 0, 2, 2, 2, 7, 28, 0, 2, + 2, 2, 2, 28, 7, 2, 2, 2, 2, 21, 21, 16, 30, 31, 10, 167, + 168, 169, 170, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, + 2, 63, 23, 18, 18, 0, 20, 21, 27, 106, 0, 31, 0, 0, 0, 0, + 0, 50, 18, 20, 20, 20, 138, 2, 2, 2, 171, 172, 9, 13, 173, 70, + 174, 0, 0, 1, 145, 0, 0, 0, 0, 50, 18, 20, 14, 17, 18, 2, + 2, 2, 2, 156, 156, 156, 175, 175, 175, 175, 175, 175, 13, 176, 0, 28, + 0, 20, 18, 18, 29, 20, 20, 9, 165, 0, 59, 59, 59, 59, 59, 59, + 59, 64, 19, 80, 44, 0, 0, 0, 0, 2, 2, 2, 7, 2, 28, 2, + 2, 50, 20, 20, 29, 0, 36, 20, 25, 9, 158, 177, 173, 0, 0, 0, + 0, 2, 2, 2, 28, 7, 2, 2, 2, 2, 2, 2, 2, 2, 21, 21, + 45, 20, 33, 80, 66, 0, 0, 0, 0, 2, 178, 64, 45, 0, 0, 0, + 0, 179, 179, 179, 106, 7, 0, 0, 0, 9, 9, 9, 44, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 7, 0, 56, 180, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, + 38, 114, 24, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 56, + 35, 0, 4, 119, 119, 119, 120, 0, 0, 9, 9, 9, 47, 2, 2, 2, + 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 44, 2, 2, 2, 2, 2, 2, 9, 9, 2, 2, 42, 42, 42, 90, 0, + 0, O, O, O, GB, B, B, GB, O, O, WJ,FMPst,FMPst, O, CGJ, B, + O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, + B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, + VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, O, O, VPre, VPre, + O, VPre, H, O, VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, H, O,VMBlw,VMAbv, + CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, + B, O, CS, CS, O, B, VAbv, VAbv, B, R, O, HVM, O, O, FBlw, O, + CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB, SUB, O, SUB, SUB, O, FBlw, O, B, + VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst, + VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, + CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, + CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, + FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv, + VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, + FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, CS,VMPst, O,FMAbv, ZWNJ, CGJ, WJ, + WJ, WJ, O,FMPst, O, O, H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, + VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, + O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst, + VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, + HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R, O,FMBlw,CMBlw, VAbv, VPre, + VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, + VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R, MBlw, MBlw, GB, FBlw, + FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, H, H, O, VBlw, }; static const uint16_t -hb_use_u16[2056] = +hb_use_u16[768] = { 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10, 11, - 0, 0, 0, 0, 9, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 13, 9, 9, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 17, 25, - 26, 20, 21, 27, 28, 29, 30, 31, 32, 33, 21, 34, 35, 0, 17, 36, - 37, 20, 21, 38, 23, 39, 17, 40, 41, 42, 43, 44, 45, 46, 30, 0, - 47, 48, 21, 49, 50, 51, 17, 0, 52, 48, 21, 53, 50, 54, 17, 55, - 56, 48, 9, 57, 58, 59, 17, 0, 60, 61, 9, 62, 63, 64, 30, 65, - 66, 67, 9, 68, 69, 9, 70, 71, 72, 73, 74, 75, 76, 0, 0, 0, - 9, 9, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 0, 0, 0, 0, - 9, 85, 9, 86, 9, 87, 88, 89, 9, 9, 9, 90, 91, 92, 2, 0, - 93, 0, 9, 9, 9, 9, 9, 94, 95, 9, 96, 0, 0, 0, 0, 0, - 97, 98, 99,100, 30, 9,101,102, 9, 9,103, 9,104,105, 0, 0, - 9,106, 9, 9, 9,107,108,109, 2, 2, 0, 0, 0, 0, 0, 0, - 110, 9, 9,111,112, 2,113,114,115, 9,116, 9, 9, 9,117,118, - 9, 9,119,120,121, 0, 0, 0, 0, 0, 0, 0, 0,122,123,124, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,125, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10, 11, + 0, 0, 0, 0, 9, 12, 0, 0, 13, 9, 9, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 17, 25, 26, 20, 21, 27, 28, 29, 30, 31, + 32, 33, 21, 34, 35, 0, 17, 36, 37, 20, 21, 38, 23, 39, 17, 40, + 41, 42, 43, 44, 45, 46, 30, 0, 47, 48, 21, 49, 50, 51, 17, 0, + 52, 48, 21, 53, 50, 54, 17, 55, 56, 48, 9, 57, 58, 59, 17, 0, + 60, 61, 9, 62, 63, 64, 30, 65, 66, 67, 9, 68, 69, 9, 70, 71, + 72, 73, 74, 75, 76, 0, 0, 0, 9, 9, 77, 78, 79, 80, 81, 82, + 83, 84, 0, 0, 0, 0, 0, 0, 9, 85, 9, 86, 9, 87, 88, 89, + 9, 9, 9, 90, 91, 92, 2, 0, 93, 0, 9, 9, 9, 9, 9, 94, + 95, 9, 96, 0, 0, 0, 0, 0, 97, 98, 99,100, 30, 9,101,102, + 9, 9,103, 9,104,105, 0, 0, 9,106, 9, 9, 9,107,108,109, + 2, 2, 0, 0, 0, 0, 0, 0,110, 9, 9,111,112, 2,113,114, + 115, 9,116, 9, 9, 9,117,118, 9, 9,119,120,121, 0, 0, 0, + 0, 0, 0, 0, 0,122,123,124, 0, 0, 0, 0, 0, 0, 0,125, 126,127,128, 0, 0, 0,129,130,131, 0, 0, 0, 0, 0, 0,132, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,133, 0, 0, 0, - 0, 0, 0, 9, 9, 9,134,135, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,133, 0, 0, 0, 0, 0, 0, 9, 9, 9,134,135, 136, 9,137, 0, 9, 9, 9,138,139, 9, 9,140,141, 2,142,143, 9, 9,144, 9,145,146, 0, 0,147, 9, 9,148,149, 2,150, 98, 9, 9,151,152,153, 2, 9,154, 9, 9, 9,155,156, 0,157,158, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,159, 2, - 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, + 0, 0, 0, 0, 9, 9,159, 2,160, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,161, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0,163,163,164, 33,165, 0, 0, 0, 0, 166,167, 9,168, 94, 0, 0, 0, 0, 0, 0, 0, 69, 9,169, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9,170,171, 0, 0, 0, 0, 0, - 9, 9,172, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,173,170, 0, 0, 0, 0, - 0, 0, 0, 9,174,175, 0, 9,176, 0, 0,177,178, 0, 0, 0, - 179, 9, 9,180,181,182,183,184,185, 9, 9,186,187, 0, 0, 0, - 188, 9,189,190,191, 9, 9,192,185, 9, 9,193,194,105,195,102, - 9, 33,196,197, 0, 0, 0, 0,198,199, 94, 9, 9,200,201, 2, - 202, 20, 21,203,204,205,206,207, 0, 0, 0, 0, 0, 0, 0, 0, + 9,170,171, 0, 0, 0, 0, 0, 9, 9,172, 2, 0, 0, 0, 0, + 9, 9,173,170, 0, 0, 0, 0, 0, 0, 0, 9,174,175, 0, 9, + 176, 0, 0,177,178, 0, 0, 0,179, 9, 9,180,181,182,183,184, + 185, 9, 9,186,187, 0, 0, 0,188, 9,189,190,191, 9, 9,192, + 185, 9, 9,193,194,105,195,102, 9, 33,196,197, 0, 0, 0, 0, + 198,199, 94, 9, 9,200,201, 2,202, 20, 21,203,204,205,206,207, 9, 9, 9,208,209,210,211, 0,195, 9, 9,212,213, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,214,215,216,217, 0, 0, - 9, 9, 9,218,219, 2, 0, 0, 9, 9,220,221, 2, 0, 0, 0, - 9,222,223,103,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9,225,226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 227,228, 9,229,230, 2, 0, 0, 0, 0,231, 9, 9,232,233, 0, - 234, 9, 9,235,236,237, 9, 9,238,239, 0, 0, 0, 0, 0, 0, - 21, 9,214,240, 7, 9, 70, 18, 9,241, 73,242, 0, 0, 0, 0, - 243, 9, 9,244,245, 2,246, 9,247,248, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,249, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 98,250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 9, 9, 9,251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9,214,215,216,217, 0, 0, 9, 9, 9,218,219, 2, 0, 0, + 9, 9,220,221, 2, 0, 0, 0, 9,222,223,103,224, 0, 0, 0, + 9, 9,225,226, 0, 0, 0, 0,227,228, 9,229,230, 2, 0, 0, + 0, 0,231, 9, 9,232,233, 0,234, 9, 9,235,236,237, 9, 9, + 238,239, 0, 0, 0, 0, 0, 0, 21, 9,214,240, 7, 9, 70, 18, + 9,241, 73,242, 0, 0, 0, 0,243, 9, 9,244,245, 2,246, 9, + 247,248, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,249, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 98,250, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 9, 9, 9,251, 0, 0, 0, 0, 9, 9, 9, 9,252,253,254,254,255,256, 0, 0, 0, 0,257, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,258, 0, 0, - 9, 9, 9, 9, 9, 9,105, 70, 94,259, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,260, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 70,261,262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,263, 0, 9, 9,264, 2, - 9, 9, 9, 9,265, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, + 9, 9, 9, 9, 9,258, 0, 0, 9, 9, 9, 9, 9, 9,105, 70, + 94,259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,260, + 9, 9, 70,261,262, 0, 0, 0, 0, 9,263, 0, 9, 9,264, 2, + 9, 9, 9, 9,265, 2, 0, 0,129,129,129,129,129,129,129,129, 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,129, - 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 0, 4, 0, 0, 5, - 6, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, - 0, 0, 10, 2, 2, 2, 2, 2, 2, 2, 11, 12, 12, 0, 13, 14, - 2, 2, 15, 0, 16, 2, 2, 2, 2, 2, 17, 18, 19, 20, 21, 22, - 23, 24, 2, 2, 25, 10, 2, 2, 10, 2, 2, 2, 26, 27, 2, 28, - 28, 2, 2, 2, 2, 2, 29, 2, 30, 10, 3, 18, 19, 31, 32, 33, - 0, 34, 0, 35, 3, 0, 0, 36, 37, 27, 38, 39, 29, 40, 3, 41, - 42, 43, 44, 45, 46, 0, 27, 30, 0, 10, 2, 2, 47, 48, 0, 0, - 37, 27, 2, 35, 35, 2, 2, 2, 29, 27, 3, 18, 19, 49, 50, 51, - 0, 0, 52, 53, 54, 27, 2, 28, 29, 27, 3, 55, 0, 56, 0, 35, - 57, 0, 0, 0, 58, 27, 38, 10, 29, 3, 40, 29, 39, 9, 38, 10, - 2, 2, 3, 59, 60, 61, 62, 33, 0, 34, 0, 0, 63, 64, 2, 29, - 29, 2, 2, 2, 2, 2, 3, 65, 21, 66, 67, 45, 0, 68, 38, 0, - 69, 27, 2, 29, 2, 27, 3, 55, 0, 70, 0, 13, 71, 0, 0, 0, - 72, 2, 2, 29, 2, 2, 73, 74, 75, 76, 62, 77, 0, 34, 0, 39, - 54, 27, 2, 2, 2, 38, 10, 2, 35, 2, 2, 57, 2, 38, 78, 34, - 79, 80, 81, 82, 59, 0, 0, 0, 3, 38, 0, 0, 0, 0, 83, 0, - 2, 84, 85, 86, 2, 2, 27, 2, 2, 2, 2, 9, 87, 88, 89, 90, - 91, 92, 2, 93, 94, 94, 95, 94, 94, 94, 94, 94, 94, 94, 94, 96, - 0, 97, 0, 0, 2, 2, 98, 99,100,101,102,103, 2, 2,104,105, - 2,106,107,108,109,110,111,112,113,114, 2, 2,115,116,117,118, - 2, 2,119,120,121,122, 0, 39,121,123, 0, 0,121, 0, 0, 0, - 2, 2, 2, 29,124, 0, 0, 0, 2,125,126,127,128,129,130,131, - 132, 0, 0,133, 9, 39,134,135, 2, 2, 9, 0,136,137, 2, 2, - 2, 2,138, 0,139, 2, 2, 2, 2, 2, 2, 38,140,141,142, 0, - 143,144,145, 0, 2, 2, 2, 3, 2, 9, 0, 0, 2, 2, 2, 0, - 2, 2,146, 0, 2, 2, 38, 0, 2, 73,147, 0, 2,148,149,150, - 151,141,152,153,154, 12,155,156,157,158, 2, 2, 2,159,160,161, - 162,163, 2, 9, 0, 0,164,165,166, 0, 0, 0,167, 2, 2, 2, - 93,168,169,170, 2,171,172,173,174, 0, 0, 0, 2,175,176,177, - 178,179, 0, 0, 2, 2, 3, 27,180,181,182,181,183,181,184, 46, - 0,185,186, 0, 0, 0,187, 0, 0, 0,188,189,136, 4, 0, 0, - 0, 0,190,191,192,192,192,192, 0,193, 0, 0, 6,193, 0, 0, - 194, 0, 0, 0, 0, 0, 0, 9, 2, 2, 0, 39, 0, 0, 0,195, - 196,197, 11, 2, 98,198, 0,199, 2, 0, 0, 0,112, 2, 2, 2, - 2,200,201,201,201,202, 0, 0, 12, 12, 12, 12,203, 0, 0,204, - 2,205,206,207, 2,208,209,210,211, 0, 0, 0,212, 2, 2, 2, - 213, 79,127,214,215, 0, 0, 0, 2,216, 2, 2, 2, 2,217,218, - 219,220, 0, 0,221, 2, 2,222, 27,223,224,225,226,227,114,228, - 229, 0, 0, 0, 2, 2,230,231, 0,232, 0, 0, 98,233,234,235, - 236,236,236,236, 0, 0, 0,188,192,192,237, 0, 2, 2, 38, 2, - 38, 35, 2, 2, 35, 2, 35, 9,238, 68, 0,239, 2, 27, 27, 2, - 2, 3,240,241, 2,242, 39, 2, 3, 0, 0, 0, 0, 0, 27, 38, - 2,243, 0, 0, 2, 2,244,245, 2,246,181,181,247, 9, 0, 0, - 248,249, 0, 0, 29, 38, 2, 2, 27, 9, 27, 0,250,251, 2, 2, - 2, 2,252,160,253,254, 0, 0,255,256,256,256,256,257, 2, 2, - 258,259, 0,260,261, 2, 2, 2,262,263,264, 0,265, 0, 0, 0, - 266, 2, 2, 2, 2,208,253,267,268,269, 2, 2, 0,270, 0, 0, - 271, 0, 0, 0, 98,272,160,252,273, 0,274,275, 27, 2, 2, 2, - 2, 2, 2, 75,252,276, 0, 58, 2, 38, 29, 35, 2, 2, 2, 35, - 2, 2, 2, 11,262, 20,277, 0, 12, 27, 2, 28, 29, 27,278,279, - 21,280, 32, 33, 0, 34, 0, 10,106,281, 12,194, 12,194, 0, 0, - 2,282,160,253,283,284, 0, 0, 2, 2, 3,285,286, 0, 0, 0, - 262,160,287,288,289, 9, 0, 0, 2, 2, 2, 98,272, 83,128,290, - 291, 0, 0, 0, 0, 0, 2, 83, 75,160,263,292,245, 0, 0, 0, - 2, 2, 11,293,253,294, 9, 0, 2, 2, 38,295, 79,296, 20, 0, - 2, 38, 0, 0, 2, 2, 2,262,297,298,299, 0, 2, 38, 57, 2, - 2, 40, 2, 2,201,300,301,302,303, 0, 0, 0, 2, 2, 10, 2, - 282,160,304,305,306,307, 0, 0,308,252,309, 2,310,311,312,313, - 0,314, 0, 0,308,315, 19, 2, 2,316,317,318,318,319,320, 57, - 89,321,252,290,322, 94, 94, 94,323,324, 0, 0, 2, 38, 35, 2, - 113,325,326,327,328,329, 0, 0, 2, 35, 29, 2, 2, 2,106,330, - 50,331, 0, 0,332,333, 0, 0,334,335, 9, 0, 12,180, 0, 0, - 2, 2, 38,336,337,160,160,160,160,160,160,160,160,160, 0,338, - 339, 0, 0, 0, 0, 9, 0, 0, 2, 3, 0, 0, 2, 2, 3,340, - 188,192,191, 0, 12,266, 2, 3, 2, 2, 3, 10, 2, 2, 2,341, - 2, 2, 2, 12, 2,342,343, 0, }; +static inline unsigned +hb_use_b4 (const uint8_t* a, unsigned i) +{ + return (a[i>>1]>>((i&1u)<<2))&15u; +} static inline uint_fast8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[466+(((hb_use_u16[992+(((hb_use_u16[((hb_use_u8[226+(((hb_use_u8[u>>2>>2>>4>>4])<<4)+((u>>2>>2>>4)&15u))])<<4)+((u>>2>>2)&15u)])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:O; + return u<921600u?hb_use_u8[2721+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; } #undef B @@ -392,5 +393,26 @@ hb_use_get_category (unsigned u) #undef VMPre +#ifdef HB_USE_TABLE_MAIN +int main (int argc, char **argv) +{ + if (argc != 2) + { + for (unsigned u = 0; u < 0x10FFFFu; u++) + printf ("U+%04X %d\n", u, hb_use_get_category (u)); + return 0; + } + + hb_codepoint_t u; + sscanf (argv[1], "%x", &u); + + printf ("%d\n", hb_use_get_category (u)); + + return 0; +} + +#endif + + #endif /* HB_OT_SHAPER_USE_TABLE_HH */ /* == End of generated table == */ diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh index 173fe4a2fb..61b142238e 100644 --- a/thirdparty/harfbuzz/src/hb-repacker.hh +++ b/thirdparty/harfbuzz/src/hb-repacker.hh @@ -29,10 +29,9 @@ #include "hb-open-type.hh" #include "hb-map.hh" -#include "hb-priority-queue.hh" -#include "hb-serialize.hh" #include "hb-vector.hh" #include "graph/graph.hh" +#include "graph/gsubgpos-graph.hh" #include "graph/serialize.hh" using graph::graph_t; @@ -42,6 +41,143 @@ using graph::graph_t; * docs/repacker.md */ +struct lookup_size_t +{ + unsigned lookup_index; + size_t size; + unsigned num_subtables; + + static int cmp (const void* a, const void* b) + { + return cmp ((const lookup_size_t*) a, + (const lookup_size_t*) b); + } + + static int cmp (const lookup_size_t* a, const lookup_size_t* b) + { + double subtables_per_byte_a = (double) a->num_subtables / (double) a->size; + double subtables_per_byte_b = (double) b->num_subtables / (double) b->size; + if (subtables_per_byte_a == subtables_per_byte_b) { + return b->lookup_index - a->lookup_index; + } + + double cmp = subtables_per_byte_b - subtables_per_byte_a; + if (cmp < 0) return -1; + if (cmp > 0) return 1; + return 0; + } +}; + +static inline +bool _presplit_subtables_if_needed (graph::gsubgpos_graph_context_t& ext_context) +{ + // For each lookup this will check the size of subtables and split them as needed + // so that no subtable is at risk of overflowing. (where we support splitting for + // that subtable type). + // + // TODO(grieger): de-dup newly added nodes as necessary. Probably just want a full de-dup + // pass after this processing is done. Not super necessary as splits are + // only done where overflow is likely, so de-dup probably will get undone + // later anyways. + for (unsigned lookup_index : ext_context.lookups.keys ()) + { + graph::Lookup* lookup = ext_context.lookups.get(lookup_index); + if (!lookup->split_subtables_if_needed (ext_context, lookup_index)) + return false; + } + + return true; +} + +/* + * Analyze the lookups in a GSUB/GPOS table and decide if any should be promoted + * to extension lookups. + */ +static inline +bool _promote_extensions_if_needed (graph::gsubgpos_graph_context_t& ext_context) +{ + // Simple Algorithm (v1, current): + // 1. Calculate how many bytes each non-extension lookup consumes. + // 2. Select up to 64k of those to remain as non-extension (greedy, highest subtables per byte first) + // 3. Promote the rest. + // + // Advanced Algorithm (v2, not implemented): + // 1. Perform connected component analysis using lookups as roots. + // 2. Compute size of each connected component. + // 3. Select up to 64k worth of connected components to remain as non-extensions. + // (greedy, highest subtables per byte first) + // 4. Promote the rest. + + // TODO(garretrieger): support extension demotion, then consider all lookups. Requires advanced algo. + // TODO(garretrieger): also support extension promotion during iterative resolution phase, then + // we can use a less conservative threshold here. + // TODO(grieger): skip this for the 24 bit case. + if (!ext_context.lookups) return true; + + hb_vector_t<lookup_size_t> lookup_sizes; + lookup_sizes.alloc (ext_context.lookups.get_population ()); + + for (unsigned lookup_index : ext_context.lookups.keys ()) + { + const graph::Lookup* lookup = ext_context.lookups.get(lookup_index); + hb_set_t visited; + lookup_sizes.push (lookup_size_t { + lookup_index, + ext_context.graph.find_subgraph_size (lookup_index, visited), + lookup->number_of_subtables (), + }); + } + + lookup_sizes.qsort (); + + size_t lookup_list_size = ext_context.graph.vertices_[ext_context.lookup_list_index].table_size (); + size_t l2_l3_size = lookup_list_size; // Lookup List + Lookups + size_t l3_l4_size = 0; // Lookups + SubTables + size_t l4_plus_size = 0; // SubTables + their descendants + + // Start by assuming all lookups are using extension subtables, this size will be removed later + // if it's decided to not make a lookup extension. + for (auto p : lookup_sizes) + { + unsigned subtables_size = p.num_subtables * 8; + l3_l4_size += subtables_size; + l4_plus_size += subtables_size; + } + + bool layers_full = false; + for (auto p : lookup_sizes) + { + const graph::Lookup* lookup = ext_context.lookups.get(p.lookup_index); + if (lookup->is_extension (ext_context.table_tag)) + // already an extension so size is counted by the loop above. + continue; + + if (!layers_full) + { + size_t lookup_size = ext_context.graph.vertices_[p.lookup_index].table_size (); + hb_set_t visited; + size_t subtables_size = ext_context.graph.find_subgraph_size (p.lookup_index, visited, 1) - lookup_size; + size_t remaining_size = p.size - subtables_size - lookup_size; + + l2_l3_size += lookup_size; + l3_l4_size += lookup_size + subtables_size; + l3_l4_size -= p.num_subtables * 8; + l4_plus_size += subtables_size + remaining_size; + + if (l2_l3_size < (1 << 16) + && l3_l4_size < (1 << 16) + && l4_plus_size < (1 << 16)) continue; // this lookup fits within all layers groups + + layers_full = true; + } + + if (!ext_context.lookups.get(p.lookup_index)->make_extension (ext_context, p.lookup_index)) + return false; + } + + return true; +} + static inline bool _try_isolating_subgraphs (const hb_vector_t<graph::overflow_record_t>& overflows, graph_t& sorted_graph) @@ -157,7 +293,8 @@ template<typename T> inline hb_blob_t* hb_resolve_overflows (const T& packed, hb_tag_t table_tag, - unsigned max_rounds = 20) { + unsigned max_rounds = 20, + bool recalculate_extensions = false) { graph_t sorted_graph (packed); sorted_graph.sort_shortest_distance (); @@ -167,13 +304,31 @@ hb_resolve_overflows (const T& packed, return graph::serialize (sorted_graph); } + graph::gsubgpos_graph_context_t ext_context (table_tag, sorted_graph); if ((table_tag == HB_OT_TAG_GPOS || table_tag == HB_OT_TAG_GSUB) && will_overflow) { + if (recalculate_extensions) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Splitting subtables if needed."); + if (!_presplit_subtables_if_needed (ext_context)) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Subtable splitting failed."); + return nullptr; + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, "Promoting lookups to extensions if needed."); + if (!_promote_extensions_if_needed (ext_context)) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Extensions promotion failed."); + return nullptr; + } + } + DEBUG_MSG (SUBSET_REPACK, nullptr, "Assigning spaces to 32 bit subgraphs."); if (sorted_graph.assign_spaces ()) sorted_graph.sort_shortest_distance (); + else + sorted_graph.sort_shortest_distance_if_needed (); } unsigned round = 0; diff --git a/thirdparty/harfbuzz/src/hb-set.cc b/thirdparty/harfbuzz/src/hb-set.cc index 5bf9d7c8cd..0270b21998 100644 --- a/thirdparty/harfbuzz/src/hb-set.cc +++ b/thirdparty/harfbuzz/src/hb-set.cc @@ -145,7 +145,7 @@ hb_set_set_user_data (hb_set_t *set, * Since: 0.9.2 **/ void * -hb_set_get_user_data (hb_set_t *set, +hb_set_get_user_data (const hb_set_t *set, hb_user_data_key_t *key) { return hb_object_get_user_data (set, key); diff --git a/thirdparty/harfbuzz/src/hb-set.h b/thirdparty/harfbuzz/src/hb-set.h index 56902c267e..93636ab5d7 100644 --- a/thirdparty/harfbuzz/src/hb-set.h +++ b/thirdparty/harfbuzz/src/hb-set.h @@ -77,7 +77,7 @@ hb_set_set_user_data (hb_set_t *set, hb_bool_t replace); HB_EXTERN void * -hb_set_get_user_data (hb_set_t *set, +hb_set_get_user_data (const hb_set_t *set, hb_user_data_key_t *key); diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.cc b/thirdparty/harfbuzz/src/hb-shape-plan.cc index 8dbb661cd2..9e513c0458 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.cc +++ b/thirdparty/harfbuzz/src/hb-shape-plan.cc @@ -358,8 +358,8 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, * Since: 0.9.7 **/ void * -hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, - hb_user_data_key_t *key) +hb_shape_plan_get_user_data (const hb_shape_plan_t *shape_plan, + hb_user_data_key_t *key) { return hb_object_get_user_data (shape_plan, key); } diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.h b/thirdparty/harfbuzz/src/hb-shape-plan.h index fc7c041899..aaf5cf9c45 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.h +++ b/thirdparty/harfbuzz/src/hb-shape-plan.h @@ -102,8 +102,8 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, hb_bool_t replace); HB_EXTERN void * -hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, - hb_user_data_key_t *key); +hb_shape_plan_get_user_data (const hb_shape_plan_t *shape_plan, + hb_user_data_key_t *key); HB_EXTERN hb_bool_t diff --git a/thirdparty/harfbuzz/src/hb-subset-repacker.cc b/thirdparty/harfbuzz/src/hb-subset-repacker.cc index 03e3feb1f6..55ca48d709 100644 --- a/thirdparty/harfbuzz/src/hb-subset-repacker.cc +++ b/thirdparty/harfbuzz/src/hb-subset-repacker.cc @@ -25,18 +25,24 @@ #include "hb-repacker.hh" #ifdef HB_EXPERIMENTAL_API + /** * hb_subset_repack_or_fail: + * @table_tag: tag of the table being packed, needed to allow table specific optimizations. * @hb_objects: raw array of struct hb_object_t, which provides * object graph info * @num_hb_objs: number of hb_object_t in the hb_objects array. * * Given the input object graph info, repack a table to eliminate * offset overflows. A nullptr is returned if the repacking attempt fails. + * Table specific optimizations (eg. extension promotion in GSUB/GPOS) may be performed. + * Passing HB_TAG_NONE will disable table specific optimizations. * * Since: EXPERIMENTAL **/ -hb_blob_t* hb_subset_repack_or_fail (hb_object_t* hb_objects, unsigned num_hb_objs) +hb_blob_t* hb_subset_repack_or_fail (hb_tag_t table_tag, + hb_object_t* hb_objects, + unsigned num_hb_objs) { hb_vector_t<const hb_object_t *> packed; packed.alloc (num_hb_objs + 1); @@ -44,6 +50,9 @@ hb_blob_t* hb_subset_repack_or_fail (hb_object_t* hb_objects, unsigned num_hb_ob for (unsigned i = 0 ; i < num_hb_objs ; i++) packed.push (&(hb_objects[i])); - return hb_resolve_overflows (packed, HB_OT_TAG_GSUB); + return hb_resolve_overflows (packed, + table_tag, + 20, + true); } #endif diff --git a/thirdparty/harfbuzz/src/hb-subset-repacker.h b/thirdparty/harfbuzz/src/hb-subset-repacker.h index e28f879362..245cf60765 100644 --- a/thirdparty/harfbuzz/src/hb-subset-repacker.h +++ b/thirdparty/harfbuzz/src/hb-subset-repacker.h @@ -70,7 +70,8 @@ struct hb_object_t typedef struct hb_object_t hb_object_t; HB_EXTERN hb_blob_t* -hb_subset_repack_or_fail (hb_object_t* hb_objects, +hb_subset_repack_or_fail (hb_tag_t table_tag, + hb_object_t* hb_objects, unsigned num_hb_objs); #endif diff --git a/thirdparty/harfbuzz/src/hb-ucd-table.hh b/thirdparty/harfbuzz/src/hb-ucd-table.hh index 9e76ca460b..14734c91ea 100644 --- a/thirdparty/harfbuzz/src/hb-ucd-table.hh +++ b/thirdparty/harfbuzz/src/hb-ucd-table.hh @@ -1068,2860 +1068,6 @@ _hb_ucd_dm2_u64_map[388] = #ifndef HB_OPTIMIZE_SIZE static const uint8_t -_hb_ucd_u8[33120] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 27, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 28, 26, 29, 30, 31, 32, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 33, 34, 34, 34, 34, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 26, 56, 57, 58, 58, 58, 58, 59, 26, 26, 60, 58, 58, 58, 58, 58, - 58, 58, 26, 61, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 26, 62, 58, 63, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 64, 26, 26, 65, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 66, 67, 68, 58, 58, 58, 58, 69, 58, - 58, 58, 58, 58, 58, 58, 58, 70, 71, 72, 73, 74, 75, 76, 58, 77, - 78, 79, 58, 80, 81, 58, 82, 83, 84, 85, 75, 86, 87, 88, 58, 58, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 89, 26, 26, 26, 26, 26, 26, 26, 90, 91, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 92, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 93, 58, 58, 58, 58, 58, 58, 26, 94, 58, 58, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 95, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 96, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 97, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 98, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 29, 21, 21, 21, 23, 21, 21, 21, 22, 18, 21, 25, 21, 17, 21, 21, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 25, 25, 25, 21, - 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 21, 18, 24, 16, - 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 29, 21, 23, 23, 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, - 26, 25, 15, 15, 24, 5, 21, 21, 24, 15, 7, 19, 15, 15, 15, 21, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, 9, 9, 9, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 5, 5, - 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, - 9, 5, 9, 5, 9, 5, 9, 5, 5, 9, 5, 9, 5, 9, 5, 9, - 5, 9, 5, 9, 5, 9, 5, 9, 5, 5, 9, 5, 9, 5, 9, 5, - 9, 5, 9, 5, 9, 5, 9, 5, 9, 9, 5, 9, 5, 9, 5, 5, - 5, 9, 9, 5, 9, 5, 9, 9, 5, 9, 9, 9, 5, 5, 9, 9, - 9, 9, 5, 9, 9, 5, 9, 9, 9, 5, 5, 5, 9, 9, 5, 9, - 9, 5, 9, 5, 9, 5, 9, 9, 5, 9, 5, 5, 9, 5, 9, 9, - 5, 9, 9, 9, 5, 9, 5, 9, 9, 5, 5, 7, 9, 5, 5, 5, - 7, 7, 7, 7, 9, 8, 5, 9, 8, 5, 9, 8, 5, 9, 5, 9, - 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 5, 9, 5, - 5, 9, 8, 5, 9, 5, 9, 9, 9, 5, 9, 5, 9, 5, 9, 5, - 9, 5, 9, 5, 5, 5, 5, 5, 5, 5, 9, 9, 5, 9, 9, 5, - 5, 9, 5, 9, 9, 9, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, - 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 24, 24, 24, 24, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 6, 6, 6, 6, 6, 24, 24, 24, 24, 24, 24, 24, 6, 24, 6, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 9, 5, 9, 5, 6, 24, 9, 5, 2, 2, 6, 5, 5, 5, 21, 9, - 2, 2, 2, 2, 24, 24, 9, 21, 9, 9, 9, 2, 9, 2, 9, 9, - 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 9, - 5, 5, 9, 9, 9, 5, 5, 5, 9, 5, 9, 5, 9, 5, 9, 5, - 5, 5, 5, 5, 9, 5, 25, 9, 5, 9, 9, 5, 5, 9, 9, 9, - 9, 5, 26, 12, 12, 12, 12, 12, 11, 11, 9, 5, 9, 5, 9, 5, - 9, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 5, - 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 2, 2, 6, 21, 21, 21, 21, 21, 21, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 21, 17, 2, 2, 26, 26, 23, - 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 17, 12, - 21, 12, 12, 21, 12, 12, 21, 12, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 7, - 7, 7, 7, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 25, 25, 25, 21, 21, 23, 21, 21, 26, 26, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 21, 1, 21, 21, 21, - 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 21, 21, 7, 7, - 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 21, 7, 12, 12, 12, 12, 12, 12, 12, 1, 26, 12, - 12, 12, 12, 12, 12, 6, 6, 12, 12, 26, 12, 12, 12, 12, 7, 7, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 7, 7, 7, 26, 26, 7, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 1, - 7, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 6, 6, 26, 21, 21, 21, 6, 2, 2, 12, 23, 23, - 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 6, 12, 12, 12, 6, 12, 12, 12, 12, 12, 2, 2, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 2, 2, 21, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 24, 7, 7, 7, 7, 7, 7, 2, - 1, 1, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12, 12, 12, 12, 12, 12, - 12, 12, 1, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 10, 12, 7, 10, 10, - 10, 12, 12, 12, 12, 12, 12, 12, 12, 10, 10, 10, 10, 12, 10, 10, - 7, 12, 12, 12, 12, 12, 12, 12, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 12, 12, 21, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 21, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 12, 10, 10, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 7, - 7, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, - 7, 2, 7, 2, 2, 2, 7, 7, 7, 7, 2, 2, 12, 7, 10, 10, - 10, 12, 12, 12, 12, 2, 2, 10, 10, 2, 2, 10, 10, 12, 7, 2, - 2, 2, 2, 2, 2, 2, 2, 10, 2, 2, 2, 2, 7, 7, 2, 7, - 7, 7, 12, 12, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 7, 7, 23, 23, 15, 15, 15, 15, 15, 15, 26, 23, 7, 21, 12, 2, - 2, 12, 12, 10, 2, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 7, - 7, 2, 7, 7, 2, 7, 7, 2, 7, 7, 2, 2, 12, 2, 10, 10, - 10, 12, 12, 2, 2, 2, 2, 12, 12, 2, 2, 12, 12, 12, 2, 2, - 2, 12, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 2, 7, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 12, 12, 7, 7, 7, 12, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 12, 12, 10, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, - 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, 2, 2, 12, 7, 10, 10, - 10, 12, 12, 12, 12, 12, 2, 12, 12, 10, 2, 10, 10, 12, 2, 2, - 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 21, 23, 2, 2, 2, 2, 2, 2, 2, 7, 12, 12, 12, 12, 12, 12, - 2, 12, 10, 10, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 7, - 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, 2, 2, 12, 7, 10, 12, - 10, 12, 12, 12, 12, 2, 2, 10, 10, 2, 2, 10, 10, 12, 2, 2, - 2, 2, 2, 2, 2, 12, 12, 10, 2, 2, 2, 2, 7, 7, 2, 7, - 26, 7, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 12, 7, 2, 7, 7, 7, 7, 7, 7, 2, 2, 2, 7, 7, - 7, 2, 7, 7, 7, 7, 2, 2, 2, 7, 7, 2, 7, 2, 7, 7, - 2, 2, 2, 7, 7, 2, 2, 2, 7, 7, 7, 2, 2, 2, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 10, 10, - 12, 10, 10, 2, 2, 2, 10, 10, 10, 2, 10, 10, 10, 12, 2, 2, - 7, 2, 2, 2, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, - 15, 15, 15, 26, 26, 26, 26, 26, 26, 23, 26, 2, 2, 2, 2, 2, - 12, 10, 10, 10, 12, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, - 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 12, 7, 12, 12, - 12, 10, 10, 10, 10, 2, 12, 12, 12, 2, 12, 12, 12, 12, 2, 2, - 2, 2, 2, 2, 2, 12, 12, 2, 7, 7, 7, 2, 2, 7, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 21, 15, 15, 15, 15, 15, 15, 15, 26, - 7, 12, 10, 10, 21, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, - 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 2, 2, 12, 7, 10, 12, - 10, 10, 10, 10, 10, 2, 12, 10, 10, 2, 10, 10, 12, 12, 2, 2, - 2, 2, 2, 2, 2, 10, 10, 2, 2, 2, 2, 2, 2, 7, 7, 2, - 2, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 12, 12, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 7, 10, 10, - 10, 12, 12, 12, 12, 2, 10, 10, 10, 2, 10, 10, 10, 12, 7, 26, - 2, 2, 2, 2, 7, 7, 7, 10, 15, 15, 15, 15, 15, 15, 15, 7, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 7, 7, 7, 7, 7, 7, - 2, 12, 10, 10, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 7, 7, 7, 7, 7, 7, - 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 12, 2, 2, 2, 2, 10, - 10, 10, 12, 12, 12, 2, 12, 2, 10, 10, 10, 10, 10, 10, 10, 10, - 2, 2, 10, 10, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 12, 7, 7, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, 2, 23, - 7, 7, 7, 7, 7, 7, 6, 12, 12, 12, 12, 12, 12, 12, 12, 21, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 7, 7, 2, 7, 2, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, - 7, 7, 7, 7, 2, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 12, 7, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 2, 2, - 7, 7, 7, 7, 7, 2, 6, 2, 12, 12, 12, 12, 12, 12, 2, 2, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 7, 7, 7, 7, - 7, 26, 26, 26, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 26, 21, 26, 26, 26, 12, 12, 26, 26, 26, 26, 26, 26, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 26, 12, 26, 12, 26, 12, 22, 18, 22, 18, 10, 10, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, - 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 10, - 12, 12, 12, 12, 12, 21, 12, 12, 7, 7, 7, 7, 7, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 26, 26, - 26, 26, 26, 26, 26, 26, 12, 26, 26, 26, 26, 26, 26, 2, 26, 26, - 21, 21, 21, 21, 21, 26, 26, 26, 26, 21, 21, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 10, 12, 12, 12, - 12, 10, 12, 12, 12, 12, 12, 12, 10, 12, 12, 10, 10, 12, 12, 7, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 21, 21, 21, 21, - 7, 7, 7, 7, 7, 7, 10, 10, 12, 12, 7, 7, 7, 7, 12, 12, - 12, 7, 10, 10, 10, 7, 7, 10, 10, 10, 10, 10, 10, 10, 7, 7, - 7, 12, 12, 12, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 12, 10, 10, 12, 12, 10, 10, 10, 10, 10, 10, 12, 7, 10, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 10, 10, 10, 12, 26, 26, - 9, 9, 9, 9, 9, 9, 2, 9, 2, 2, 2, 2, 2, 9, 2, 2, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 21, 6, 5, 5, 5, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 2, 7, 2, 7, 7, 7, 7, 2, 2, - 7, 2, 7, 7, 7, 7, 2, 2, 7, 7, 7, 7, 7, 7, 7, 2, - 7, 2, 7, 7, 7, 7, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 12, 12, 12, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, - 9, 9, 9, 9, 9, 9, 2, 2, 5, 5, 5, 5, 5, 5, 2, 2, - 17, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 26, 21, 7, - 29, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 22, 18, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 21, 21, 14, 14, - 14, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 12, 12, 12, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, - 7, 7, 12, 12, 10, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, - 7, 2, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 12, 12, 10, 12, 12, 12, 12, 12, 12, 12, 10, 10, - 10, 10, 10, 10, 10, 10, 12, 10, 10, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 21, 21, 21, 6, 21, 21, 21, 23, 7, 12, 2, 2, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, - 21, 21, 21, 21, 21, 21, 17, 21, 21, 21, 21, 12, 12, 12, 1, 12, - 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 12, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 7, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, - 12, 12, 12, 10, 10, 10, 10, 12, 12, 10, 10, 10, 2, 2, 2, 2, - 10, 10, 12, 10, 10, 10, 10, 10, 10, 12, 12, 12, 2, 2, 2, 2, - 26, 2, 2, 2, 21, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, - 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 2, 2, 2, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 7, 7, 7, 7, 7, 7, 7, 12, 12, 10, 10, 12, 2, 2, 21, 21, - 7, 7, 7, 7, 7, 10, 12, 10, 12, 12, 12, 12, 12, 12, 12, 2, - 12, 10, 12, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 10, 10, 10, - 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 12, - 21, 21, 21, 21, 21, 21, 21, 6, 21, 21, 21, 21, 21, 21, 2, 2, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, - 12, 12, 12, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 12, 10, 12, 12, 12, 12, 12, 10, 12, 10, 10, 10, - 10, 10, 12, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, - 21, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 21, 21, 2, - 12, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 10, 12, 12, 12, 12, 10, 10, 12, 12, 10, 12, 12, 12, 7, 7, - 7, 7, 7, 7, 7, 7, 12, 10, 12, 12, 10, 10, 10, 12, 10, 12, - 12, 12, 10, 10, 2, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 21, - 7, 7, 7, 7, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, - 12, 12, 12, 12, 10, 10, 12, 12, 2, 2, 2, 21, 21, 21, 21, 21, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 21, 21, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, - 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, - 12, 12, 12, 21, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 10, 12, 12, 12, 12, 12, 12, 12, 7, 7, 7, 7, 12, 7, 7, - 7, 7, 7, 7, 12, 7, 7, 10, 12, 12, 7, 2, 2, 2, 2, 2, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, - 9, 5, 9, 5, 9, 5, 5, 5, 5, 5, 5, 5, 5, 5, 9, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 9, 9, 9, 9, 9, 9, 9, 9, - 5, 5, 5, 5, 5, 5, 2, 2, 9, 9, 9, 9, 9, 9, 2, 2, - 5, 5, 5, 5, 5, 5, 5, 5, 2, 9, 2, 9, 2, 9, 2, 9, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, - 5, 5, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 8, - 5, 5, 5, 5, 5, 2, 5, 5, 9, 9, 9, 9, 8, 24, 5, 24, - 24, 24, 5, 5, 5, 2, 5, 5, 9, 9, 9, 9, 8, 24, 24, 24, - 5, 5, 5, 5, 2, 2, 5, 5, 9, 9, 9, 9, 2, 24, 24, 24, - 5, 5, 5, 5, 5, 5, 5, 5, 9, 9, 9, 9, 9, 24, 24, 24, - 2, 2, 5, 5, 5, 2, 5, 5, 9, 9, 9, 9, 8, 24, 24, 2, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 1, 1, 1, 1, 1, - 17, 17, 17, 17, 17, 17, 21, 21, 20, 19, 22, 20, 20, 19, 22, 20, - 21, 21, 21, 21, 21, 21, 21, 21, 27, 28, 1, 1, 1, 1, 1, 29, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 19, 21, 21, 21, 21, 16, - 16, 21, 21, 21, 25, 22, 18, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 25, 21, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 29, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 15, 6, 2, 2, 15, 15, 15, 15, 15, 15, 25, 25, 25, 22, 18, 6, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 25, 25, 25, 22, 18, 2, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, - 11, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 9, 26, 26, 26, 26, 9, 26, 26, 5, 9, 9, 9, 5, 5, - 9, 9, 9, 5, 26, 9, 26, 26, 25, 9, 9, 9, 9, 9, 26, 26, - 26, 26, 26, 26, 9, 26, 9, 26, 9, 26, 9, 9, 9, 9, 26, 5, - 9, 9, 9, 9, 5, 7, 7, 7, 7, 5, 26, 26, 5, 5, 9, 9, - 25, 25, 25, 25, 25, 9, 5, 5, 5, 5, 26, 25, 26, 26, 5, 26, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 9, 5, 14, 14, 14, 14, 15, 26, 26, 2, 2, 2, 2, - 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 25, 25, 26, 26, 26, 26, - 25, 26, 26, 25, 26, 26, 25, 26, 26, 26, 26, 26, 26, 26, 25, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, 25, - 26, 26, 25, 26, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 26, 26, 26, 26, 26, 22, 18, 22, 18, 26, 26, 26, 26, - 25, 25, 26, 26, 26, 26, 26, 26, 26, 22, 18, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, 25, 25, 25, - 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 15, 15, 15, 15, 15, 15, - 26, 26, 26, 26, 26, 26, 26, 25, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 25, 25, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, - 26, 26, 26, 26, 26, 26, 26, 26, 22, 18, 22, 18, 22, 18, 22, 18, - 22, 18, 22, 18, 22, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 25, 25, 25, 25, 25, 22, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, - 25, 25, 25, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22, - 18, 22, 18, 22, 18, 22, 18, 22, 18, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 22, 18, 22, 18, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 22, 18, 25, 25, - 25, 25, 25, 25, 25, 26, 26, 25, 25, 25, 25, 25, 25, 26, 26, 26, - 26, 26, 26, 26, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 9, 5, 9, 9, 9, 5, 5, 9, 5, 9, 5, 9, 5, 9, 9, 9, - 9, 5, 9, 5, 5, 9, 5, 5, 5, 5, 5, 5, 6, 6, 9, 9, - 9, 5, 9, 5, 5, 26, 26, 26, 26, 26, 26, 9, 5, 9, 5, 12, - 12, 12, 9, 5, 2, 2, 2, 2, 2, 21, 21, 21, 21, 15, 21, 21, - 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 2, 2, 5, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 6, - 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, - 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 2, - 21, 21, 20, 19, 20, 19, 21, 21, 21, 20, 19, 21, 20, 19, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 17, 21, 21, 17, 21, 20, 19, 21, 21, - 20, 19, 22, 18, 22, 18, 22, 18, 22, 18, 21, 21, 21, 21, 21, 6, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 17, 17, 21, 21, 21, 21, - 17, 21, 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 26, 26, 21, 21, 21, 22, 18, 22, 18, 22, 18, 22, 18, 17, 2, 2, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, - 29, 21, 21, 21, 26, 6, 7, 14, 22, 18, 22, 18, 22, 18, 22, 18, - 22, 18, 26, 26, 22, 18, 22, 18, 22, 18, 22, 18, 17, 22, 18, 18, - 26, 14, 14, 14, 14, 14, 14, 14, 14, 14, 12, 12, 12, 12, 10, 10, - 17, 6, 6, 6, 6, 6, 26, 26, 14, 14, 14, 6, 7, 21, 26, 26, - 7, 7, 7, 7, 7, 7, 7, 2, 2, 12, 12, 24, 24, 6, 6, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 6, 6, 6, 7, - 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 26, 26, 15, 15, 15, 15, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 15, 15, 15, 15, 15, 15, 15, 15, - 26, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 21, 21, 21, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 7, 7, 2, 2, 2, 2, - 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 7, 12, - 11, 11, 11, 21, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 21, 6, - 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 6, 6, 12, 12, - 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 12, 12, 21, 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, - 24, 24, 24, 24, 24, 24, 24, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 24, 24, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, - 5, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, - 6, 5, 5, 5, 5, 5, 5, 5, 5, 9, 5, 9, 5, 9, 9, 5, - 9, 5, 9, 5, 9, 5, 9, 5, 6, 24, 24, 9, 5, 9, 5, 7, - 9, 5, 9, 5, 5, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, - 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 9, 9, 9, 9, 5, - 9, 9, 9, 9, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, - 9, 5, 9, 5, 9, 9, 9, 9, 5, 9, 5, 2, 2, 2, 2, 2, - 9, 5, 2, 5, 2, 5, 9, 5, 9, 5, 2, 2, 2, 2, 2, 2, - 2, 2, 6, 6, 6, 9, 5, 7, 6, 6, 5, 7, 7, 7, 7, 7, - 7, 7, 12, 7, 7, 7, 12, 7, 7, 7, 7, 12, 7, 7, 7, 7, - 7, 7, 7, 10, 10, 12, 12, 10, 26, 26, 26, 26, 12, 2, 2, 2, - 15, 15, 15, 15, 15, 15, 26, 26, 23, 26, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, - 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 21, 21, - 12, 12, 7, 7, 7, 7, 7, 7, 21, 21, 21, 7, 21, 7, 7, 12, - 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 12, 12, 12, 21, 21, - 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 10, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, - 7, 7, 7, 12, 10, 10, 12, 12, 12, 12, 10, 10, 12, 12, 10, 10, - 10, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 6, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 21, 21, - 7, 7, 7, 7, 7, 12, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 7, 7, 7, 7, 7, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 12, 10, - 10, 12, 12, 10, 10, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 12, 7, 7, 7, 7, 7, 7, 7, 7, 12, 10, 2, 2, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 21, 21, 21, 21, - 6, 7, 7, 7, 7, 7, 7, 26, 26, 26, 7, 10, 12, 10, 7, 7, - 12, 7, 12, 12, 12, 7, 7, 12, 12, 7, 7, 7, 7, 7, 12, 12, - 7, 12, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 6, 21, 21, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 12, 12, 10, 10, - 21, 21, 7, 6, 6, 10, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 7, 7, 7, 7, 7, 7, 2, 2, 7, 7, 7, 7, 7, 7, 2, - 2, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 6, 6, 6, 6, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 24, 24, 2, 2, 2, 2, - 7, 7, 7, 10, 10, 12, 10, 10, 12, 10, 10, 21, 10, 12, 2, 2, - 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 7, 7, 7, 7, 7, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 7, 12, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 25, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 2, 7, 2, - 7, 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 18, 22, - 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 26, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 23, 26, 26, 26, - 21, 21, 21, 21, 21, 21, 21, 22, 18, 21, 2, 2, 2, 2, 2, 2, - 21, 17, 17, 16, 16, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22, - 18, 22, 18, 22, 18, 21, 21, 22, 18, 21, 21, 21, 21, 16, 16, 16, - 21, 21, 21, 2, 21, 21, 21, 21, 17, 22, 18, 22, 18, 22, 18, 21, - 21, 21, 25, 17, 25, 25, 25, 2, 21, 23, 21, 21, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 1, - 2, 21, 21, 21, 23, 21, 21, 21, 22, 18, 21, 25, 21, 17, 21, 21, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 22, 25, 18, 25, 22, - 18, 21, 22, 18, 21, 21, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, - 2, 2, 7, 7, 7, 7, 7, 7, 2, 2, 7, 7, 7, 7, 7, 7, - 2, 2, 7, 7, 7, 7, 7, 7, 2, 2, 7, 7, 7, 2, 2, 2, - 23, 23, 25, 24, 26, 23, 23, 2, 26, 25, 25, 25, 25, 26, 26, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 26, 26, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 2, 7, - 21, 21, 21, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 14, 14, 14, 14, 14, 15, 15, 15, 15, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 15, 15, 26, 26, 26, 2, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, - 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 12, 2, 2, - 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, - 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, - 7, 14, 7, 7, 7, 7, 7, 7, 7, 7, 14, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 21, - 7, 7, 7, 7, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, - 21, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 5, 5, 5, 5, - 9, 9, 9, 9, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 2, 9, 9, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 2, 2, 2, - 6, 6, 6, 6, 6, 6, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 2, 2, 7, 2, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 2, 7, 7, 2, 2, 2, 7, 2, 2, 7, - 7, 7, 7, 7, 7, 7, 2, 21, 15, 15, 15, 15, 15, 15, 15, 15, - 7, 7, 7, 7, 7, 7, 7, 26, 26, 15, 15, 15, 15, 15, 15, 15, - 2, 2, 2, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 7, 7, 7, 2, 7, 7, 2, 2, 2, 2, 2, 15, 15, 15, 15, 15, - 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 2, 2, 2, 21, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 21, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 15, 15, 7, 7, - 2, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 7, 12, 12, 12, 2, 12, 12, 2, 2, 2, 2, 2, 12, 12, 12, 12, - 7, 7, 7, 7, 2, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 2, 2, 12, 12, 12, 2, 2, 2, 2, 12, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 15, 15, 21, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 15, 15, 15, - 7, 7, 7, 7, 7, 7, 7, 7, 26, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 12, 12, 2, 2, 2, 2, 15, 15, 15, 15, 15, - 21, 21, 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 2, 2, 2, 21, 21, 21, 21, 21, 21, 21, - 7, 7, 7, 7, 7, 7, 2, 2, 15, 15, 15, 15, 15, 15, 15, 15, - 7, 7, 7, 2, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, 15, 15, - 7, 7, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 21, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, 15, - 9, 9, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, - 7, 7, 7, 7, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 12, 12, 17, 2, 2, - 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 15, 15, 15, 15, 15, 15, 15, 7, 2, 2, 2, 2, 2, 2, 2, 2, - 12, 15, 15, 15, 15, 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, - 7, 7, 12, 12, 12, 12, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, - 10, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 21, 21, 21, 21, 21, 21, 21, 2, 2, - 15, 15, 15, 15, 15, 15, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 12, 7, 7, 12, 12, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, - 10, 10, 10, 12, 12, 12, 12, 10, 10, 12, 12, 21, 21, 1, 21, 21, - 21, 21, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, - 12, 12, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 10, 12, 12, 12, - 12, 12, 12, 12, 12, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 21, 21, 21, 21, 7, 10, 10, 7, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 12, 21, 21, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 10, - 10, 7, 7, 7, 7, 21, 21, 21, 21, 12, 12, 12, 12, 21, 10, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 7, 21, 7, 21, 21, 21, - 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 12, - 12, 12, 10, 10, 12, 10, 12, 12, 21, 21, 21, 21, 21, 21, 12, 2, - 7, 7, 7, 7, 7, 7, 7, 2, 7, 2, 7, 7, 7, 7, 2, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, - 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, - 12, 12, 10, 10, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 7, - 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, 2, 12, 12, 7, 10, 10, - 12, 10, 10, 10, 10, 2, 2, 10, 10, 2, 2, 10, 10, 10, 2, 2, - 7, 2, 2, 2, 2, 2, 2, 10, 2, 2, 2, 2, 2, 7, 7, 7, - 7, 7, 10, 10, 2, 2, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, - 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, - 10, 10, 12, 12, 12, 10, 12, 7, 7, 7, 7, 21, 21, 21, 21, 21, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 2, 21, 12, 7, - 10, 10, 10, 12, 12, 12, 12, 12, 12, 10, 12, 10, 10, 10, 10, 12, - 12, 10, 12, 12, 7, 7, 21, 7, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, - 10, 10, 12, 12, 12, 12, 2, 2, 10, 10, 10, 10, 12, 12, 10, 12, - 12, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 7, 7, 7, 7, 12, 12, 2, 2, - 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 10, 10, 12, 10, 12, - 12, 21, 21, 21, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 10, 12, 10, 10, - 12, 12, 12, 12, 12, 12, 10, 12, 7, 21, 2, 2, 2, 2, 2, 2, - 10, 10, 12, 12, 12, 12, 10, 12, 12, 12, 12, 12, 2, 2, 2, 2, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 21, 21, 21, 26, - 12, 12, 12, 12, 12, 12, 12, 12, 10, 12, 12, 21, 2, 2, 2, 2, - 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, - 7, 7, 7, 7, 7, 7, 7, 2, 2, 7, 2, 2, 7, 7, 7, 7, - 7, 7, 7, 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, - 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 2, 12, 12, 10, 12, 7, - 10, 7, 10, 12, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 7, 7, 7, 7, 7, 7, - 7, 10, 10, 10, 12, 12, 12, 12, 2, 2, 12, 12, 10, 10, 10, 10, - 12, 7, 21, 7, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 7, 7, 7, 7, - 7, 7, 7, 12, 12, 12, 12, 12, 12, 10, 7, 12, 12, 12, 12, 21, - 21, 21, 21, 21, 21, 21, 21, 12, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 12, 12, 12, 12, 12, 12, 10, 10, 12, 12, 12, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 10, 12, 12, 21, 21, 21, 7, 21, 21, - 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, 12, 12, 12, 12, 10, 12, - 7, 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 21, 21, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 2, 10, 12, 12, 12, 12, 12, 12, - 12, 10, 12, 12, 10, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, - 7, 12, 12, 12, 12, 12, 12, 2, 2, 2, 12, 2, 12, 12, 2, 12, - 12, 12, 12, 12, 12, 12, 7, 12, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10, 2, - 12, 12, 2, 10, 10, 12, 10, 12, 7, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 12, 12, 10, 10, 21, 21, 2, 2, 2, 2, 2, 2, 2, - 15, 15, 15, 15, 15, 26, 26, 26, 26, 26, 26, 26, 26, 23, 23, 23, - 23, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, - 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, - 12, 12, 12, 12, 12, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 12, 12, 12, 12, 12, 12, 12, 21, 21, 21, 21, 21, 26, 26, 26, 26, - 6, 6, 6, 6, 21, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 15, 15, 15, 15, 15, - 15, 15, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 7, 7, 7, - 15, 15, 15, 15, 15, 15, 15, 21, 21, 21, 21, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 12, - 7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 12, - 12, 12, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 21, 6, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 10, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 6, 6, 6, 6, 2, 6, 6, 6, 6, 6, 6, 6, 2, 6, 6, 2, - 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 26, 12, 12, 21, - 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, - 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 26, 26, 26, 26, 26, 2, 2, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 10, 10, 12, 12, 12, 26, 26, 26, 10, 10, 10, - 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, - 12, 12, 12, 26, 26, 12, 12, 12, 12, 12, 12, 12, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 12, 12, 12, 12, 26, 26, - 26, 26, 12, 12, 12, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, - 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 9, 9, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 9, 2, 9, 9, - 2, 2, 9, 2, 2, 9, 9, 2, 2, 9, 9, 9, 9, 2, 9, 9, - 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 2, 5, 2, 5, 5, 5, - 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 9, 9, 2, 9, 9, 9, 9, 2, 2, 9, 9, 9, - 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 2, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 9, 9, 2, 9, 9, 9, 9, 2, - 9, 9, 9, 9, 9, 2, 9, 2, 2, 2, 9, 9, 9, 9, 9, 9, - 9, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, - 5, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, - 5, 5, 5, 5, 5, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 9, 5, 2, 2, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 12, 12, 12, 12, 12, 12, 12, 26, 26, 26, 26, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 26, 26, 26, - 26, 26, 26, 26, 26, 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 12, 26, 26, 21, 21, 21, 21, 21, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 12, 12, - 12, 12, 2, 12, 12, 2, 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, - 12, 12, 12, 12, 12, 12, 12, 6, 6, 6, 6, 6, 6, 6, 2, 2, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 7, 26, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 23, - 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 2, 7, 7, 2, - 7, 7, 7, 7, 7, 2, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 5, 5, 5, 5, 12, 12, 12, 12, 12, 12, 12, 6, 2, 2, 2, 2, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 15, 15, 15, - 23, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, - 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 2, 7, 7, 2, 7, 2, 2, 7, 2, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 2, 7, 7, 7, 7, 2, 7, 2, 7, 2, 2, 2, 2, - 2, 2, 7, 2, 2, 2, 2, 7, 2, 7, 2, 7, 2, 7, 7, 7, - 2, 7, 7, 2, 7, 2, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, - 2, 7, 7, 2, 7, 2, 2, 7, 7, 7, 7, 2, 7, 7, 7, 7, - 7, 7, 7, 2, 7, 7, 7, 7, 2, 7, 7, 7, 7, 2, 7, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, - 2, 7, 7, 7, 2, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, - 25, 25, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, - 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 24, 24, 24, 24, 24, - 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 26, 26, 26, 2, 2, 2, 26, 26, 26, 26, 26, 2, 2, 2, - 26, 26, 26, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 12, 12, 13, 14, 12, 15, 16, 17, 18, 19, 20, - 21, 22, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 24, 25, - 0, 26, 27, 0, 28, 29, 30, 31, 32, 33, 0, 34, 0, 0, 0, 0, - 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 37, 38, 0, 0, 0, 0, - 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, - 43, 44, 45, 46, 0, 47, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 50, 0, 0, 0, - 0, 0, 0, 51, 0, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 55, 0, 0, 0, 0, 56, 0, 0, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 0, 67, 68, 0, 69, 70, 71, 72, 0, - 61, 0, 73, 74, 75, 76, 0, 0, 70, 0, 77, 78, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 79, 80, 0, 0, 0, 0, 0, 0, 0, 0, 81, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 83, 84, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 86, 0, 80, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 1, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 14, 15, 16, 17, 18, 19, 20, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 21, 0, 0, 0, 0, 0, 22, 23, 24, - 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, - 28, 29, 0, 0, 0, 0, 30, 0, 0, 0, 31, 32, 33, 34, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 13, 35, 36, 0, 0, 26, 37, 38, 39, 0, 0, 0, 0, 0, 40, - 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 42, 43, 1, - 44, 45, 46, 47, 0, 0, 0, 0, 0, 0, 0, 48, 0, 49, 50, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, - 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 49, 52, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 49, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 56, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 58, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 60, 61, 0, 0, 0, 0, - 0, 0, 62, 63, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 67, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, - 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 71, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 0, 0, 0, 0, - 76, 0, 68, 77, 0, 0, 0, 0, 0, 0, 78, 79, 80, 81, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 70, 0, 0, 0, - 0, 82, 83, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, - 85, 0, 84, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 87, - 88, 89, 90, 91, 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, 94, 1, - 1, 1, 95, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 98, - 99,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 74, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 74,105,106, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 91, 0,107, 0, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, - 1, 1, 91, 0, 0, 0, 0, 0, 0,108, 0, 0, 0, 0,109, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 0, 76, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,112,113, 0, 0, 0, - 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 49, 0, 0, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,115,116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 26,117, 0,118, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 120, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,121, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122,123, 75, 0, - 0, 0, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0, 0, 0, - 0, 0, 76,102, 0, 0, 0, 0, 0, 0, 0,125, 0, 0, 0, 0, - 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 53, 0, 0, 0, 0, 0, - 0, 0,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,126, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 0, 49, 0, 0, - 26,130,130, 0, 0, 0, 0, 0, 0, 0, 0, 0,131, 0, 0, 51, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,132, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102,133, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,134, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,110, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0,102, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,136, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,137, 0, 0, 0, - 0, 0, 0, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,138, 0, 0, 0, 0, 0, 0, 0,139, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,140, 0, 0, 0, 0,141, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 142,143,144,145,146,147, 0, 0, 0,148, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,149, 0, 0, 0, - 0, 0, 0, 0,139, 1, 1,150,151,117, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, - 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,153, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230, - 230,230,230,230,230,230,230,230,230,232,220,220,220,220,232,216, - 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, - 220,220,220,220,220,220,220,220, 1, 1, 1, 1, 1,220,220,220, - 220,230,230,230,230,230,230,230,230,240,230,220,220,220,230,230, - 230,220,220, 0,230,230,230,220,220,220,220,230,232,220,220,230, - 233,234,234,233,234,234,233,230,230,230,230,230, 0, 0, 0,230, - 230,230,230,230, 0,220,230,230,230,230,220,230,230,230,222,220, - 230,230,230,230,230,230,220,220,220,220,220,220,230,230,220,230, - 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, - 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230, - 230,220,220,230,230,230,230,230,220,230,230,220, 35, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230,230,230, - 230, 0, 0,230,230,230,230,220,230, 0, 0,230,230, 0,220,230, - 230,220, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0,230,220,230,230, - 220,230,230,220,220,220,230,220,220,230,220,230,230,230,220,230, - 220,230,220,230,220,230,230, 0, 0, 0, 0, 0,230,230,220,230, - 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0, 0,230,230, 0,230, - 230,230,230,230,230,230,230,230, 0,230,230,230, 0,230,230,230, - 230,230, 0, 0, 0,220,220,220, 0, 0, 0, 0,230,220,220,220, - 230,230,230,230, 0, 0,230,230,230,230,230,220,220,220,220,220, - 230,230,230,230,230,230, 0,220,230,230,220,230,230,220,230,230, - 230,220,220,220, 27, 28, 29,230,230,230,220,230,230,220,220,230, - 230,230,230,230, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0, 0, 0, - 0, 0,230, 0, 0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,103,103, 9, 0, - 0, 0, 0, 0,107,107,107,107, 0, 0, 0, 0,118,118, 9, 0, - 0, 0, 0, 0,122,122,122,122, 0, 0, 0, 0,220,220, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0,220, 0,216, 0, 0, - 0, 0, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, - 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0, 0, 0, - 0, 0,220, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230, 0, 0, 0, 0, - 9, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 0,230, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0,222,230,220, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,220, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,230,230,230,230, - 230, 0, 0,220,230,230,230,230,230,220,220,220,220,220,220,230, - 230,220, 0,220,220,230,230,220,220,230,230,230,230,230,220,230, - 230,230,230, 0, 0, 0, 0,230,220,230,230,230,230,230,230,230, - 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 0,230,230,230, 0, 1,220,220,220,220,220,230,230, - 220,220,220,220,230, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0,220, 0, 0, 0, 0, 0, 0,230, 0, 0, 0,230,230, 0, 0, - 0, 0, 0, 0,230,230,220,230,230,230,230,230,230,230,220,230, - 230,234,214,220,202,230,230,230,230,230,230,230,230,230,230,230, - 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, - 230,230,230,230, 1, 1, 1,230,230, 0, 0, 0, 0,230, 0, 0, - 0, 1, 1,230,220,230, 1, 1,220,220,220,220,230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0,218,228, - 232,222,224,224, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 230,230,230,230,230,230,230,230,230,230, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0,220,220,220, 0, 0, 0, 0, 0, 9, - 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,230, 0,230,230, - 220, 0, 0,230,230, 0, 0, 0, 0, 0,230,230, 0,230, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0,230,230,230,230, - 230,230,230,220,220,220,220,220,220,220,230,230,230,230,230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0,230,230, 1,220, 0, - 0, 0, 0, 9, 0, 0, 0, 0, 0,230,220, 0, 0, 0, 0,230, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,220,230,230,230,220, - 230,220,220,220, 0, 0,230,220,230,220, 0, 0, 0, 9, 7, 0, - 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 0, 0, 0, 0, 0, 7, - 7, 0, 0, 0,230,230,230,230,230, 0, 0, 0, 0, 0, 9, 0, - 0, 0, 7, 0, 0, 0, 9, 7, 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, - 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, - 9, 9, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,230,230,230,230, - 230,230,230, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0,216,216, 1, 1, 1, 0, 0, - 0,226,216,216,216,216,216, 0, 0, 0, 0, 0, 0, 0, 0,220, - 220,220,220,220,220,220,220, 0, 0,230,230,230,230,230,220,220, - 0, 0, 0, 0, 0, 0,230,230,230,230, 0, 0, 0, 0,230,230, - 230, 0, 0, 0,230, 0, 0,230,230,230,230,230,230,230, 0,230, - 230, 0,230,230,220,220,220,220,220,220,220, 0,230,230, 7, 0, - 0, 0, 0, 0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19, - 17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, - 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, - 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, - 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, - 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, - 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, - 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 21, 32, 4, 0, 10, 0, 33, 7, 20, 20, 20, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, 37, 0, 38, 1, 20, 20, - 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, 20, 0, 0, 0, 1, 0, - 0, 40, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 21, - 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 7, 20, 41, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 0, 42, 43, 44, 0, 45, - 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, - 0, 0, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 17, 19, 20, 21, 22, 23, 24, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 27, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 34, 34, 34, 34, 58, 59, 59, 60, 34, - 34, 34, 34, 34, 34, 34, 61, 62, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 63, 64, 34, 65, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 67, 66, 68, 69, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 70, 71, 72, 34, 34, - 34, 34, 73, 34, 34, 34, 34, 34, 34, 34, 34, 74, 75, 76, 77, 78, - 79, 80, 34, 81, 82, 83, 34, 84, 85, 34, 86, 87, 88, 89, 17, 90, - 91, 92, 34, 34, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 93, 25, 25, 25, 25, 25, 25, 25, 94, - 95, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 96, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 97, 34, 34, 34, 34, 34, 34, - 25, 98, 34, 34, 25, 25, 25, 25, 25, 25, 25, 25, 25, 99, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, - 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, - 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, - 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, - 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, - 2, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 0, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 2, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 2, 2, 95, 2, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, - 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, - 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, - 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, - 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, - 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, - 2, 2, 11, 2, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, - 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, - 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, - 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, - 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, - 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, - 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, - 2, 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, - 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, - 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, - 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, - 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, - 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, - 22, 22, 22, 22, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, - 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, - 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, - 2, 2, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, - 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 2, 2, - 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 2, 16, 16, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, - 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 2, 36, 2, 2, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, - 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 36, 36, - 36, 36, 36, 36, 36, 36, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, - 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, - 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 2, 2, 2, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, - 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2, - 2, 2, 2, 8, 2, 2, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, - 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 2, - 30, 30, 30, 30, 2, 2, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 30, 30, 30, 30, 2, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 2, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 29, 29, - 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 2, - 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 2, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 2, 2, 2, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 2, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, - 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, - 2, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, - 2, 2, 2, 2, 2, 2, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 2, 2, 8, 8, 8, 76, 76, 76, 76, 76, 76, 76, 76, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, - 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 6, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, - 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, - 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, - 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 19, 19, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, - 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, - 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, - 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 61, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, - 30, 30, 30, 30, 30, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 1, 1, 1, 1, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, - 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, - 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, - 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, - 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 2, 2, 2, 2, 2, 19, 19, 2, 19, 2, 19, 19, 19, 19, 19, - 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 2, 2, - 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, - 2, 2, 2, 2, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 2, 0, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 2, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 30, 30, 30, 30, 30, 30, 2, 2, 30, - 30, 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, - 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 2, 2, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, - 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, - 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, - 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, - 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, - 12, 12, 12, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, - 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, - 118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, - 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 2, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, - 135,135,135,135,135,135,135,135,135,135, 2, 2, 2, 2,135,135, - 135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, - 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,106,106, - 106,106,106,106,106,106,106,106,106,106,106,106,106,106, 2, 2, - 2, 2, 2, 2, 2, 2,104,104,104,104,104,104,104,104,104,104, - 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, - 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, - 161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161,161, - 161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161,161, - 2,161,161, 2, 2, 2,110,110,110,110,110,110,110,110,110,110, - 110,110,110,110,110,110,110,110,110,110,110,110,110, 2, 2, 2, - 2, 2, 2, 2, 2, 2,110,110,110,110,110,110, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,110,110,110,110,110,110,110,110, 2, 2, - 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 2, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 2, 2, 2, 2, 2, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, - 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81, 81, 81, - 81, 81, 81, 81, 81, 81,120,120,120,120,120,120,120,120,120,120, - 120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116, - 116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, - 116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, 2,116,116,116, - 116,116,116,116,116,116,128,128,128,128,128,128,128,128,128,128, - 128,128,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, - 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, - 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 2, - 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 2, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, - 57, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, - 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,117,117, - 117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112, - 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, - 2,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, - 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 83, 83, - 83, 83, 83, 83, 83, 83, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2, 82, 82, - 82, 82, 82, 82, 82, 82,122,122,122,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122, - 122,122,122, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,122, - 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, - 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, - 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,130,130,130, 2, 2, 2, 2, 2, 2, 2, - 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, - 144,144,144,144,144,144,144,144,144,144,144,144,144,144, 2, 2, - 2, 2, 2, 2, 2, 2,144,144,144,144,144,144,144,144,144,144, - 2, 2, 2, 2, 2, 2,156,156,156,156,156,156,156,156,156,156, - 156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, - 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,147,147,147,147,147,147,147,147,147,147, - 147,147,147,147,147,147,147,147,147,147,147,147,147,147, 2, 2, - 2, 2, 2, 2, 2, 2,148,148,148,148,148,148,148,148,148,148, - 148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, - 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, - 158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, - 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, - 153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, - 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, - 149,149,149,149,149,149,149,149,149,149,149,149,149, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 85, 2, 2,101,101,101,101,101,101,101,101,101,101, - 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, 2, - 2, 2, 2, 2, 2, 2,101,101,101,101,101,101,101,101,101,101, - 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 2, - 2, 2, 2, 2, 2, 2,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111, 2, 2, 2, - 2, 2, 2, 2, 2, 2,100,100,100,100,100,100,100,100,100,100, - 100,100,100,100,100,100, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,108,108,108,108,108,108,108,108,108,108, - 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, - 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, - 108,108,108,108,108, 2,129,129,129,129,129,129,129, 2,129, 2, - 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, - 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, - 2, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109, - 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, - 109, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109, - 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, - 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, 2, - 107,107,107,107,107,107,107, 2,107,107, 2,107,107,107,107,107, - 2, 1,107,107,107,107,107,107,107,107,107, 2, 2,107,107, 2, - 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, - 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, - 107,107,107, 2, 2, 2,107,107,107,107,107, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, - 137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, - 137,137, 2,137,137,137,137,137, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, - 124,124,124,124,124,124,124,124,124,124,124,124,124,124, 2, 2, - 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, - 2, 2, 2, 2, 2, 2,123,123,123,123,123,123,123,123,123,123, - 123,123,123,123,123,123,123,123,123,123,123,123, 2, 2,123,123, - 123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, - 123,123,123,123, 2, 2,114,114,114,114,114,114,114,114,114,114, - 114,114,114,114,114,114,114,114,114,114,114, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,114,114,114,114,114,114,114,114,114,114, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, - 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, - 2, 2, 2, 2, 2, 2,126,126,126,126,126,126,126,126,126,126, - 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, - 126, 2, 2,126,126,126,126,126,126,126,126,126,126,126,126,126, - 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, - 2, 2, 2, 2, 2, 2,142,142,142,142,142,142,142,142,142,142, - 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, - 142,142, 2, 2, 2, 2,125,125,125,125,125,125,125,125,125,125, - 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, - 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, - 154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, - 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, - 2,154,154,154,154,154,154,154,154,154,154,154,154, 2, 2, 2, - 2, 2, 2, 2, 2, 2,154,154,154,154,154,154,154,154,154,154, - 2, 2, 2, 2, 2, 2,150,150,150,150,150,150,150,150, 2, 2, - 150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, - 150,150,150,150,150,150,150,150,150,150,150, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,141,141,141,141,141,141,141,141,141,141, - 141,141,141,141,141,141,141,141,141,141,141,141,141,141, 2, 2, - 2, 2, 2, 2, 2, 2,140,140,140,140,140,140,140,140,140,140, - 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,121,121,121,121,121,121,121,121,121,121, - 121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, 2, - 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, - 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, - 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, - 133,133,133,133,133,133,133,133,133,133,133,133, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133,133, - 133,133,133, 2, 2, 2,134,134,134,134,134,134,134,134,134,134, - 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134,134,134, - 134,134,134,134,134,134,134,134,134,134,134,134,134,134, 2,134, - 134,134,134,134,134,134,134,134,134,134,134,134,134, 2, 2, 2, - 2, 2, 2, 2, 2, 2,138,138,138,138,138,138,138, 2,138,138, - 2,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, - 138,138,138,138,138,138,138,138,138,138,138,138,138, 2, 2, 2, - 138, 2,138,138, 2,138,138,138,138,138,138,138,138,138, 2, 2, - 2, 2, 2, 2, 2, 2,138,138,138,138,138,138,138,138,138,138, - 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, - 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, - 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, - 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, - 2, 2, 2, 2, 2, 2,143,143,143,143,143,143,143,143,143,143, - 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145,145, - 145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, 2, - 2, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,157,157,157,157,157,157,157,157,157,157, - 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, - 2, 2, 2, 2, 2, 2,127,127,127,127,127,127,127,127,127,127, - 127,127,127,127,127,127,127,127,127,127,127,127,127, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 79, 2, - 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, - 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, - 115,115,115,115,115, 2,115,115,115,115,115,115,115,115,115,115, - 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, - 159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, - 159,159,159,159,159, 2,159,159,159,159,159,159,159,159,159,159, - 2, 2, 2, 2, 2, 2,103,103,103,103,103,103,103,103,103,103, - 103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, - 103,103,103,103, 2, 2,103,103,103,103,103,103, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,119,119,119,119,119,119,119,119,119,119, - 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,119,119,119,119,119,119,119,119,119,119, - 2,119,119,119,119,119,119,119, 2,119,119,119,119,119,119,119, - 119,119,119,119,119,119,119,119,119,119,119,119,119,119, 2, 2, - 2, 2, 2,119,119,119,146,146,146,146,146,146,146,146,146,146, - 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, - 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, - 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,136,136,136,136,136,136,136,136,136,136, - 136,136,136,136,136,136,136,136,136,136,136,136,136,136, 2, 2, - 2, 2, 2, 2, 2, 2,155,155,155,155,155,155,155,155,155,155, - 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2,136,136,136,136,136,136,136,136,136, 2, - 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, - 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 2, - 2, 2, 2, 2, 2, 2,139,139,139,139,139,139,139,139,139,139, - 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, - 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, - 105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, - 105, 2, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, - 105,105,105, 2, 2, 2,105,105,105,105,105,105,105,105,105, 2, - 2, 2, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, - 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 9, 9, 9, 9, 9, 9, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 0, 0,131,131,131,131,131,131,131,131,131,131, - 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, - 131,131, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2,131,131,131,131,131, 2,131,131,131,131,131,131,131,131,131, - 131,131,131,131,131,131, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 2, - 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 2, 56, 56, 56, 56, - 56, 2, 2, 2, 2, 2,151,151,151,151,151,151,151,151,151,151, - 151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, - 151,151,151, 2, 2, 2,151,151,151,151,151,151,151,151,151,151, - 151,151,151,151, 2, 2,151,151,151,151,151,151,151,151,151,151, - 2, 2, 2, 2,151,151,160,160,160,160,160,160,160,160,160,160, - 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, - 160,160,160,160,160, 2,152,152,152,152,152,152,152,152,152,152, - 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, - 2, 2, 2, 2, 2,152, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, - 30, 30, 2, 30, 30, 2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, - 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, - 113,113,113,113,113,113,113,113,113,113,113,113,113, 2, 2, 2, - 2, 2, 2, 2, 2, 2,132,132,132,132,132,132,132,132,132,132, - 132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, - 132,132, 2, 2, 2, 2,132,132,132,132,132,132,132,132,132,132, - 2, 2, 2, 2,132,132, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, - 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, - 2, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 3, 2, 3, 2, 2, 3, 3, 3, - 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, - 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, - 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, - 0, 0, 0, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, - 2, 2, 2, 2, 2, 2, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 1, 2, 3, 4, 5, 6, 0, - 0, 0, 0, 7, 8, 9, 10, 11, 0, 12, 0, 0, 0, 0, 13, 0, - 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 0, 17, 18, 19, - 0, 0, 0, 20, 21, 22, 0, 23, 0, 24, 0, 25, 0, 26, 0, 0, - 0, 0, 0, 27, 28, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 0, 0, 0, 41, 0, 42, 43, 44, 45, - 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 50, 51, 52, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 64, 0, 0, 0, 0, 0, - 0, 0, 0, 65, 0, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 71, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 72, 73, 74, 75, 76, 77, 78, 79, 80, 0, -}; -static const uint16_t -_hb_ucd_u16[11584] = -{ - 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, - 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, - 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, - 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, - 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, - 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50, - 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58, - 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66, - 48, 67, 68, 69, 48, 70, 71, 48, 72, 73, 48, 48, 74, 32, 75, 32, - 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101, - 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113, - 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124, - 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135, - 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140, - 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140, - 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, - 48, 171, 48, 48, 48, 173, 174, 175, 48, 176, 9, 9, 9, 9, 9, 177, - 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, - 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, - 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, - 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, - 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, - 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, - 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, - 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, - 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, - 209, 209, 287, 140, 288, 140, 271, 271, 271, 289, 209, 209, 209, 209, 290, 271, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 291, 292, 209, 209, 293, - 209, 209, 209, 209, 209, 209, 294, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 279, 279, 279, 279, 279, 279, 279, 279, 300, 301, 279, 279, 279, 302, 279, 303, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 209, 209, 209, 279, 304, 209, 209, 305, 209, 306, 209, 209, 209, 209, 209, 209, - 9, 9, 9, 11, 11, 11, 307, 308, 13, 13, 13, 13, 13, 13, 309, 310, - 11, 11, 311, 48, 48, 48, 312, 313, 48, 314, 315, 315, 315, 315, 32, 32, - 316, 317, 318, 319, 320, 321, 140, 140, 209, 322, 209, 209, 209, 209, 209, 323, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 324, 140, 325, - 326, 327, 328, 329, 136, 48, 48, 48, 48, 330, 178, 48, 48, 48, 48, 331, - 332, 48, 48, 136, 48, 48, 48, 48, 200, 333, 48, 48, 209, 209, 323, 48, - 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, - 48, 338, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 287, 48, 48, 229, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, - 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, - 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, - 64, 48, 365, 48, 366, 367, 48, 151, 76, 48, 48, 368, 369, 370, 371, 372, - 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, - 383, 384, 315, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, - 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, - 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410, - 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419, - 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, - 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, - 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, - 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, - 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, - 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, - 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, - 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, - 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, - 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, - 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 271, 476, 48, 48, 477, 478, 140, 140, 140, 140, - 48, 464, 479, 48, 62, 480, 140, 48, 481, 140, 140, 48, 482, 140, 48, 314, - 483, 48, 48, 484, 485, 457, 486, 487, 222, 48, 48, 488, 489, 48, 196, 192, - 490, 48, 491, 492, 493, 48, 48, 494, 222, 48, 48, 495, 496, 497, 498, 499, - 48, 97, 500, 501, 140, 140, 140, 140, 502, 503, 504, 48, 48, 505, 506, 192, - 507, 83, 84, 508, 509, 510, 511, 512, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 513, 514, 515, 478, 140, 48, 48, 48, 516, 517, 192, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 518, 519, 520, 521, 140, 140, - 48, 48, 48, 522, 523, 192, 524, 140, 48, 48, 525, 526, 192, 140, 140, 140, - 48, 173, 527, 528, 314, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 500, 529, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 530, - 531, 532, 48, 533, 534, 192, 140, 140, 140, 140, 535, 48, 48, 536, 537, 140, - 538, 48, 48, 539, 540, 541, 48, 48, 542, 543, 544, 48, 48, 48, 48, 196, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 84, 48, 518, 545, 546, 148, 175, 547, 48, 548, 549, 550, 140, 140, 140, 140, - 551, 48, 48, 552, 553, 192, 554, 48, 555, 556, 192, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 557, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 100, 271, 558, 559, 560, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, - 272, 272, 272, 272, 272, 272, 561, 562, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 563, - 48, 48, 200, 564, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 314, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 565, - 48, 48, 48, 566, 567, 568, 569, 570, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 571, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 572, 573, 574, 574, 575, 576, 140, 140, 140, 140, 577, 578, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 140, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 579, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 580, 140, 140, 580, 581, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 582, 583, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 32, 32, 584, 32, 585, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 324, - 209, 209, 586, 209, 209, 209, 587, 588, 589, 209, 590, 209, 209, 209, 288, 140, - 209, 209, 209, 209, 591, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 592, - 209, 209, 209, 209, 209, 287, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, - 9, 593, 11, 594, 595, 596, 241, 9, 597, 598, 599, 600, 601, 9, 593, 11, - 602, 603, 11, 604, 605, 606, 607, 9, 608, 11, 9, 593, 11, 594, 595, 11, - 241, 9, 597, 607, 9, 608, 11, 9, 593, 11, 609, 9, 610, 611, 612, 613, - 11, 614, 9, 615, 616, 617, 618, 11, 619, 9, 620, 11, 621, 622, 622, 622, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 32, 32, 32, 623, 32, 32, 624, 625, 626, 627, 45, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 628, 629, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 630, 631, 632, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 151, 633, 634, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 635, 140, 48, 48, 636, 637, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 638, 200, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 639, 585, 140, 140, - 9, 9, 597, 11, 640, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 498, 271, 271, 641, 642, 140, 140, 140, 140, - 498, 271, 643, 644, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 645, 48, 646, 647, 648, 649, 650, 651, 652, 206, 653, 206, 140, 140, 140, 654, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 655, 655, 655, 209, 324, - 656, 209, 209, 209, 209, 209, 209, 209, 209, 209, 657, 140, 140, 140, 658, 209, - 659, 209, 209, 325, 660, 661, 324, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 662, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 663, 426, 426, - 209, 209, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 660, 325, 427, - 325, 209, 209, 209, 664, 176, 209, 209, 664, 209, 657, 661, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 323, 657, 665, 287, 209, 426, 288, 324, 176, 664, 287, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 666, 209, 209, 288, 140, 140, 192, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 196, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 140, - 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 71, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 667, 140, 668, 668, 668, 668, 668, 668, 140, 140, 140, 140, 140, 140, 140, 140, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 669, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 670, - 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, - 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 11, 11, 11, 13, 11, - 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 16, 17, 18, 17, 17, 19, 20, 21, 21, 22, 21, 23, 24, - 25, 26, 27, 27, 28, 29, 27, 30, 27, 27, 27, 27, 27, 31, 27, 27, - 32, 33, 33, 33, 34, 27, 27, 27, 35, 35, 35, 36, 37, 37, 37, 38, - 39, 39, 40, 41, 42, 43, 44, 27, 45, 46, 27, 27, 27, 27, 47, 27, - 48, 48, 48, 48, 48, 49, 50, 48, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 109, 110, 111, 112, 109, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 122, 123, 122, 124, 125, 125, 126, 127, 128, 129, 130, 131, 125, 125, - 132, 132, 132, 132, 133, 132, 134, 135, 132, 133, 132, 136, 136, 137, 125, 125, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 140, 139, 139, 141, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143, - 143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170, - 171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176, - 177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168, - 188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194, 8, 195, 125, 125, 125, - 196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201, - 202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211, - 4, 4, 212, 4, 4, 213, 214, 215, 4, 4, 4, 216, 8, 8, 8, 8, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 11, 217, 11, 11, 217, 218, 11, 219, 11, 11, 11, 220, 220, 221, 11, 222, - 223, 0, 0, 0, 0, 0, 224, 225, 226, 227, 0, 0, 228, 8, 8, 229, - 0, 0, 230, 231, 232, 0, 4, 4, 233, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 234, 125, 235, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 238, 0, 0, 0, 0, 0, 0, - 239, 239, 239, 239, 239, 239, 4, 4, 240, 240, 240, 240, 240, 240, 240, 241, - 139, 139, 140, 242, 242, 242, 243, 244, 143, 245, 246, 246, 246, 246, 14, 14, - 0, 0, 0, 0, 0, 247, 125, 125, 248, 249, 248, 248, 248, 248, 248, 250, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 125, 252, - 253, 0, 254, 255, 256, 257, 257, 257, 257, 258, 259, 260, 260, 260, 260, 261, - 262, 263, 263, 264, 142, 142, 142, 142, 265, 0, 263, 263, 0, 0, 266, 260, - 142, 265, 0, 0, 0, 0, 142, 267, 0, 0, 0, 0, 0, 260, 260, 268, - 260, 260, 260, 260, 260, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 0, 0, 0, 0, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 271, 270, 270, 270, 272, 273, 273, 273, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 275, 125, 14, 14, 14, 14, 14, 14, 276, 276, 276, 276, 276, 277, - 0, 0, 278, 4, 4, 4, 4, 4, 279, 4, 4, 4, 280, 281, 125, 282, - 283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290, 48, 48, - 291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299, - 300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308, - 309, 310, 246, 4, 4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 315, 142, 316, 142, 142, 317, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319, 125, 125, - 320, 321, 21, 322, 323, 27, 27, 27, 27, 27, 27, 27, 324, 325, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 326, 27, 27, 27, 27, 27, 327, 27, 27, 328, 125, 125, 27, - 8, 285, 329, 0, 0, 330, 331, 332, 27, 27, 27, 27, 27, 27, 27, 333, - 334, 0, 1, 2, 1, 2, 335, 259, 260, 336, 142, 265, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 345, 125, 125, 342, 342, 342, 342, 342, 342, 342, 346, - 347, 0, 0, 348, 11, 11, 11, 11, 349, 350, 351, 125, 125, 0, 0, 352, - 125, 125, 125, 125, 125, 125, 125, 125, 353, 354, 355, 355, 355, 356, 357, 252, - 358, 358, 359, 360, 361, 362, 362, 363, 364, 365, 366, 366, 367, 368, 125, 125, - 369, 369, 369, 369, 369, 370, 370, 370, 371, 372, 373, 374, 374, 375, 374, 376, - 377, 377, 378, 379, 379, 379, 380, 381, 381, 382, 383, 384, 125, 125, 125, 125, - 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, - 385, 385, 385, 386, 385, 387, 388, 125, 389, 4, 4, 390, 125, 125, 125, 125, - 391, 392, 392, 393, 394, 395, 396, 396, 397, 398, 399, 125, 125, 125, 400, 401, - 402, 403, 404, 405, 125, 125, 125, 125, 406, 406, 407, 408, 407, 409, 407, 407, - 410, 411, 412, 413, 414, 414, 415, 415, 416, 416, 125, 125, 417, 417, 418, 419, - 420, 420, 420, 421, 422, 423, 424, 425, 426, 427, 428, 125, 125, 125, 125, 125, - 429, 429, 429, 429, 430, 125, 125, 125, 431, 431, 431, 432, 431, 431, 431, 433, - 434, 434, 435, 436, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 27, 45, 437, 437, 438, 439, 125, 125, 125, 125, - 440, 440, 441, 442, 442, 443, 125, 444, 445, 125, 125, 446, 447, 125, 448, 449, - 450, 450, 450, 450, 451, 452, 450, 453, 454, 454, 454, 454, 455, 456, 457, 458, - 459, 459, 459, 460, 461, 462, 462, 463, 464, 464, 464, 464, 464, 464, 465, 466, - 467, 468, 467, 469, 125, 125, 125, 125, 470, 471, 472, 473, 473, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 483, 125, 125, 125, 125, 125, 125, 125, 125, - 484, 484, 484, 484, 484, 485, 486, 125, 487, 487, 487, 487, 488, 489, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 490, 490, 490, 491, 490, 492, 125, 125, - 493, 493, 493, 493, 494, 495, 496, 125, 497, 497, 497, 498, 498, 125, 125, 125, - 499, 500, 501, 499, 502, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 503, 503, 503, 504, 125, 125, 125, 125, 125, 125, 505, 505, 505, 505, 505, 506, - 507, 508, 509, 510, 511, 512, 125, 125, 125, 125, 513, 514, 514, 513, 515, 125, - 516, 516, 516, 516, 517, 518, 518, 518, 518, 518, 519, 154, 520, 520, 520, 521, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 522, 523, 523, 524, 525, 523, 526, 527, 527, 528, 529, 530, 125, 125, 125, 125, - 531, 532, 532, 533, 534, 535, 536, 537, 538, 539, 540, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 541, 542, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 543, 544, 544, 544, 545, - 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, - 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, - 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, - 546, 546, 546, 546, 546, 546, 546, 546, 546, 547, 125, 125, 125, 125, 125, 125, - 546, 546, 546, 546, 546, 546, 548, 549, 546, 546, 546, 546, 546, 546, 546, 546, - 546, 546, 546, 546, 550, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 551, 551, 551, 551, 551, 551, 552, - 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, - 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, - 553, 553, 554, 555, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, - 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, - 556, 556, 556, 556, 557, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 558, 559, 560, 561, 562, 562, 562, 562, 563, 564, 565, 566, 567, - 568, 568, 568, 568, 569, 570, 571, 572, 568, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 573, 573, 573, 573, 573, 574, 125, 125, 125, 125, 125, 125, - 575, 575, 575, 575, 576, 575, 575, 575, 577, 575, 125, 125, 125, 125, 578, 579, - 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, - 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, - 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, - 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 581, - 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, - 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, - 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 583, 125, 125, - 584, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 585, - 586, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, - 257, 257, 587, 125, 125, 588, 589, 590, 590, 590, 590, 590, 590, 590, 590, 590, - 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 591, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 592, 592, 592, 592, 592, 592, 593, 594, 595, 596, 266, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 8, 8, 597, 8, 598, 0, 0, 0, 0, 0, 0, 0, 266, 125, 125, 125, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 599, - 0, 0, 600, 0, 0, 0, 601, 602, 603, 0, 604, 0, 0, 0, 235, 125, - 11, 11, 11, 11, 605, 125, 125, 125, 125, 125, 125, 125, 125, 125, 0, 266, - 0, 0, 0, 0, 0, 234, 0, 606, 125, 125, 125, 125, 125, 125, 125, 125, - 0, 0, 0, 0, 0, 224, 0, 0, 0, 607, 608, 609, 610, 0, 0, 0, - 611, 612, 0, 613, 614, 615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 617, 0, 0, 0, - 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, - 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, - 618, 618, 618, 618, 618, 618, 618, 618, 619, 620, 621, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 4, 622, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 623, 624, 625, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 626, 626, 627, 628, 629, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 630, 631, 125, 632, 632, 632, 633, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 634, 635, - 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 638, 125, 125, - 639, 639, 639, 639, 640, 641, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 334, 0, 0, 0, 642, 125, 125, 125, 125, - 334, 0, 0, 247, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 643, 27, 644, 645, 646, 647, 648, 649, 650, 651, 652, 651, 125, 125, 125, 653, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 0, 0, 252, 0, 0, 0, 0, 0, 0, 266, 226, 334, 334, 334, 0, 599, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 125, 125, 125, 654, 0, - 655, 0, 0, 252, 606, 656, 599, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 657, 350, 350, - 0, 0, 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, 0, 606, 252, 228, - 252, 0, 0, 0, 658, 285, 0, 0, 658, 0, 247, 656, 125, 125, 125, 125, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 266, 247, 659, 234, 0, 350, 235, 599, 285, 658, 234, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 0, 0, 235, 125, 125, 285, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 125, 125, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 660, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 579, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 661, 125, - 248, 318, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 662, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 663, 125, 0, 0, 0, 0, 0, 0, 125, 125, 125, 125, 125, 125, 125, 125, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, - 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, - 1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, - 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, - 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, - 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, - 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199, - 1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, - 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231, - 1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258, - 1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275, - 1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093, - 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010, - 1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347, - 1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424, - 1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, - 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238, - 1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, - 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232, - 1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461, - 1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486, - 1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, - 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, - 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560, - 1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, - 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, - 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, - 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, - 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, - 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0, - 1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, - 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, - 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356, - 1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214, - 1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363, - 1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251, - 1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266, - 1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287, - 1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302, - 1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, - 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375, - 1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353, - 1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234, - 1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403, - 1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412, - 1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0, - 1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721, - 1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0, - 1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757, - 1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776, - 1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0, - 1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793, - 1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814, - 1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0, - 1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728, - 1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764, - 1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821, - 1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, - 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828, - 1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833, - 1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, - 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, - 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938, - 1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0, - 1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0, - 1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0, - 1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0, - 1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0, - 1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0, - 1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0, - 1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, - 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, - 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, - 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, - 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, - 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, - 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, - 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, - 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, - 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, - 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, - 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, - 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, - 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, - 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, - 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, - 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, - 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, - 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, - 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, - 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, - 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, - 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, - 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, - 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, - 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, - 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, - 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, - 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, - 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, - 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575, - 1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0, - 1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0,1937, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1939,1940, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1944,1943, 0,1945, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1949,1950, - 1951,1952,1953,1954,1955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1956,1957,1958,1960,1959, - 1961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, - 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, - 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, - 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, - 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, - 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, - 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, - 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, - 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, - 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, - 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, - 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, - 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, - 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, - 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, - 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, - 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, - 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, - 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, - 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, - 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, - 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, - 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, - 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, - 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, - 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, - 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, - 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, - 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, - 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, - 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, - 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, - 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, - 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const int16_t -_hb_ucd_i16[196] = -{ - 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, - 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, - 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, 0, 3, 3, 3, -3, - -3, -3, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 2527, 1923, 1914, 1918, 0, - 2250, 0, 0, 0, 0, 0, 0, 138, 0, 7, 0, 0, -7, 0, 0, 0, - 1, -1, 1, -1, -1, 1, -1, 0, 1824, 0, 0, 0, 0, 0, 2104, 0, - 2108, 2106, 0, 2106, 1316, 0, 0, 0, 0, 1, -1, 1, -1, -138, 0, 0, - 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, -8, -7, -7, 0, - 1, -1, 0, 2,-1316, 1, -1, 0, -1, 1, -1, 1, -1, 3, 1, -1, - -3, 1, -1, 1, -1, 0, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0, 0, - 0,-2016, 0, 0, 1, -1, 0, 1, 0, 0,-2104, 0, 0, 0, 0,-2106, - -2108,-2106, 0, 0, 1, -1,-2250, 0, 0, 0,-2527, 0, 0, -2, 0, 1, - -1, 0, 1, -1, -}; - -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) -{ - return u<1114110u?_hb_ucd_u8[2176+(((_hb_ucd_u16[((_hb_ucd_u8[u>>4>>5])<<5)+((u>>4)&31u)])<<4)+((u)&15u))]:2; -} -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) -{ - return u<125259u?_hb_ucd_u8[15332+(((_hb_ucd_u8[13892+(((_hb_ucd_u8[12912+(u>>3>>4)])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:0; -} -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) -{ - return (a[i>>1]>>((i&1u)<<2))&15u; -} -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) -{ - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[16692+(((_hb_ucd_b4(16564+_hb_ucd_u8,u>>2>>6))<<6)+((u>>2)&63u))])<<2)+((u)&3u)]:0; -} -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) -{ - return u<918000u?_hb_ucd_u8[19446+(((_hb_ucd_u16[3168+(((_hb_ucd_u8[17652+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:2; -} -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) -{ - return u<195102u?_hb_ucd_u16[6400+(((_hb_ucd_u8[30070+(u>>6)])<<6)+((u)&63u))]:0; -} - - -#elif !defined(HB_NO_UCD_UNASSIGNED) - -static const uint8_t _hb_ucd_u8[17936] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, @@ -5675,10 +2821,1743 @@ _hb_ucd_dm (unsigned u) } +#elif !defined(HB_NO_UCD_UNASSIGNED) + +static const uint8_t +_hb_ucd_u8[17564] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 22, 22, 22, 22, 24, 7, 7, + 25, 26, 22, 22, 22, 27, 28, 29, 22, 30, 31, 32, 33, 34, 35, 36, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 22, 42, + 7, 7, 43, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 44, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 46, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 69, 72, 73, + 69, 69, 64, 74, 64, 64, 75, 76, 77, 78, 79, 80, 81, 82, 69, 83, + 84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34, + 91, 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 93, 94, 95, 96, + 97, 98, 99,100,101,102,103,104, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,105, + 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, + 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, + 107,107, 34, 34,108,109,110,111, 34, 34,112,113,114,115,116,117, + 118,119,120,121,122,123,124,125,126,127,128,129, 34, 34,130,131, + 132,133,134,135,136,137,138,139,140,141,142,122,143,144,145,146, + 147,148,149,150,151,152,153,122,154,155,122,156,157,158,159,122, + 160,161,162,163,164,165,122,122,166,167,168,169,122,170,122,171, + 34, 34, 34, 34, 34, 34, 34,172,173, 34,174,122,122,122,122,122, + 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,175, + 34, 34, 34, 34, 34, 34, 34, 34,176,122,122,122,122,122,122,122, + 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, + 122,122,122,122,122,122,122,122, 34, 34, 34, 34,177,122,122,122, + 34, 34, 34, 34,178,179,180,181,122,122,122,122,182,183,184,185, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,186, + 34, 34, 34, 34, 34, 34, 34, 34, 34,187,188,122,122,122,122,122, + 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,189, + 34, 34,190, 34, 34,191,122,122,122,122,122,122,122,122,122,122, + 122,122,122,122,122,122,122,122,192,193,122,122,122,122,122,122, + 122,122,122,122,122,122,122,122,122,122,122,122,122,122,194,195, + 69,196,197,198,199,200,201,122,202,203,204,205,206,207,208,209, + 69, 69, 69, 69,210,211,122,122,122,122,122,122,122,122,212,122, + 213,122,214,122,122,215,122,122,122,122,122,122,122,122,122,216, + 34,217,218,122,122,122,122,122,219,220,221,122,222,223,122,122, + 224,225,226,227,228,122, 69,229, 69, 69, 69, 69, 69,230,231,232, + 233,234, 69, 69,235,236, 69,237,122,122,122,122,122,122,122,122, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,238, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,239, 34, + 240, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,241, 34, 34, + 34, 34, 34, 34, 34, 34, 34,242,122,122,122,122,122,122,122,122, + 34, 34, 34, 34,243,122,122,122,122,122,122,122,122,122,122,122, + 34, 34, 34, 34, 34, 34,244,122,122,122,122,122,122,122,122,122, + 245,122,246,247,122,122,122,122,122,122,122,122,122,122,122,122, + 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,248, + 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,249, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, + 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25, + 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32, + 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11, + 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11, + 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, + 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, + 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, + 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, + 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, + 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10, + 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11, + 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, + 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11, + 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, + 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2, + 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62, + 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67, + 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43, + 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36, + 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79, + 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36, + 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44, + 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, + 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, + 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, + 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, + 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 44, 43, 43, 43, 43, + 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, + 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, + 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, + 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36, + 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86, + 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62, + 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, + 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86, + 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, + 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, + 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, + 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44, + 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, + 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87, + 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62, + 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, + 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, + 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44, + 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44, + 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44, + 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91, + 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87, + 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61, + 62, 61, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36, + 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77, + 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36, + 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, + 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89, + 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44, + 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96, + 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, + 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, + 36, 36, 61, 81, 43, 43, 43, 44, 7, 7, 7, 7, 7, 44, 36, 36, + 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67, + 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86, + 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, + 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43, + 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, + 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44, + 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71, + 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43, + 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36, + 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67, + 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, + 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, + 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, + 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, + 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, + 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, + 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, + 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44, + 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44, + 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44, + 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, + 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86, + 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44, + 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, + 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, + 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44, + 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7, + 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, + 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80, + 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, + 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, + 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, + 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 44, + 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 64, + 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, + 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, + 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, + 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, + 16, 16, 16, 16,110, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, + 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, + 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, + 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, + 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40, + 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, + 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48, + 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112, + 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41, + 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41, + 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65, + 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124, + 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2, + 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65, + 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104, + 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, + 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51, + 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, + 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67, + 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11, + 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27, + 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44, + 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144, + 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67, + 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, + 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, + 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, + 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 92, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67, + 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67, + 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8, + 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, + 8, 8,129,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,129,148,148,148,148,148,148,148,148,148,148,147, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,144, 26, 8, 8,144, 67, 67, 67, 44, 67, 67, 67, 67, 67, + 67, 67, 67, 55, 67, 67, 67, 67, 32, 11, 32, 34, 34, 34, 34, 11, + 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,140, 67, 67,138, 34,149, + 43, 32, 44, 44, 93, 2, 99, 2, 16, 16, 16,150, 44, 44,150, 44, + 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57, + 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61, + 2,121,121, 2,125,126,121, 2, 2, 2, 2, 6, 2,108,121, 2, + 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2, + 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44, + 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44, + 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, + 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, + 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, + 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67, + 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, + 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2, + 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, + 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, + 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, + 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, + 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, + 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, + 32, 32, 11, 11, 34,110, 44, 44, 32,150,150, 32, 32, 44, 44, 44, + 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, + 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, + 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2, + 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, + 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93, + 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52, + 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, + 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85, + 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44, + 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36, + 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86, + 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, + 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40, + 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44, + 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, + 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171, + 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71, + 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, + 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, + 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67, + 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148, + 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130, + 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36, + 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, + 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, + 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44, + 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, + 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, + 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92, + 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, + 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, + 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36, + 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, + 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, + 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93, + 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16, + 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44, + 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44, + 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, + 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27, + 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27, + 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93, + 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, + 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, + 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44, + 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30, + 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36, + 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, + 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, + 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, + 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, + 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, + 27, 27, 27, 27, 27, 27, 27,100, 36, 36, 36, 36, 36, 57,184, 44, + 36, 44, 44, 44, 44, 44, 44, 44, 27, 27, 27, 95, 44, 44, 44, 44, + 180, 27, 30, 2, 2, 44, 44, 44, 36, 43, 43, 2, 2, 44, 44, 44, + 36, 36,183, 27, 27, 27, 44, 44, 87, 98, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 43, 60, 2, 2, 2, 44, + 27, 27, 27, 7, 7, 7, 7, 7, 71, 70, 71, 44, 44, 44, 44, 57, + 86, 87, 43, 85, 87, 60,185, 2, 2, 80, 44, 44, 44, 44, 79, 44, + 43, 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, 87, 43, + 43, 43, 80, 7, 7, 7, 7, 7, 2, 2, 94, 98, 44, 44, 44, 44, + 36, 70, 2, 61, 44, 44, 44, 44, 36, 94, 86, 43, 43, 43, 43, 85, + 98, 36, 63, 2, 59, 43, 60, 87, 7, 7, 7, 7, 7, 63, 63, 2, + 179, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 36, 86, 87, 43, 86, 85, 43, 2, 2, 2, 80, + 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, + 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, + 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, + 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, + 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, + 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 94, 86, 43, 43, 43, 43, + 86, 43, 85, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 93, 71, + 86, 87, 43, 43, 85, 85, 86, 87, 85, 43, 36, 72, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 36, 36, 94, 86, 43, 43, 44, 86, 86, 43, 87, + 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44, + 86, 87, 43, 43, 43, 85, 87, 87, 60, 2, 61, 44, 44, 44, 44, 44, + 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 87, 86, + 43, 43, 43, 87, 63, 44, 44, 44, 86, 43, 43, 87, 43, 43, 44, 44, + 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, + 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, + 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, + 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, + 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44, + 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60, + 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, + 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, + 2, 64, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, + 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, + 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, + 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, + 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, + 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, + 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, + 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, + 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, + 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, + 65, 65, 65, 65,132, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44, + 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, + 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44, + 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, + 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, + 86, 44, 44, 44, 44, 44, 44, 44, 40, 40, 52, 40, 40, 40, 52, 81, + 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44, + 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 80, 44, 44, 44, 44, + 67, 67, 67, 92, 55, 67, 67, 67, 67, 67,186, 87, 43, 67,186, 86, + 86,187, 65, 65, 65, 84, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67, + 67, 67, 67, 67, 67, 43, 43, 67, 67, 43, 76, 44, 44, 44, 44, 44, + 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16, + 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, + 16, 16,110, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11, + 11, 11, 11, 16, 16,150,150, 16, 16, 16,150, 16, 16, 16, 16, 16, + 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16, + 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11, + 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, + 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43, + 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, + 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, + 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, + 43, 43, 43, 80, 43, 43, 43, 43, 43, 43, 43, 43, 80, 57, 43, 43, + 43, 57, 80, 43, 43, 80, 44, 44, 43, 43, 43, 74, 40, 40, 40, 44, + 7, 7, 7, 7, 7, 44, 44, 77, 36, 36, 36, 36, 36, 36, 36, 80, + 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 44, 44, 96, + 36, 36, 36, 61, 36, 36, 62, 61, 36, 36, 61,179, 27, 27, 27, 27, + 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,163, 27, + 188, 27,100, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,163, + 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36, + 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44, + 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62, + 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61, + 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36, + 8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, + 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, + 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 55, 67, + 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 44, 67, 67, 92, 44, + 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44, + 65, 65, 65, 65, 65, 65, 65, 65,171,171,171,171,171,171,171, 44, + 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, + 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, + 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, + 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, + 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, + 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, + 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, + 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, + 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, + 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, + 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, + 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, + 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, + 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, + 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, + 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, + 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, + 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, + 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, + 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, + 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, + 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, + 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, + 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, + 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, + 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, + 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 34, 0, 35, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, + 0, 0, 39, 40, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, + 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, + 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, + 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, + 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, + 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, + 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, + 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, + 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 75, 0, 0, 76, 77, 0, + 0, 78, 79, 0, 80, 62, 0, 81, 82, 0, 0, 83, 84, 85, 0, 0, + 0, 86, 0, 87, 0, 0, 51, 88, 51, 0, 89, 0, 90, 0, 0, 0, + 79, 0, 0, 0, 91, 92, 0, 93, 94, 95, 96, 0, 0, 0, 0, 0, + 51, 0, 0, 0, 0, 97, 98, 0, 0, 0, 0, 99,100, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,101, 0, 0,102, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,103,104, 0, 0,105, 0, 0, 0, 0, 0, 0, + 106, 0, 0, 0,100, 0, 0, 0, 0, 0,107,108, 0, 0, 0, 0, + 0, 0, 0,109, 0,110, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, + 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, + 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, + 0, 27, 0, 0, 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, + 33, 0, 0, 35, 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, + 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, + 42, 0, 0, 0, 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, + 47, 0, 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, + 0, 51, 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, + 0, 56, 0, 0, 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, + 0, 0, 0, 61, 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, + 0, 0, 0, 67, 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, + 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, + 0, 81, 0, 0, 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, + 84, 0, 85, 0, 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, + 0, 0, 0, 88, 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, + 0, 0, 33, 0, 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, + 0, 0, 93, 0, 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, + 0, 0, 98, 0, 0, 0, 99, 0,100, 93, 0, 0,101, 0, 0, 0, + 84, 0, 0,102, 0, 0, 0,103,104, 0, 0,105,106, 0, 0, 0, + 0, 0, 0,107, 0, 0,108, 0, 0, 0, 0,109, 33, 0,110,111, + 112, 35, 0, 0,113, 0, 0, 0,114, 0, 0, 0, 0, 0, 0,115, + 0, 0,116, 0, 0, 0, 0,117, 88, 0, 0, 0, 0, 0, 57, 0, + 0, 0, 0, 52,118, 0, 0, 0, 0,119, 0, 0,120, 0, 0, 0, + 0,118, 0, 0, 0, 0, 0,121, 0, 0, 0,122, 0, 0, 0,123, + 0,124, 0, 0, 0, 0,125,126,127, 0,128, 0,129, 0, 0, 0, + 130,131,132, 0, 0, 0, 35, 0, 0, 0,133, 0, 0,134, 0, 0, + 135, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, + 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, + 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, + 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, + 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, + 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, + 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, + 0, 0, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, + 54, 21, 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, + 0, 0, 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, + 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, + 0, 0, 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, + 0, 77, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, + 0, 80, 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, + 0, 0, 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, + 1, 52, 15, 86, 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, + 1, 0, 0, 0, 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, + 0, 78, 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, + 21, 1, 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, + 81, 99,100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, + 0, 0, 0, 61, 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, + 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, + 61, 0, 0, 0, 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, + 0, 0, 0,107, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, + 0, 0, 0,108, 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, + 0, 0, 19, 58, 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, + 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, + 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, 0, 38, 1, 58, + 1, 58, 0, 0, 63, 89, 0, 0,115, 0, 0, 0, 55, 0, 0, 0, + 0,115, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, 0, 0, + 0, 0, 56, 0, 89, 80, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0, + 116, 0, 0, 0, 0, 0, 0,117, 0,118,119,120,121, 0,104, 4, + 122, 49, 23, 0, 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, + 1, 1, 39, 1, 48,105, 87, 0, 0, 0, 0, 1, 4,122, 0, 0, + 0, 1,123, 0, 0, 0, 0, 0,230,230,230,230,230,232,220,220, + 220,220,232,216,220,220,220,220,220,202,202,220,220,220,220,202, + 202,220,220,220, 1, 1, 1, 1, 1,220,220,220,220,230,230,230, + 230,240,230,220,220,220,230,230,230,220,220, 0,230,230,230,220, + 220,220,220,230,232,220,220,230,233,234,234,233,234,234,233,230, + 0, 0, 0,230, 0,220,230,230,230,230,220,230,230,230,222,220, + 230,230,220,220,230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, + 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230, + 230,220,220,230,220,230,230,220, 35, 0, 0, 0, 0, 0,230,230, + 230, 0, 0,230,230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0, + 230,220,230,230,220,220,230,220,220,230,220,230,220,230,230, 0, + 0,220, 0, 0,230,230, 0,230, 0,230,230,230,230,230, 0, 0, + 0,220,220,220,230,220,220,220,230,230, 0,220, 27, 28, 29,230, + 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, + 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, + 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,118,118, 9, 0, + 122,122,122,122,220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, + 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0, + 130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, + 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, + 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,230,220, 0,220, + 230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0,230, 0, 1, 1, + 1, 0, 0, 0,230,234,214,220,202,230,230,230,230,230,232,228, + 228,220,218,230,233,220,230,220,230,230, 1, 1, 1, 1, 1,230, + 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228,232,222,224,224, + 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, + 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, + 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, + 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, + 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,220,220,220, 0, + 230,230, 7, 0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19, + 17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,237, 0, 1, 2, 2, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, 0, 0, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, + 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, 25, 26, 0, 27, 0, 28, + 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 33, 34, 35, 36, 0, + 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, + 0, 0, 0, 0, 1, 2, 40, 41, 0, 1, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 3, 4, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, + 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 11, 12, + 0, 13, 0, 14, 15, 16, 0, 0, 0, 0, 0, 1, 17, 18, 0, 19, + 7, 1, 0, 0, 0, 20, 20, 7, 20, 20, 20, 20, 20, 20, 20, 8, + 21, 0, 22, 0, 7, 23, 24, 0, 20, 20, 25, 0, 0, 0, 26, 27, + 1, 7, 20, 20, 20, 20, 20, 1, 28, 29, 30, 31, 0, 0, 20, 0, + 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 20, 20, + 20, 1, 0, 0, 8, 21, 32, 4, 0, 10, 0, 33, 7, 20, 20, 20, + 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, 37, 0, 38, 1, 20, 20, + 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, 20, 0, 0, 0, 1, 0, + 0, 40, 1, 1, 0, 0, 8, 21, 0, 1, 0, 1, 0, 1, 0, 0, + 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 7, 20, 41, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 0, 42, 43, 44, 0, 45, + 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 46, 7, 1, 10, 1, + 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, + 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13, + 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, 7, 7, 43, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 44, 0, 0, 1, + 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56, + 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61, + 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109, + 110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123, + 124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138, + 139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151, + 152,153,154,155, 96, 96,156,157,158,159, 96,160, 96,161,162,162, + 162,162,162,162,162,163,164,162,165, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,166,167,167, + 167,167,167,167,167,167,168, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96,169,169,169,169,170, 96, 96, 96,171,171, + 171,171,172,173,174,175, 96, 96, 96, 96,176,177,178,179,180,180, + 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,180,180,180,180,180,180,180,181,180,180, + 180,180,180,180,182,182,182,183,184, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,185,186,187, + 188,189,189,190, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96,191,192, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194, 59,195, + 196,197,198,199,200, 96,201,202,203, 59, 59,204, 59,205,206,206, + 206,206,206,207, 96, 96, 96, 96, 96, 96, 96, 96,208, 96,209, 96, + 210, 96, 96,211, 96, 96, 96, 96, 96, 96, 96, 96, 96,212,213,214, + 215, 96, 96, 96, 96, 96,216,217,218, 96,219,220, 96, 96,221,222, + 59,223,224, 96, 59, 59, 59, 59, 59, 59, 59,225,226,227,228,229, + 59, 59,230,231, 59,232, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,233, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,234, 70,235, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,236, 70, 70, 70, 70, + 70, 70, 70, 70, 70,237, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, + 70, 70,238, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, + 70, 70, 70, 70,239, 96, 96, 96, 96, 96, 96, 96, 96, 96,240, 96, + 241,242, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, + 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, + 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, + 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, + 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, + 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, + 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, + 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, + 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, + 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, + 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, + 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, + 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, + 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, + 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, + 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, + 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, + 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, + 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, + 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, + 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, + 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, + 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, + 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, + 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, + 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, + 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, + 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, + 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, + 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, + 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, + 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, + 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, + 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, + 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, + 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, + 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, + 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, + 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23, + 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, + 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, + 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, + 16, 2, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, + 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36, + 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, + 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, + 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, + 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, + 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, + 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 2, 2, 25, 25, + 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, + 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2, + 2, 2, 2, 8, 2, 2, 8, 8, 8, 0, 8, 8, 8, 8, 12, 12, + 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, + 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, + 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, 30, + 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, + 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, 2, + 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 2, 2, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32, + 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, + 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48, + 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52, + 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58, + 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, + 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 2, 76, 76, + 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, + 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, + 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 2, + 2, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, + 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, + 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, + 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, + 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, + 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, + 0, 0, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, + 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55, + 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, + 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 0, 0, + 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, + 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, + 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, + 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, + 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, + 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, + 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, + 0, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 19, 19, + 2, 19, 2, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 2, 2, 2, + 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 65, 65, + 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, + 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 12, 12, + 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, + 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 2, 68, 68, 68, 68, 68, 68, 2, 2, 68, 68, + 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 2, 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, 92, 92, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 30, + 30, 30, 30, 30, 30, 2, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 87, 87, + 87, 87, 87, 87, 2, 2, 87, 87, 2, 2, 2, 2, 2, 2, 12, 12, + 12, 12, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 13, 13, + 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, + 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, 14, 2, 14, 14, + 2, 14, 14, 2, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, + 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, + 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 3, 3, + 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, + 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, + 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, + 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, + 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, + 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, + 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, + 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, + 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, + 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, + 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, + 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,110,110, + 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, + 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, + 19, 19, 19, 19, 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81,120,120, + 120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116, + 116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, 2,116,128,128, + 128,128,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, + 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, + 97, 97, 97, 97, 97, 97, 2, 2, 2, 2, 97, 97, 97, 97, 2, 2, + 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 2, + 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 2, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, + 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, 88, 88,117,117, + 117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112, 2, 2, 2, 2,112,112,112,112,112, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, + 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 2, 2, 2, 2, 2,122,122,122,122,122,122,122,122,122,122, + 2, 2, 2, 2, 2, 2, 2,122,122,122,122, 2, 2, 2, 2,122, + 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, + 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, + 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144, + 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,156,156, + 156,156,156,156,156,156,156,156, 2,156,156,156, 2, 2,156,156, + 2, 2, 2, 2, 2, 2,147,147,147,147,147,147,147,147,148,148, + 148,148,148,148,148,148,148,148, 2, 2, 2, 2, 2, 2,158,158, + 158,158,158,158,158,158,158,158, 2, 2, 2, 2, 2, 2,153,153, + 153,153,153,153,153,153,153,153,153,153, 2, 2, 2, 2,149,149, + 149,149,149,149,149,149,149,149,149,149,149,149,149, 2, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, + 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, 2, 94, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 85, 2, 2,101,101,101,101,101,101,101,101,101, 2, + 2, 2, 2, 2, 2, 2,101,101, 2, 2, 2, 2, 2, 2, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 96, 96,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111, 2,100,100, + 100,100,100,100,100,100, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 2, 2, 2,108,108,108,108,108,108,108,108,108,108, + 2,108,108,108,108,108,108,108,108,108,108,108,108, 2,129,129, + 129,129,129,129,129, 2,129, 2,129,129,129,129, 2,129,129,129, + 129,129,129,129,129,129,129,129,129,129,129,129, 2,129,129,129, + 2, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109, + 109, 2, 2, 2, 2, 2,109,109, 2, 2, 2, 2, 2, 2,107,107, + 107,107, 2,107,107,107,107,107,107,107,107, 2, 2,107,107, 2, + 2,107,107,107,107,107,107,107,107,107,107,107,107,107,107, 2, + 107,107,107,107,107,107,107, 2,107,107, 2,107,107,107,107,107, + 2, 1,107,107,107,107,107, 2, 2,107,107,107, 2, 2,107, 2, + 2, 2, 2, 2, 2,107, 2, 2, 2, 2, 2,107,107,107,107,107, + 107,107, 2, 2,107,107,107,107,107,107,107, 2, 2, 2,137,137, + 137,137,137,137,137,137,137,137,137,137, 2,137,137,137,137,137, + 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, + 2, 2, 2, 2, 2, 2,123,123,123,123,123,123,123,123,123,123, + 123,123,123,123, 2, 2,114,114,114,114,114,114,114,114,114,114, + 114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, 32, + 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, + 2, 2, 2, 2, 2, 2,126,126,126,126,126,126,126,126,126,126, + 126, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, 2,126,126, + 126,126,126,126,126, 2,142,142,142,142,142,142,142,142,142,142, + 142,142, 2, 2, 2, 2,125,125,125,125,125,125,125,125,125,125, + 125, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,125,154,154, + 154,154,154,154,154, 2, 2,154, 2, 2,154,154,154,154,154,154, + 154,154, 2,154,154, 2,154,154,154,154,154,154,154,154,154,154, + 154,154,154,154, 2,154,154, 2, 2,154,154,154,154,154,154,154, + 2, 2, 2, 2, 2, 2,150,150,150,150,150,150,150,150, 2, 2, + 150,150,150,150,150,150,150,150,150,150,150, 2, 2, 2,141,141, + 141,141,141,141,141,141,140,140,140,140,140,140,140,140,140,140, + 140, 2, 2, 2, 2, 2,121,121,121,121,121,121,121,121,121, 2, + 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, + 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, + 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, + 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, + 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, + 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, + 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, + 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, + 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, + 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, + 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, + 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2, 86, 2, + 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, + 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, + 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 80, 2, + 2, 2, 2, 2, 2, 2,127,127,127,127,127,127,127,127,127,127, + 127,127,127,127,127, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115, + 115,115,115,115,115,115,115,115,115,115,115,115,115, 2,115,115, + 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, + 159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103, + 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119, + 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119, + 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,146,146, + 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, + 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136, + 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, + 155,155,155,155, 2, 2,136, 2, 2, 2, 2, 2, 2, 2, 17, 17, + 17, 17, 2, 17, 17, 17, 17, 17, 17, 17, 2, 17, 17, 2, 17, 15, + 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 15, 15, + 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139, + 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105, + 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105, + 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, + 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, + 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, + 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, + 131,131,131,131,131,131, 56, 56, 56, 56, 56, 56, 56, 2, 56, 2, + 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 2, 56, 56, 56, 56, + 56, 2, 2, 2, 2, 2,151,151,151,151,151,151,151,151,151,151, + 151,151,151, 2, 2, 2,151,151,151,151,151,151, 2, 2,151,151, + 2, 2, 2, 2,151,151,160,160,160,160,160,160,160,160,160,160, + 160,160,160,160,160, 2,152,152,152,152,152,152,152,152,152,152, + 2, 2, 2, 2, 2,152, 30, 30, 30, 30, 2, 30, 30, 2,113,113, + 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, + 113,113,113,113,113, 2,132,132,132,132,132,132,132,132,132,132, + 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 3, 3, + 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, + 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, + 2, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, + 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 0, 0, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13, + 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, + 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, + 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, + 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, + 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, + 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, + 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, + 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0, + 110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 118,119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,129,130,131, + 132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147, + 148,149,150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160, + 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,169,170, 0, 0, 0, 0,171,172, 0, 0, 0,173,174,175,176, + 177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192, + 193,194,195,196,197,198,199,200,201,202,203,204,205,206, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, +}; +static const uint16_t +_hb_ucd_u16[9200] = +{ + 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, + 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, + 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, + 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, + 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, + 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50, + 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58, + 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66, + 48, 67, 68, 69, 48, 70, 71, 48, 72, 73, 48, 48, 74, 32, 75, 32, + 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101, + 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113, + 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124, + 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135, + 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140, + 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140, + 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48, + 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175, + 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, + 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, + 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, + 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, + 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, + 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, + 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, + 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, + 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, + 279, 279, 279, 279, 279, 279, 279, 279, 280, 209, 281, 209, 209, 209, 209, 282, + 209, 283, 279, 284, 209, 285, 286, 209, 209, 209, 287, 140, 288, 140, 271, 271, + 271, 289, 209, 209, 209, 209, 290, 271, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 291, 292, 209, 209, 293, 209, 209, 209, 209, 209, 209, 294, 209, + 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279, + 300, 301, 279, 279, 279, 302, 279, 303, 209, 209, 209, 279, 304, 209, 209, 305, + 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308, + 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313, + 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140, + 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325, + 326, 327, 328, 329, 136, 48, 48, 48, 48, 330, 178, 48, 48, 48, 48, 331, + 332, 48, 48, 136, 48, 48, 48, 48, 200, 333, 48, 48, 209, 209, 323, 48, + 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209, + 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48, + 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342, + 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349, + 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, + 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151, + 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377, + 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 315, 11, 11, 385, 386, 11, + 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 388, 48, 389, 48, 48, 206, + 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, + 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, + 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, + 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, + 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410, + 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419, + 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, + 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, + 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, + 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, + 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140, + 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, + 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, + 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, + 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, + 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, + 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 476, + 48, 48, 477, 478, 140, 140, 140, 140, 48, 464, 479, 48, 62, 480, 140, 48, + 481, 140, 140, 48, 482, 140, 48, 314, 483, 48, 48, 484, 485, 457, 486, 487, + 222, 48, 48, 488, 489, 48, 196, 192, 490, 48, 491, 492, 493, 48, 48, 494, + 222, 48, 48, 495, 496, 497, 498, 499, 48, 97, 500, 501, 140, 140, 140, 140, + 502, 503, 504, 48, 48, 505, 506, 192, 507, 83, 84, 508, 509, 510, 511, 512, + 48, 48, 48, 513, 514, 515, 478, 140, 48, 48, 48, 516, 517, 192, 140, 140, + 48, 48, 518, 519, 520, 521, 140, 140, 48, 48, 48, 522, 523, 192, 524, 140, + 48, 48, 525, 526, 192, 140, 140, 140, 48, 173, 527, 528, 314, 140, 140, 140, + 48, 48, 500, 529, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 530, + 531, 532, 48, 533, 534, 192, 140, 140, 140, 140, 535, 48, 48, 536, 537, 140, + 538, 48, 48, 539, 540, 541, 48, 48, 542, 543, 544, 48, 48, 48, 48, 196, + 84, 48, 518, 545, 546, 148, 175, 547, 48, 548, 549, 550, 140, 140, 140, 140, + 551, 48, 48, 552, 553, 192, 554, 48, 555, 556, 192, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 48, 557, 140, 140, 140, 100, 271, 558, 559, 560, + 48, 207, 140, 140, 140, 140, 140, 140, 272, 272, 272, 272, 272, 272, 561, 562, + 48, 48, 48, 48, 388, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 563, + 48, 48, 200, 564, 140, 140, 140, 140, 48, 48, 48, 48, 314, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 565, + 48, 48, 48, 566, 567, 568, 569, 570, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 271, 571, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 572, 573, 574, 574, 575, 576, 140, 140, 140, 140, 577, 578, + 48, 48, 48, 48, 48, 48, 48, 440, 48, 48, 48, 48, 48, 199, 140, 140, + 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 579, + 48, 48, 580, 140, 140, 580, 581, 48, 48, 48, 48, 48, 48, 48, 48, 206, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 582, 583, 140, 140, 140, 140, 140, + 32, 32, 584, 32, 585, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 586, 209, 209, 209, 587, 588, + 589, 209, 590, 209, 209, 209, 288, 140, 209, 209, 209, 209, 591, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 271, 592, 209, 209, 209, 209, 209, 287, 271, 461, + 9, 593, 11, 594, 595, 596, 241, 9, 597, 598, 599, 600, 601, 9, 593, 11, + 602, 603, 11, 604, 605, 606, 607, 9, 608, 11, 9, 593, 11, 594, 595, 11, + 241, 9, 597, 607, 9, 608, 11, 9, 593, 11, 609, 9, 610, 611, 612, 613, + 11, 614, 9, 615, 616, 617, 618, 11, 619, 9, 620, 11, 621, 622, 622, 622, + 32, 32, 32, 623, 32, 32, 624, 625, 626, 627, 45, 140, 140, 140, 140, 140, + 628, 629, 140, 140, 140, 140, 140, 140, 630, 631, 632, 140, 140, 140, 140, 140, + 48, 48, 151, 633, 634, 140, 140, 140, 140, 48, 635, 140, 48, 48, 636, 637, + 140, 140, 140, 140, 140, 140, 638, 200, 48, 48, 48, 48, 639, 585, 140, 140, + 9, 9, 597, 11, 640, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 498, + 271, 271, 641, 642, 140, 140, 140, 140, 498, 271, 643, 644, 140, 140, 140, 140, + 645, 48, 646, 647, 648, 649, 650, 651, 652, 206, 653, 206, 140, 140, 140, 654, + 209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 655, 655, 655, 209, 324, + 656, 209, 209, 209, 209, 209, 209, 209, 209, 209, 657, 140, 140, 140, 658, 209, + 659, 209, 209, 325, 660, 661, 324, 140, 209, 209, 209, 209, 209, 209, 209, 662, + 209, 209, 209, 209, 209, 663, 426, 426, 209, 209, 209, 209, 209, 209, 209, 323, + 209, 209, 209, 209, 209, 660, 325, 427, 325, 209, 209, 209, 664, 176, 209, 209, + 664, 209, 657, 661, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 657, 665, + 287, 209, 426, 288, 324, 176, 664, 287, 209, 666, 209, 209, 288, 140, 140, 192, + 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 196, 48, 48, 48, 48, + 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 100, 140, 48, 204, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 71, 140, 140, 140, 667, 140, 668, 668, 668, 668, 668, 668, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, + 391, 391, 391, 391, 391, 391, 391, 669, 391, 391, 391, 391, 391, 391, 391, 670, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, + 0, 0, 0, 0, 0, 4, 0, 4, 2, 2, 5, 2, 2, 2, 5, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 6, 0, 0, 0, 0, 7, 8, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 16, 17, 14, 14, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 20, 21, 21, 21, 22, 20, 21, 21, 21, 21, + 21, 23, 24, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 27, 28, 26, + 29, 30, 31, 32, 31, 31, 31, 31, 33, 34, 35, 31, 31, 31, 36, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 29, 31, 31, 31, 31, + 37, 38, 37, 37, 37, 37, 37, 37, 37, 39, 31, 31, 31, 31, 31, 31, + 40, 40, 40, 40, 40, 40, 41, 26, 42, 42, 42, 42, 42, 42, 42, 43, + 44, 44, 44, 44, 44, 45, 44, 46, 47, 47, 47, 48, 37, 49, 31, 31, + 31, 50, 51, 31, 31, 31, 31, 31, 31, 31, 31, 31, 52, 31, 31, 31, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, + 56, 57, 58, 59, 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, + 68, 69, 70, 71, 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, + 80, 81, 82, 83, 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, + 92, 93, 94, 95, 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, + 103, 104, 105, 106, 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, + 113, 114, 115, 113, 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, + 122, 123, 124, 122, 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, + 131, 132, 133, 131, 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, + 136, 137, 138, 139, 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, + 146, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, + 150, 151, 152, 152, 153, 152, 152, 154, 155, 154, 152, 156, 26, 26, 26, 26, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 158, 157, 157, 157, 159, 158, 157, + 157, 157, 157, 158, 157, 157, 157, 160, 157, 160, 161, 162, 26, 26, 26, 26, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 164, 164, 164, 164, 165, 166, 164, 164, 164, 164, 164, 167, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 170, 171, 170, 169, 169, 169, 169, + 169, 170, 169, 169, 169, 169, 170, 171, 170, 169, 171, 169, 169, 169, 169, 169, + 169, 169, 170, 169, 169, 169, 169, 169, 169, 169, 169, 172, 169, 169, 169, 173, + 169, 169, 169, 174, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 176, 176, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 178, 178, 178, 179, 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, 180, 182, + 183, 183, 184, 185, 186, 186, 187, 26, 188, 188, 189, 26, 190, 191, 192, 26, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 194, 193, 195, 193, 195, + 196, 197, 197, 198, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 199, + 197, 197, 197, 197, 197, 200, 177, 177, 177, 177, 177, 177, 177, 177, 201, 26, + 202, 202, 202, 203, 202, 204, 202, 204, 205, 202, 206, 206, 206, 207, 208, 26, + 209, 209, 209, 209, 209, 210, 209, 209, 209, 211, 209, 212, 193, 193, 193, 193, + 213, 213, 213, 214, 215, 215, 215, 215, 215, 215, 215, 216, 215, 215, 215, 217, + 215, 218, 215, 218, 215, 219, 9, 9, 9, 220, 26, 26, 26, 26, 26, 26, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 222, 221, 221, 221, 221, 221, 223, + 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, + 228, 228, 228, 228, 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, + 18, 232, 164, 164, 164, 164, 164, 233, 224, 26, 234, 9, 235, 236, 237, 238, + 2, 2, 2, 2, 239, 240, 2, 2, 2, 2, 2, 241, 242, 243, 2, 244, + 2, 2, 2, 2, 2, 2, 2, 245, 9, 9, 9, 9, 9, 9, 9, 9, + 14, 14, 246, 246, 14, 14, 14, 14, 246, 246, 14, 247, 14, 14, 14, 246, + 14, 14, 14, 14, 14, 14, 248, 14, 248, 14, 249, 250, 14, 14, 251, 252, + 0, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 255, 256, + 0, 257, 2, 258, 0, 0, 0, 0, 259, 26, 9, 9, 9, 9, 260, 26, + 0, 0, 0, 0, 261, 262, 4, 0, 0, 263, 0, 0, 2, 2, 2, 2, + 2, 264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 257, 26, 26, 26, 0, 265, 26, 26, 0, 0, 0, 0, + 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 267, 0, + 0, 0, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 2, 2, 2, 2, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 270, 271, + 164, 164, 164, 164, 165, 166, 272, 272, 272, 272, 272, 272, 272, 273, 274, 273, + 169, 169, 171, 26, 171, 171, 171, 171, 171, 171, 171, 171, 18, 18, 18, 18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, + 276, 276, 276, 277, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 278, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 26, 26, 26, 0, 280, + 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, + 292, 293, 293, 293, 293, 293, 294, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 295, 0, 0, 293, 293, 293, 293, 0, 0, 0, 0, 280, 26, 290, 290, + 168, 168, 168, 295, 0, 0, 0, 0, 0, 0, 0, 0, 168, 168, 168, 296, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 290, 290, 290, 290, 297, + 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 0, 0, 0, 0, 0, + 276, 276, 276, 276, 276, 276, 276, 276, 0, 0, 0, 0, 0, 0, 0, 0, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 299, 298, 298, 298, 298, 298, 298, 300, 26, 301, 301, 301, 301, 301, 301, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 303, 26, 26, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 26, + 0, 0, 0, 0, 305, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 306, 2, 2, 2, 2, 2, 2, 2, 307, 308, 309, 26, 26, 310, 2, + 311, 311, 311, 311, 311, 312, 0, 313, 314, 314, 314, 314, 314, 314, 314, 26, + 315, 315, 315, 315, 315, 315, 315, 315, 316, 317, 315, 318, 53, 53, 53, 53, + 319, 319, 319, 319, 319, 320, 321, 321, 321, 321, 322, 323, 168, 168, 168, 324, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 326, 325, 327, 163, 163, 163, 328, + 329, 329, 329, 329, 329, 329, 330, 26, 329, 331, 329, 332, 163, 163, 163, 163, + 333, 333, 333, 333, 333, 333, 333, 333, 334, 26, 26, 335, 336, 336, 337, 26, + 338, 338, 338, 26, 171, 171, 2, 2, 2, 2, 2, 339, 340, 341, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 336, 336, 336, 336, 336, 342, 336, 343, + 168, 168, 168, 168, 344, 26, 168, 168, 295, 345, 168, 168, 168, 168, 168, 344, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 346, 26, 26, 26, 26, + 347, 26, 348, 349, 25, 25, 350, 351, 352, 25, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 353, 26, 354, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 355, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 356, 31, 31, 31, 31, 31, 31, 357, 26, 26, 26, 26, 31, 31, + 9, 9, 0, 313, 9, 358, 0, 0, 0, 0, 359, 0, 257, 280, 360, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 361, + 362, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 363, 290, 289, 290, + 290, 290, 290, 364, 168, 168, 168, 295, 365, 365, 365, 366, 257, 257, 26, 367, + 368, 369, 368, 368, 370, 368, 368, 371, 368, 372, 368, 372, 26, 26, 26, 26, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 373, + 374, 0, 0, 0, 0, 0, 375, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 252, 0, 376, 377, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 378, + 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 280, + 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, + 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 26, 26, 26, 26, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, + 398, 398, 398, 399, 398, 400, 401, 401, 401, 401, 402, 401, 401, 401, 401, 402, + 403, 403, 403, 403, 403, 26, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408, + 407, 408, 409, 407, 410, 407, 410, 411, 26, 26, 26, 26, 26, 26, 26, 26, + 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, + 412, 412, 412, 412, 412, 412, 413, 26, 412, 412, 414, 26, 412, 26, 26, 26, + 415, 2, 2, 2, 2, 2, 416, 307, 26, 26, 26, 26, 26, 26, 26, 26, + 417, 418, 419, 419, 419, 419, 420, 421, 422, 422, 423, 422, 424, 424, 424, 424, + 425, 425, 425, 426, 427, 425, 26, 26, 26, 26, 26, 26, 428, 428, 429, 430, + 431, 431, 431, 432, 433, 433, 433, 434, 26, 26, 26, 26, 26, 26, 26, 26, + 435, 435, 435, 435, 436, 436, 436, 437, 436, 436, 438, 436, 436, 436, 436, 436, + 439, 440, 441, 442, 443, 443, 444, 445, 443, 446, 443, 446, 447, 447, 447, 447, + 448, 448, 448, 448, 26, 26, 26, 26, 449, 449, 449, 449, 450, 451, 450, 26, + 452, 452, 452, 452, 452, 452, 453, 454, 455, 455, 456, 455, 457, 457, 458, 457, + 459, 459, 460, 461, 26, 462, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 463, 463, 463, 463, 463, 463, 463, 463, 463, 464, 26, 26, 26, 26, 26, 26, + 465, 465, 465, 465, 465, 465, 466, 26, 465, 465, 465, 465, 465, 465, 466, 467, + 468, 468, 468, 468, 468, 26, 468, 469, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, + 470, 470, 470, 470, 470, 471, 472, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 473, 473, 473, 473, 473, 26, 474, 474, 474, 474, 474, 475, 26, 26, 476, 476, + 476, 477, 26, 26, 26, 26, 478, 478, 478, 479, 26, 26, 480, 480, 481, 26, + 482, 482, 482, 482, 482, 482, 482, 482, 482, 483, 484, 482, 482, 482, 483, 485, + 486, 486, 486, 486, 486, 486, 486, 486, 487, 488, 489, 489, 489, 490, 489, 491, + 492, 492, 492, 492, 492, 492, 493, 492, 492, 26, 494, 494, 494, 494, 495, 26, + 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 497, 137, 498, 26, + 499, 499, 500, 499, 499, 499, 499, 501, 26, 26, 26, 26, 26, 26, 26, 26, + 502, 503, 504, 505, 504, 506, 507, 507, 507, 507, 507, 507, 507, 508, 507, 509, + 510, 511, 512, 513, 513, 514, 515, 516, 511, 517, 518, 519, 520, 521, 521, 26, + 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 523, 524, 26, 26, 26, + 525, 525, 525, 525, 525, 525, 525, 525, 525, 26, 525, 526, 26, 26, 26, 26, + 527, 527, 527, 527, 527, 527, 528, 527, 527, 527, 527, 528, 26, 26, 26, 26, + 529, 529, 529, 529, 529, 529, 529, 529, 530, 26, 529, 531, 197, 532, 26, 26, + 533, 533, 533, 533, 533, 533, 533, 534, 533, 534, 26, 26, 26, 26, 26, 26, + 535, 535, 535, 536, 535, 537, 535, 535, 538, 26, 26, 26, 26, 26, 26, 26, + 539, 539, 539, 539, 539, 539, 539, 540, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, 542, 543, + 544, 545, 546, 547, 547, 547, 548, 549, 544, 26, 547, 550, 26, 26, 26, 26, + 26, 26, 26, 26, 551, 552, 551, 551, 551, 551, 551, 552, 553, 26, 26, 26, + 554, 554, 554, 554, 554, 554, 554, 554, 554, 26, 555, 555, 555, 555, 555, 555, + 555, 555, 555, 555, 556, 26, 177, 177, 557, 557, 557, 557, 557, 557, 557, 558, + 559, 560, 559, 559, 559, 559, 561, 559, 562, 26, 559, 559, 559, 563, 564, 564, + 564, 564, 565, 564, 564, 566, 567, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 568, 569, 570, 570, 570, 570, 568, 571, 570, 26, 570, 572, 573, 574, 575, 575, + 575, 576, 577, 578, 575, 579, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 580, 580, 580, 581, + 26, 26, 26, 26, 26, 26, 582, 26, 108, 108, 108, 108, 108, 108, 583, 584, + 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, + 585, 585, 585, 586, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 587, 588, 26, + 585, 585, 585, 585, 585, 585, 585, 585, 589, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 591, 26, + 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, + 592, 592, 592, 592, 592, 593, 592, 594, 26, 26, 26, 26, 26, 26, 26, 26, + 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, + 595, 595, 595, 595, 595, 595, 595, 595, 596, 26, 26, 26, 26, 26, 26, 26, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, + 304, 304, 304, 304, 304, 304, 304, 597, 598, 598, 598, 599, 598, 600, 601, 601, + 601, 601, 601, 601, 601, 601, 601, 602, 601, 603, 604, 604, 604, 605, 605, 26, + 606, 606, 606, 606, 606, 606, 606, 606, 607, 26, 606, 608, 608, 606, 606, 609, + 606, 606, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 610, 610, 610, 610, 610, 610, 610, 610, + 610, 610, 610, 611, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 613, 612, 612, 612, 612, 612, 612, + 612, 614, 612, 612, 26, 26, 26, 26, 26, 26, 26, 26, 615, 26, 346, 26, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 26, + 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, + 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 618, 26, 26, 26, 26, 26, + 616, 619, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 620, 621, + 622, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 623, 26, 26, 26, 26, 26, 624, 26, 625, 26, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 627, + 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 629, 628, 630, + 628, 631, 628, 632, 280, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 9, 9, 9, 9, 9, 633, 9, 9, 220, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 280, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 26, + 0, 0, 0, 0, 257, 362, 0, 0, 0, 0, 0, 0, 634, 635, 0, 636, + 637, 638, 0, 0, 0, 639, 0, 0, 0, 0, 0, 0, 0, 265, 26, 26, + 14, 14, 14, 14, 14, 14, 14, 14, 246, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 280, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 257, 26, 0, 0, 0, 259, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, + 0, 0, 0, 254, 640, 641, 0, 642, 643, 0, 0, 0, 0, 0, 0, 0, + 268, 644, 254, 254, 0, 0, 0, 645, 646, 647, 648, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, + 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, + 649, 650, 26, 651, 652, 649, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 2, 2, 2, 347, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 653, 269, 269, 654, 655, 656, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 657, 657, 657, 657, 657, 658, 657, 659, 657, 660, 26, 26, 26, 26, 26, 26, + 26, 26, 661, 661, 661, 662, 26, 26, 663, 663, 663, 663, 663, 663, 663, 664, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 171, 665, 169, 171, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 667, 666, 668, 26, 26, 26, 26, 26, + 669, 669, 669, 669, 669, 669, 669, 669, 669, 670, 669, 671, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 362, 0, + 0, 0, 0, 0, 0, 0, 376, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 362, 0, 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, 26, 26, 26, 26, + 672, 31, 31, 31, 673, 674, 675, 676, 677, 678, 673, 679, 673, 675, 675, 680, + 31, 681, 31, 682, 683, 681, 31, 682, 26, 26, 26, 26, 26, 26, 51, 26, + 0, 0, 0, 0, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 280, 26, 0, 257, 362, 0, 362, 0, 362, 0, 0, 0, 275, 26, + 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, 26, 26, 684, 0, 0, 0, + 685, 26, 0, 0, 0, 0, 0, 280, 0, 259, 313, 26, 275, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 686, 0, 376, 0, 376, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 280, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 280, 259, 26, + 0, 280, 0, 0, 0, 0, 0, 0, 0, 26, 0, 313, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 275, 313, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 280, 26, 0, 275, 376, 376, + 257, 26, 0, 0, 0, 376, 0, 265, 275, 26, 0, 313, 0, 26, 257, 26, + 0, 0, 359, 0, 0, 0, 0, 0, 0, 265, 26, 26, 26, 26, 0, 313, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 26, 26, 26, 26, + 276, 276, 276, 276, 276, 276, 276, 687, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 279, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 346, 26, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 687, 26, 26, 26, + 276, 276, 276, 279, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 688, 26, 26, 26, 26, 26, 26, + 689, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, + 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, + 1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, + 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, + 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, + 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, + 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199, + 1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, + 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231, + 1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258, + 1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275, + 1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0, + 1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093, + 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010, + 1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347, + 1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424, + 1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, + 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238, + 1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, + 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232, + 1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461, + 1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486, + 1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, + 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0, + 1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, + 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, + 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560, + 1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, + 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, + 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, + 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, + 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0, + 1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, + 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, + 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, + 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, + 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, + 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0, + 1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, + 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, + 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356, + 1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214, + 1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363, + 1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251, + 1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266, + 1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287, + 1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302, + 1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, + 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375, + 1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353, + 1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234, + 1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403, + 1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412, + 1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0, + 1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721, + 1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0, + 1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757, + 1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776, + 1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0, + 1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793, + 1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814, + 1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0, + 1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728, + 1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764, + 1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821, + 1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, + 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828, + 1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833, + 1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, + 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, + 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, + 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, + 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938, + 1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0, + 1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870, + 1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0, + 1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0, + 1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0, + 1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, + 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0, + 1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0, + 1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0, + 1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, + 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, + 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, + 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, + 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, + 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, + 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, + 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, + 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, + 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, + 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, + 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, + 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, + 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, + 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, + 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, + 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, + 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, + 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, + 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, + 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, + 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, + 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, + 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, + 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, + 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, + 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, + 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, + 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, + 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, + 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, + 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575, + 1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0, + 1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0,1937, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1939,1940, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1944,1943, 0,1945, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1949,1950, + 1951,1952,1953,1954,1955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1956,1957,1958,1960,1959, + 1961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, + 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, + 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, + 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, + 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, + 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, + 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, + 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, + 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, + 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, + 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, + 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, + 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, + 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, + 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, + 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, + 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, + 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, + 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, + 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, + 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, + 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, + 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, + 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, + 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, + 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, + 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, + 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, + 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, + 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, + 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, + 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, + 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, + 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, +}; +static const int16_t +_hb_ucd_i16[196] = +{ + 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, + 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, + 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, 0, 3, 3, 3, -3, + -3, -3, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 2527, 1923, 1914, 1918, 0, + 2250, 0, 0, 0, 0, 0, 0, 138, 0, 7, 0, 0, -7, 0, 0, 0, + 1, -1, 1, -1, -1, 1, -1, 0, 1824, 0, 0, 0, 0, 0, 2104, 0, + 2108, 2106, 0, 2106, 1316, 0, 0, 0, 0, 1, -1, 1, -1, -138, 0, 0, + 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, -8, -7, -7, 0, + 1, -1, 0, 2,-1316, 1, -1, 0, -1, 1, -1, 1, -1, 3, 1, -1, + -3, 1, -1, 1, -1, 0, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0, 0, + 0,-2016, 0, 0, 1, -1, 0, 1, 0, 0,-2104, 0, 0, 0, 0,-2106, + -2108,-2106, 0, 0, 1, -1,-2250, 0, 0, 0,-2527, 0, 0, -2, 0, 1, + -1, 0, 1, -1, +}; + +static inline uint_fast8_t +_hb_ucd_gc (unsigned u) +{ + return u<1114110u?_hb_ucd_u8[6664+(((_hb_ucd_u8[1296+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; +} +static inline uint_fast8_t +_hb_ucd_ccc (unsigned u) +{ + return u<125259u?_hb_ucd_u8[8612+(((_hb_ucd_u8[8068+(((_hb_ucd_u8[7624+(((_hb_ucd_u8[7288+(((_hb_ucd_u8[7042+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; +} +static inline unsigned +_hb_ucd_b4 (const uint8_t* a, unsigned i) +{ + return (a[i>>1]>>((i&1u)<<2))&15u; +} +static inline int_fast16_t +_hb_ucd_bmg (unsigned u) +{ + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9356+(((_hb_ucd_u8[9236+(((_hb_ucd_b4(9108+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; +} +static inline uint_fast8_t +_hb_ucd_sc (unsigned u) +{ + return u<918000u?_hb_ucd_u8[10862+(((_hb_ucd_u16[2000+(((_hb_ucd_u8[10142+(((_hb_ucd_u8[9692+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; +} +static inline uint_fast16_t +_hb_ucd_dm (unsigned u) +{ + return u<195102u?_hb_ucd_u16[5888+(((_hb_ucd_u8[16764+(((_hb_ucd_u8[16382+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; +} + + #else static const uint8_t -_hb_ucd_u8[13602] = +_hb_ucd_u8[13246] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, @@ -6146,331 +5025,309 @@ _hb_ucd_u8[13602] = 220, 0, 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216, - 216, 0,220,220,220, 0,230,230, 7, 0, 16, 17, 17, 17, 17, 17, - 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,129,169, - 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 216, 0,220,220,220, 0,230,230, 7, 0, 16, 17, 17, 33, 17, 49, + 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, + 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, + 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, + 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, + 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, + 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, + 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, + 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, + 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, + 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, + 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, + 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, + 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, + 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, + 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, + 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, + 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, + 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, + 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, + 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, + 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, + 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, + 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, + 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, + 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, + 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, + 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, + 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 3, 3, 3, 3, 3, 3, + 3, 15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, 0, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, - 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, - 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, - 0, 33, 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 1, 2, 40, 41, 0, 1, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, - 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, - 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, 0, 0, - 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, 20, 20, - 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, 20, 20, - 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, 28, 29, - 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, 0, 10, - 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, - 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, - 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, 0, 1, - 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, - 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, - 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, - 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 11, 12, 12, 12, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 12, 21, 12, 12, 12, 12, 22, - 23, 23, 23, 24, 12, 12, 12, 25, 26, 27, 12, 28, 29, 30, 31, 32, - 33, 34, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 35, - 12, 36, 7, 7, 37, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 38, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 32, 33, 33, 33, 34, 35, 35, 35, 35, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 2, 2, 51, 51, 52, 53, 54, 55, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 57, 57, 56, 56, 56, 56, 56, 56, 58, 59, 60, 61, - 56, 62, 62, 63, 64, 65, 66, 67, 68, 69, 70, 56, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 71, - 62, 62, 62, 62, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 74, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, 88, 89, 89, 89, 90, 89, - 91, 92, 93, 94, 95, 95, 96, 97, 87, 98, 99,100,101,102,103,104, - 105,105,105, 2,106,107,108,109,110,111,112,113,114,115,116, 87, - 89,117,118,119,120,121,122,123,124,125,126, 87,127,128, 87,129, - 130,131,132, 87,133,134,135,136,137,138, 87, 87,139,140,141,142, - 87,143, 87,144,145,145,145,145,145,145,145,145,145,145,145, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87,146,147,147,147,147,147,147,147,147,147, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,148,148,148,148, - 148, 87, 87, 87,149,149,149,149,150,151,152,152, 87, 87, 87, 87, - 153,153,154,155,156,156,156,156,156,156,156,156,156,156,156,156, - 156,156,156,156,156,156,156,156,156,156,157,157,157,157,156, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87,158,159,160,161,162,162,162, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,163,164, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87,165, 56, 56, 56,166,167, 51, 56, 56, 87, 56, 56, 56, 56, - 56, 56, 56, 56,168,168,168,168,168,168, 87, 87, 87, 87, 87, 87, - 87, 87, 2, 87,169, 87,170, 87, 87,171, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 33,172,172,173, 87, 87, 87, 87, 87, 56, 56, 56, 87, - 89, 89, 87, 87, 56, 56, 56, 56,174, 87, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 87, 87, 87, 87, - 87, 87, 87, 87, 62, 62, 62, 62, 62, 62, 62, 62, 87, 87, 87, 87, - 87, 87, 87, 87, 62, 62, 62, 62, 62, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 62, 62, 62, 62, 62, 62, 62, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 56, 87,175,175, 0, 1, 2, 2, 0, 1, 2, 2, - 2, 3, 4, 5, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, - 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, - 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 11, 11, - 11, 11, 12, 11, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 15, 16, 16, 16, 16, 16, 17, 18, 18, - 18, 18, 18, 18, 19, 20, 21, 21, 22, 23, 21, 24, 21, 21, 21, 21, - 21, 25, 21, 21, 26, 26, 26, 26, 26, 21, 21, 21, 27, 27, 27, 27, - 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 26, 21, 21, 21, 21, 21, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, + 18, 17, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 25, 25, 26, 27, + 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 31, + 31, 31, 31, 54, 55, 55, 56, 31, 31, 31, 31, 31, 31, 31, 57, 58, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 59, 60, 31, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 63, 64, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 65, 66, 67, 31, 31, 31, 31, 68, 31, 31, 31, 31, 31, + 31, 31, 31, 69, 70, 71, 17, 17, 72, 73, 31, 74, 75, 76, 31, 77, + 78, 31, 79, 80, 17, 81, 17, 17, 17, 17, 31, 31, 23, 23, 23, 23, + 23, 23, 31, 31, 31, 31, 31, 31, 23, 82, 31, 31, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 83, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 84, 0, 0, 1, + 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, + 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 11, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 19, 27, + 28, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, + 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 42, 43, 44, 44, 45, 46, + 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 50, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 51, + 60, 61, 62, 63, 64, 65, 66, 7, 67, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 7, 4, 4, 4, 4, 77, 77, 77, 77, 78, 79, 80, 81, + 82, 83, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, + 0, 0, 0, 0, 86, 87, 88, 88, 89, 90, 48, 91, 0, 0, 92, 92, + 92, 92, 92, 93, 94, 95, 96, 97, 98, 47, 99,100,101,102, 0,103, + 104,105, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 0,106,106,106,106,106,106,106,106,106,106,106,107, + 108,108,108,108,108, 11,109,110,111, 4,112, 4,113,114,115,116, + 117,118,119,120,121,122,123,124,125,126, 50,127, 47, 47, 47, 47, + 47, 47, 47, 47,128,128,128,128,128,128,128,128,128,128,128,128, + 92, 92, 92, 92, 92, 92, 92, 92,129,130, 19, 19, 19, 19, 19, 19, + 131, 19, 19, 19,132,133, 19,134,135,136,137,101,138,138,138,138, + 0, 77,139,140,128,128,141,142,143,144,145,146,147,148,149,150, + 151,152,153,153,154,154,154,154,154,154, 4, 4,155,156,157,158, + 159,160,161,162,163,164,165,166,167,168,169,169,170,170,171,171, + 172,172,128,128, 19, 19,173,173,174,175,176,177,178,178,179,180, + 181,182,183,184,185,185,186,187,188,189,128,128,190,190,191,191, + 128,128,192,192,193,194,195,195,196,196,128,128,197,197,198,198, + 199,199,200,200,201,202,203,204,128,128,128,128,205,206,207,207, + 208,209,210,210,128,128,211,211,128,128,212, 34,213,213,213,213, + 213,213,213,213,213,213,213,213,213,213,128,128,128,128,128,128, + 128,128,214,214,215,215,215,215,215,215,215,215,215,215,128,128, + 128,128,128,128,216,216,216,216,216,216,216,216,216,216,128,128, + 128,128,128,128,110,110,110,110,110,110,110,110,110,217,218,219, + 220,220,220,220,221,221,221,221,222,222,222,223,224,224,224,224, + 224,224,224,224,224,224,224,224,225,225,225,225,225,225,225,225, + 224,224,128,128,128,128,128,128,128,128,104,104,226,227,227,227, + 228,229,230,230,230,230,230,230,128,128,128,128,231,231,232, 0, + 128,128,128,128,128,128,128,128, 7,233, 0, 0, 0, 0, 0, 0, + 0,234,235, 0, 77, 77, 0, 0, 0, 0,128,128,236,236,236,236, + 236,236,236,236,236,236,236,236,128,128,128,128,128,128,128,128, + 4, 4,128,128, 86, 86,128,128,237,237,128,128,128,128,238,239, + 128,128,128,128,128,128,128,128,128,128, 48, 48,240,240,240,240, + 241,241,128,128, 0, 0, 0, 0, 0, 0,128,128, 19, 19, 19, 19, + 128,128,128,128,242, 0,128,128, 0, 0, 0, 0, 92, 92,128,128, + 128,128,128,128, 92, 92, 92, 92, 92, 92,128,128, 0, 0,128,128, + 7, 7, 7, 7, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, + 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, + 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 11, 11, 11, 11, 12, 11, + 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 15, 16, 16, 16, 16, + 16, 17, 18, 18, 18, 18, 18, 18, 19, 20, 21, 21, 22, 23, 21, 24, + 21, 21, 21, 21, 21, 25, 21, 21, 26, 26, 26, 26, 26, 21, 21, 21, + 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 26, 21, 21, 21, 31, 21, 32, 32, 32, 32, 32, 33, 34, 32, 35, 35, 35, 35, - 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, - 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, - 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, - 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, - 43, 43, 43, 43, 44, 44, 44, 45, 44, 44, 44, 44, 46, 46, 46, 46, - 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 48, 47, 47, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, - 50, 50, 50, 51, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, + 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, + 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, + 44, 44, 44, 45, 44, 44, 44, 44, 46, 46, 46, 46, 47, 47, 47, 47, + 47, 48, 47, 47, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, + 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 56, 56, 57, 57, 57, 57, 58, 57, 59, 59, 60, 61, - 62, 62, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 65, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 55, 55, 55, 55, 55, 67, 67, 67, 67, - 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, 64, 64, 70, 70, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 8, 8, 8, 8, 8, 72, 72, 72, 72, + 62, 62, 63, 63, 64, 64, 64, 64, 65, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 55, 67, 67, 67, 67, 67, 68, 68, 68, 69, 69, 69, 69, + 69, 69, 64, 64, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 8, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, 50, 50, 50, 73, 77, 78, 79, 4, 4, 80, 4, - 4, 81, 82, 83, 4, 4, 4, 84, 8, 8, 8, 8, 11, 11, 11, 11, - 11, 11, 11, 11, 85, 0, 0, 0, 0, 0, 0, 86, 0, 4, 0, 0, - 0, 8, 8, 8, 0, 0, 87, 88, 89, 0, 4, 4, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 90, - 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 4, 4, 92, 92, 92, 92, - 92, 92, 92, 92, 50, 50, 50, 93, 93, 93, 93, 93, 53, 53, 53, 53, - 53, 53, 13, 13, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 0, 95, 0, 96, 97, 98, 99, 99, 99, 99,100,101,102, - 102,102,102,103,104,104,104,105, 52, 52, 52, 52, 52, 0,104,104, - 0, 0, 0,102, 52, 52, 0, 0, 0, 0, 52,106, 0, 0, 0, 0, - 0,102,102,107,102,102,102,102,102,108, 0, 0, 94, 94, 94, 94, - 0, 0, 0, 0,109,109,109,109,109,109,109,109,109,109,109,109, - 109,110,110,110,111,111,111,111,111,111,111,111,111,111,111,111, - 13, 13, 13, 13, 13, 13,112,112,112,112,112,112, 0, 0,113, 4, - 4, 4, 4, 4,114, 4, 4, 4, 4, 4, 4, 4,115,115,115, 0, - 116,116,116,116,117,117,117,117,117,117, 32, 32,118,118,119,120, - 120,120, 52, 52,121,121,121,121,122,121, 49, 49,123,123,123,123, - 123,123, 49, 49,124,124,124,124,124,124,125,125, 53, 53, 53, 4, - 4,126,127, 54, 54, 54, 54, 54,125,125,125,125,128,128,128,128, - 128,128,128,128, 4,129, 18, 18, 18, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21,130, 21, 21, 21, 21, 8, 0,131, 0, - 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21,132, 0, 0, 1, 2, - 1, 2,133,101,102,134, 52, 52, 52, 52, 0, 0,135,135,135,135, - 135,135,135,135, 0, 0, 0, 0, 11, 11, 11, 11, 11, 0, 11, 11, - 11, 0, 0,136,137,137,138,138,138,138,139, 0,140,140,140,141, - 141,142,142,142,143,143,144,144,144,144,144,144,145,145,145,145, - 145,146,146,146,147,147,147,148,148,148,148,148,149,149,149,150, - 150,150,150,151,151,151,151,151,151,151,151,151,152,152,152,152, - 152,152,152,152,153,153,153,153,154,154,155,155,156,156,156,156, - 156,156,157,157,158,158,159,159,159,159,159,159,160,160,161,161, - 161,161,161,161,162,162,162,162,162,162,163,163,164,164,164,164, - 165,165,165,165,166,166,166,166,167,167,168,168,169,169,169,169, - 169,169,169,169,170,170,170,170,170,170,170,170,171,171,171,171, - 171,171,171,171,172,172,172,172,172,172,172,172,173,173,173,173, - 173,173,173,173,174,174,174,175,175,175,175,176,176,176,176,177, - 177,177,178,178,179,179,179,179,179,179,179,179,180,180,180,180, - 180,181,181,181,182,182,182,182,182,183,183,183,184,184,184,184, - 184,184,185, 43,186,186,186,186,186,186,186,186,187,187,187,188, + 4, 81, 82, 83, 4, 4, 4, 84, 11, 11, 11, 11, 85, 0, 0, 0, + 0, 0, 0, 86, 0, 4, 0, 0, 0, 8, 8, 8, 0, 0, 87, 88, + 89, 0, 4, 4, 6, 0, 0, 0, 90, 90, 90, 90, 91, 91, 91, 91, + 91, 91, 4, 4, 92, 92, 92, 92, 50, 50, 50, 93, 93, 93, 93, 93, + 53, 53, 13, 13, 94, 94, 94, 94, 94, 94, 94, 0, 95, 0, 96, 97, + 98, 99, 99, 99, 99,100,101,102,102,102,102,103,104,104,104,105, + 52, 0,104,104, 0, 0, 0,102, 52, 52, 0, 0, 0, 0, 52,106, + 0,102,102,107,102,102,102,102,102,108, 0, 0,109,109,109,109, + 109,110,110,110,111,111,111,111, 13, 13,112,112,112,112,112,112, + 0, 0,113, 4,114, 4, 4, 4,115,115,115, 0,116,116,116,116, + 117,117,117,117,117,117, 32, 32,118,118,119,120,120,120, 52, 52, + 121,121,121,121,122,121, 49, 49,123,123,123,123,123,123, 49, 49, + 124,124,124,124,124,124,125,125, 53, 53, 53, 4, 4,126,127, 54, + 125,125,125,125,128,128,128,128, 4,129, 18, 18, 18, 21, 21, 21, + 21, 21, 21,130, 8, 0,131, 0, 0, 0, 0, 21, 21, 21, 21,132, + 0, 0, 1, 2, 1, 2,133,101,102,134, 52, 52,135,135,135,135, + 11, 0, 11, 11, 11, 0, 0,136,137,137,138,138,138,138,139, 0, + 140,140,140,141,141,142,142,142,143,143,144,144,144,144,144,144, + 145,145,145,145,145,146,146,146,147,147,147,148,148,148,148,148, + 149,149,149,150,150,150,150,151,151,151,151,151,152,152,152,152, + 153,153,153,153,154,154,155,155,156,156,156,156,156,156,157,157, + 158,158,159,159,159,159,159,159,160,160,161,161,161,161,161,161, + 162,162,162,162,162,162,163,163,164,164,164,164,165,165,165,165, + 166,166,166,166,167,167,168,168,169,169,169,169,170,170,170,170, + 171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,175, + 175,175,175,176,176,176,176,177,177,177,178,178,179,179,179,179, + 180,180,180,180,180,181,181,181,182,182,182,182,182,183,183,183, + 184,184,184,184,184,184,185, 43,186,186,186,186,187,187,187,188, 188,188,188,188,189,189,189,190,189,189,189,189,191,191,191,191, - 191,191,191,191,192,192,192,192,192,192,192,192,193,193,193,193, - 193,193,193,193,194,194,194,194,194,194, 66, 66,195,195,195,195, - 195,195,195,195,196,196,196,196,196,196,196,196,197,197,197,197, - 197,197,197,197,198,198,198,198,198,198,198,198,199,199,199,199, - 199,199,199,199,200,200,200,200,200,200,200,200,201,201,201,201, - 201,202,202,202,202,202,202, 55,203,203,203,203,204,204,204,204, - 204,204,204,205,205,205,205,205,205,205,205,205,206,206,206,206, - 206,206,207,207,207,207,207,207,207,207,207,207,208,208,208,208, - 208,208,208,208,110,110,110,110, 39, 39, 39, 39,209,209,209,209, - 209,209,209,209,210,210,210,210,210,210,210,210,211,211,211,211, - 211,211,211,211,212,212,212,212,212,212,212,212,112,112,112,112, - 112,112,112,112,112,112,112,112,213,213,213,214,214,214,214,214, - 214,215,215,215,216,216,216,216,216,216,216,216,217,217,217,217, - 217,217,217,217,218,218,218,218,218,218,218,218,218,218,218,218, - 218,218,219, 94,220,220,220,220,220,220,220,220,221,221,221,221, - 221,221,221,221,102,102,102,102,102,102,102,102,222, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,102,102, - 102, 99,223,224,224,224,224,224,224,224,224,224,225,225,225,225, - 225,225,225,225,225,225, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, - 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,226,227,228, 0,229, 0, - 0, 0, 0, 0,230,230,230,230,230,230,230,230, 91, 91, 91, 91, - 91, 91, 91, 91,231,231,231,231,231,231,231,231,232,232,232,232, - 233,233,233,233,234,234,234,234,234,234,234,234,235,235,235,235, - 235,235,235,235,236, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, - 8, 8, 8, 8, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 0, - 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 5, 0, - 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, 8, 11, 8, 8, - 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, 14, 15, 14, 14, - 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 19, 19, 19, 19, 19, - 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, 20, 20, 22, 20, 24, 7, - 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, 20, 21, 27, 27, 27, 27, - 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, - 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, 33, 33, 33, 36, 33, 33, - 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, - 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, - 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 48, 48, 48, 48, - 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, 52, 52, 53, 53, 53, 53, - 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, - 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 61, 62, - 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 0, 0, 66, 66, 66, 66, - 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, 71, 71, 71, 71, 71, 71, - 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, - 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 79, - 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, 7, 7, 83, 7, 84, 85, - 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, 2, 89, 90, 87, 91, 2, - 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, 0, 86, 1, 0, 0, 94, - 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, 0, 4, 97, 97, 97, 97, - 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, 99, 99,100,100,100,100, - 0,101, 0, 0,102,100,103,104, 0, 0,100, 0,105,106,106,106, - 106,106,106,106,106,106,107,105,108,109,109,109,109,109,109,109, - 109,109,110,108,111,111,111,111,112, 55, 55, 55, 55, 55, 55,113, - 109,109,109,110,109,109, 0, 0,114,114,114,114,115,115,115,115, - 116,116,116,116,117,117,117,117, 96, 2, 2, 2, 2, 2, 94, 2, - 118,118,118,118,119,119,119,119,120,120,120,120,121,121,121,121, - 121,121,121,122,123,123,123,123,124,124,124,124,124,124,124,125, - 126,126,126,126,127,127,127,127,128,128,128,128, 2, 2, 3, 2, - 2,129,130, 0,131,131,131,131,132, 17, 17, 18, 20, 20, 20,133, - 7, 7, 7,134, 20, 20, 20, 23, 0,135,109,109,109,109,109,136, - 137,137,137,137, 0, 0, 0,138,139,139,139,139,140,140,140,140, - 84, 0, 0, 0,141,141,141,141,142,142,142,142,143,143,143,143, - 144,144,144,144,145,145,145,145,146,146,146,146,147,147,147,147, - 148,148,148,148,149,149,149,149,150,150,150,150,151,151,151,151, - 152,152,152,152,153,153,153,153,154,154,154,154,155,155,155,155, - 156,156,156,156,157,157,157,157,158,158,158,158,159,159,159,159, - 160,160,160,160,161,161,161,161,162,162,162,162,163,163,163,163, - 164,164,164,164,165,165,165,165,166,166,166,166,167,167,167,167, - 168,168,168,168,169,169,169,169,170,170,170,170,171,171,171,171, - 172,172,172,172,173,173,173,173,174,174,174,174,175,175,175,175, - 176,176,176,176,177,177,177,177,178,178,178,178,179,179,179,179, - 180,180,180,180,181,181,181,181,182,182,182,182,183,183,183,183, - 184,184,184,184,185,185,185,185,186, 45, 45, 45,187,187,187,187, - 188,188,188,188,189,189,189,189,190,190,190,190,190,190,191,190, - 192,192,192,192,193,193,193,193,194,194,194,194,195,195,195,195, - 196,196,196,196,197,197,197,197,198,198,198,198,199,199,199,199, - 200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203, - 204,204,204,204,205,205,205,205,206,206,206,206,207,207,207,207, - 208,208,208,208,209,209,209,209,210,210,210,210,211,211,211,211, - 212,212,212,212,213,213,213,213,214,214,214,214,215,215,215,215, - 216,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219, - 220,221,221,221,222,222,222,222,221,221,221,221,223,106,106,106, - 106,109,109,109,224,224,224,224,225,225,225,225, 0,226, 86, 0, - 0, 0,226, 7, 82,138, 7, 0, 0, 0,227, 86,228,228,228,228, - 229,229,229,229,230,230,230,230,231,231,231,231,232,232,232,232, - 233,233,233,233,234, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, - 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, - 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, - 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, - 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, - 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, - 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, - 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, - 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, - 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, - 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, - 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, - 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, - 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, - 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, - 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, - 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, - 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, - 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, - 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, - 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, - 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, - 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, - 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, - 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, - 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, - 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, - 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, - 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, - 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, - 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, - 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, - 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, - 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, - 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135, - 106,106,106,106,104,104,104,104,161,161,161,161,110,110,110,110, - 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120,116,116,116,116, - 128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72, 98, 98, 98, 98, - 97, 97, 97, 97, 57, 57, 57, 57, 88, 88, 88, 88,117,117,117,117, - 112,112,112,112, 78, 78, 78, 78, 83, 83, 83, 83, 82, 82, 82, 82, - 122,122,122,122, 89, 89, 89, 89,130,130,130,130,144,144,144,144, - 156,156,156,156,147,147,147,147,148,148,148,148,158,158,158,158, - 153,153,153,153,149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85, - 101,101,101,101, 96, 96, 96, 96,111,111,111,111,100,100,100,100, - 100, 36, 36, 36,108,108,108,108,129,129,129,129,109,109,109,109, - 107,107,107,107,107,107,107, 1,137,137,137,137,124,124,124,124, - 123,123,123,123,114,114,114,114,102,102,102,102,126,126,126,126, - 142,142,142,142,125,125,125,125,154,154,154,154,150,150,150,150, - 141,141,141,141,140,140,140,140,121,121,121,121,133,133,133,133, - 134,134,134,134,138,138,138,138,143,143,143,143,145,145,145,145, - 63, 63, 63, 63,157,157,157,157, 80, 80, 80, 80,127,127,127,127, - 115,115,115,115,159,159,159,159,103,103,103,103,119,119,119,119, - 146,146,146,146, 99, 99, 99, 99,136,139, 13, 13,155,155,155,155, - 136,136,136,136, 17, 15, 15, 15,139,139,139,139,105,105,105,105, - 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131,151,151,151,151, - 160,160,160,160,152,152,152,152,113,113,113,113,132,132,132,132, - 15, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, - 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, + 192,192,192,192,193,193,193,193,194,194,194,194,194,194, 66, 66, + 195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198, + 199,199,199,199,200,200,200,200,201,201,201,201,201,202,202,202, + 202,202,202, 55,203,203,203,203,204,204,204,204,204,204,204,205, + 205,205,205,205,206,206,206,206,206,206,207,207,207,207,207,207, + 208,208,208,208,110,110,110,110,209,209,209,209,210,210,210,210, + 211,211,211,211,212,212,212,212,213,213,213,214,214,214,214,214, + 214,215,215,215,216,216,216,216,217,217,217,217,218,218,218,218, + 218,218,219, 94,220,220,220,220,221,221,221,221,222, 99, 99, 99, + 99, 99, 99, 99, 99, 99,102,102,102, 99,223,224,224,224,224,224, + 225,225,225,225,225,225, 0, 0, 8, 0, 0, 0, 0, 0,226,227, + 228, 0,229, 0,230,230,230,230,231,231,231,231,232,232,232,232, + 233,233,233,233,234,234,234,234,235,235,235,235,236, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 0, 0, 0, 4, 0, + 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 5, 0, 2, 5, 6, 0, + 7, 7, 7, 7, 8, 9, 8, 10, 8, 11, 8, 8, 8, 8, 8, 8, + 12, 13, 13, 13, 14, 14, 14, 14, 14, 15, 14, 14, 16, 17, 17, 17, + 17, 17, 17, 17, 18, 19, 19, 19, 19, 19, 19, 19, 20, 21, 20, 22, + 20, 20, 23, 23, 20, 20, 20, 20, 22, 20, 24, 7, 7, 25, 20, 20, + 26, 20, 20, 20, 20, 20, 20, 21, 27, 27, 27, 27, 28, 28, 28, 28, + 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 32, 20, 20, 20, + 33, 33, 33, 33, 34, 35, 33, 33, 33, 36, 33, 33, 37, 37, 37, 37, + 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, + 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, + 46, 46, 46, 46, 46, 46, 46, 47, 48, 48, 48, 48, 49, 49, 49, 49, + 49, 50, 51, 49, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 54, 53, + 55, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, + 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 61, 62, 63, 63, 63, 63, + 64, 64, 64, 64, 64, 65, 0, 0, 66, 66, 66, 66, 67, 67, 67, 67, + 68, 68, 68, 68, 69, 70, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, + 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 76, + 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 79, 80, 80, 80, 80, + 81, 81, 81, 81, 82, 7, 7, 7, 83, 7, 84, 85, 0, 84, 86, 0, + 2, 87, 88, 2, 2, 2, 2, 89, 90, 87, 91, 2, 2, 2, 92, 2, + 2, 2, 2, 93, 0, 0, 0, 86, 1, 0, 0, 94, 0, 95, 96, 0, + 4, 0, 0, 0, 0, 0, 0, 4, 97, 97, 97, 97, 98, 98, 98, 98, + 13, 13, 13, 13, 99, 99, 99, 99,100,100,100,100, 0,101, 0, 0, + 102,100,103,104, 0, 0,100, 0,105,106,106,106,106,106,106,106, + 106,106,107,105,108,109,109,109,109,109,109,109,109,109,110,108, + 111,111,111,111,112, 55, 55, 55, 55, 55, 55,113,109,109,109,110, + 109,109, 0, 0,114,114,114,114,115,115,115,115,116,116,116,116, + 117,117,117,117, 96, 2, 2, 2, 2, 2, 94, 2,118,118,118,118, + 119,119,119,119,120,120,120,120,121,121,121,121,121,121,121,122, + 123,123,123,123,124,124,124,124,124,124,124,125,126,126,126,126, + 127,127,127,127,128,128,128,128, 2, 2, 3, 2, 2,129,130, 0, + 131,131,131,131,132, 17, 17, 18, 20, 20, 20,133, 7, 7, 7,134, + 20, 20, 20, 23, 0,135,109,109,109,109,109,136,137,137,137,137, + 0, 0, 0,138,139,139,139,139,140,140,140,140, 84, 0, 0, 0, + 141,141,141,141,142,142,142,142,143,143,143,143,144,144,144,144, + 145,145,145,145,146,146,146,146,147,147,147,147,148,148,148,148, + 149,149,149,149,150,150,150,150,151,151,151,151,152,152,152,152, + 153,153,153,153,154,154,154,154,155,155,155,155,156,156,156,156, + 157,157,157,157,158,158,158,158,159,159,159,159,160,160,160,160, + 161,161,161,161,162,162,162,162,163,163,163,163,164,164,164,164, + 165,165,165,165,166,166,166,166,167,167,167,167,168,168,168,168, + 169,169,169,169,170,170,170,170,171,171,171,171,172,172,172,172, + 173,173,173,173,174,174,174,174,175,175,175,175,176,176,176,176, + 177,177,177,177,178,178,178,178,179,179,179,179,180,180,180,180, + 181,181,181,181,182,182,182,182,183,183,183,183,184,184,184,184, + 185,185,185,185,186, 45, 45, 45,187,187,187,187,188,188,188,188, + 189,189,189,189,190,190,190,190,190,190,191,190,192,192,192,192, + 193,193,193,193,194,194,194,194,195,195,195,195,196,196,196,196, + 197,197,197,197,198,198,198,198,199,199,199,199,200,200,200,200, + 201,201,201,201,202,202,202,202,203,203,203,203,204,204,204,204, + 205,205,205,205,206,206,206,206,207,207,207,207,208,208,208,208, + 209,209,209,209,210,210,210,210,211,211,211,211,212,212,212,212, + 213,213,213,213,214,214,214,214,215,215,215,215,216,216,216,216, + 217,217,217,217,218,218,218,218,219,219,219,219,220,221,221,221, + 222,222,222,222,221,221,221,221,223,106,106,106,106,109,109,109, + 224,224,224,224,225,225,225,225, 0,226, 86, 0, 0, 0,226, 7, + 82,138, 7, 0, 0, 0,227, 86,228,228,228,228,229,229,229,229, + 230,230,230,230,231,231,231,231,232,232,232,232,233,233,233,233, + 234, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, 0, 26, 26, + 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 9, + 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, + 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, 14, 14, 14, + 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 3, 3, + 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, 1, 3, 3, 3, + 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, 90, 90, 90, 90, + 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, 7, 1, 1, 1, + 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 11, 11, 11, 11, + 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, + 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, 24, 24, 24, 24, + 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, 25, 0, 0, 0, + 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 0, + 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, 28, 28, 28, 28, + 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, + 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, 43, 43, 43, 43, + 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, 32, 0, 32, 32, + 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, 58, 58, 58, 58, + 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, 76, 76, 76, 76, + 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, 1, 1, 1, 0, + 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, + 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, 9, 9, 19, 19, + 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, 0, 0, 0, 19, + 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 56, 56, 56, 56, + 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, 0, 13, 13, 13, + 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, + 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, 39, 39, 39, 39, + 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 60, 60, 60, 60, + 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, 69, 69, 0, 69, + 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, 68, 68, 68, 68, + 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, 19, 19, 0, 0, + 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, 1, 1, 6, 6, + 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, 0, 1, 1, 1, + 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, 41, 41, 41, 41, + 118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, 40, 40, 40, 40, + 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135,106,106,106,106, + 104,104,104,104,161,161,161,161,110,110,110,110, 47, 47, 47, 47, + 81, 81, 81, 81,120,120,120,120,116,116,116,116,128,128,128,128, + 66, 66, 66, 66, 72, 72, 72, 72, 98, 98, 98, 98, 97, 97, 97, 97, + 57, 57, 57, 57, 88, 88, 88, 88,117,117,117,117,112,112,112,112, + 78, 78, 78, 78, 83, 83, 83, 83, 82, 82, 82, 82,122,122,122,122, + 89, 89, 89, 89,130,130,130,130,144,144,144,144,156,156,156,156, + 147,147,147,147,148,148,148,148,158,158,158,158,153,153,153,153, + 149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, + 96, 96, 96, 96,111,111,111,111,100,100,100,100,100, 36, 36, 36, + 108,108,108,108,129,129,129,129,109,109,109,109,107,107,107,107, + 107,107,107, 1,137,137,137,137,124,124,124,124,123,123,123,123, + 114,114,114,114,102,102,102,102,126,126,126,126,142,142,142,142, + 125,125,125,125,154,154,154,154,150,150,150,150,141,141,141,141, + 140,140,140,140,121,121,121,121,133,133,133,133,134,134,134,134, + 138,138,138,138,143,143,143,143,145,145,145,145, 63, 63, 63, 63, + 157,157,157,157, 80, 80, 80, 80,127,127,127,127,115,115,115,115, + 159,159,159,159,103,103,103,103,119,119,119,119,146,146,146,146, + 99, 99, 99, 99,136,139, 13, 13,155,155,155,155,136,136,136,136, + 17, 15, 15, 15,139,139,139,139,105,105,105,105, 0, 0, 0, 1, + 0, 0, 1, 1,131,131,131,131,151,151,151,151,160,160,160,160, + 152,152,152,152,113,113,113,113,132,132,132,132, 15, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, + 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 16, 17, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, - 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -6479,58 +5336,57 @@ _hb_ucd_u8[13602] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, - 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, - 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, + 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, + 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, + 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, - 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, - 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, + 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, + 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, - 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, + 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0, + 109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0, + 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100, - 101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, - 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0, - 115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, + 0, 0,118,119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, - 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,129, + 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, + 146,147,148,149,150,151,152,153,154,155,156,157, 0, 0, 0,158, + 159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0, + 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128,129,130,131,132,133,134,135,136,137,138,139,140,141, - 142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, - 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162,163, 0, 0, 0, - 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, + 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,169,170, 0, 0, 0, 0,171,172, 0, 0, 0,173,174, + 175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190, + 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,169,170, 0, 0, 0, 0,171,172, 0, - 0, 0,173,174,175,176,177,178,179,180,181,182,183,184,185,186, - 187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202, - 203,204,205,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, - 3, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; static const uint16_t _hb_ucd_u16[4888] = @@ -6843,21 +5699,14 @@ _hb_ucd_u16[4888] = 817, 818, 819, 820, 821, 935, 0, 0, }; static const int16_t -_hb_ucd_i16[196] = +_hb_ucd_i16[92] = { - 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, - 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, - 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, 0, 3, 3, 3, -3, - -3, -3, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 2527, 1923, 1914, 1918, 0, - 2250, 0, 0, 0, 0, 0, 0, 138, 0, 7, 0, 0, -7, 0, 0, 0, - 1, -1, 1, -1, -1, 1, -1, 0, 1824, 0, 0, 0, 0, 0, 2104, 0, - 2108, 2106, 0, 2106, 1316, 0, 0, 0, 0, 1, -1, 1, -1, -138, 0, 0, - 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, -8, -7, -7, 0, - 1, -1, 0, 2,-1316, 1, -1, 0, -1, 1, -1, 1, -1, 3, 1, -1, - -3, 1, -1, 1, -1, 0, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0, 0, - 0,-2016, 0, 0, 1, -1, 0, 1, 0, 0,-2104, 0, 0, 0, 0,-2106, - -2108,-2106, 0, 0, 1, -1,-2250, 0, 0, 0,-2527, 0, 0, -2, 0, 1, - -1, 0, 1, -1, + 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, + 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, + 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0, + 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8, + -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0, + 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, }; static inline uint_fast8_t @@ -6878,17 +5727,17 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7714+(((_hb_ucd_u8[7594+(((_hb_ucd_b4(7466+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7858+(((_hb_ucd_u8[7626+(((_hb_ucd_u8[7530+(((_hb_ucd_b4(7466+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918016u?_hb_ucd_u8[11480+(((_hb_ucd_u8[10532+(((_hb_ucd_u8[9124+(((_hb_ucd_u8[8500+(((_hb_ucd_u8[8050+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + return u<918016u?_hb_ucd_u8[11124+(((_hb_ucd_u8[10176+(((_hb_ucd_u8[9204+(((_hb_ucd_u8[8524+(((_hb_ucd_u8[8220+(((_hb_ucd_u8[8106+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[1576+(((_hb_ucd_u8[12802+(((_hb_ucd_u8[12420+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[1576+(((_hb_ucd_u8[12446+(((_hb_ucd_u8[12064+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #endif diff --git a/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh b/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh index c216379201..036c71a424 100644 --- a/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh +++ b/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh @@ -24,42 +24,37 @@ #include "hb-unicode.hh" static const uint8_t -_hb_emoji_u8[544] = +_hb_emoji_u8[464] = { 16, 17, 17, 17, 50, 20, 21, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,118,152, - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 3, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 7, 8, - 0, 0, 0, 9, 0, 0, 10, 11, 12, 13, 14, 13, 15, 16, 17, 0, - 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 0, - 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, - 13, 13, 13, 13, 23, 24, 25, 26, 27, 28, 13, 13, 13, 13, 13, 29, - 13, 13, 13, 13, 30, 31, 13, 13, 13, 32, 13, 13, 0, 33, 0, 34, - 35, 36, 37, 13, 38, 39, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 30, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 16, 0, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 0, 2, 0, 0,240, 3, 0, 6, 0, 0, - 0, 0, 0, 12, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - 0,128, 0, 0, 0,254, 15, 7, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 64, 0, 1, 0, 0, 0, 0, 0, 0,120, - 191,255,247,255,255,255,255,255,255,255,255,255,255,255,255,255, - 63, 0,255,255,255,255,255,255, 63,255, 87, 32, 2, 1, 24, 0, - 144, 80,184, 0,248, 0, 0, 0, 0, 0,224, 0, 2, 0, 1,128, - 0, 0, 0, 0, 0, 0, 48, 0,224, 0, 0, 24, 0, 0, 0, 0, - 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, - 0, 0,128, 2, 0, 0, 0, 0, 0,224, 0, 0, 0,128, 0, 0, - 0, 0, 0, 0, 0,240, 3,192, 0, 64,254, 7, 0,224,255,255, - 255,255,255,255, 63, 0, 0, 0,254,255, 0, 4, 0,128,252,247, - 0,254,255,255,255,255,255,255,255,255,255,255,255,255,255, 7, - 255,255,255,255,255,255,255, 63,192,255,255,255,255,255,255,255, - 255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,255, - 0, 0,224,255,255,255,255,255, 0,240, 0, 0, 0, 0, 0, 0, - 0,255, 0,252, 0, 0, 0, 0, 0,255, 0, 0, 0,192,255,255, - 0,240,255,255,255,255,255,247,191,255,255,255,255,255,255,255, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 3, 4, 0, 0, 5, 6, 0, 7, 0, 8, 9, 10, 11, 12, + 0, 0, 13, 0, 0, 0, 14, 0, 15, 0, 0, 0, 0, 16, 0, 0, + 17, 17, 18, 19, 20, 17, 17, 21, 17, 17, 22, 17, 23, 17, 24, 25, + 26, 27, 28, 17, 17, 17, 0, 0, 17, 17, 17, 17, 17, 17, 17, 29, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 4, 0, 0, + 5, 6, 0, 0, 7, 8, 0, 0, 8, 0, 9, 10, 0, 0, 11, 0, + 0, 12, 13, 14, 15, 16, 16, 16, 17, 16, 16, 16, 18, 19, 20, 21, + 22, 23, 0, 0, 0, 24, 0, 0, 25, 0, 26, 0, 0, 27, 0, 0, + 28, 0, 0, 0, 16, 16, 16, 16, 29, 9, 0, 30, 31, 32, 16, 33, + 34, 35, 36, 16, 16, 16, 16, 37, 16, 38, 39, 16, 16, 16, 40, 0, + 0, 0, 0, 41, 0, 0, 42, 16, 43, 0, 44, 0, 45, 46, 16, 16, + 47, 48, 49, 16, 16, 16, 16, 38, 0, 0, 0, 0, 0, 66, 0, 0, + 0, 0, 0, 16, 0, 2, 0, 0, 4, 0, 0, 2, 0, 0,240, 3, + 0, 6, 0, 0, 0, 0, 0, 12, 0, 1, 0, 0, 0,128, 0, 0, + 0,254, 15, 7, 4, 0, 0, 0, 0, 12, 64, 0, 1, 0, 0, 0, + 0, 0, 0,120,191,255,247,255,255,255,255,255, 63, 0,255,255, + 63,255, 87, 32, 2, 1, 24, 0,144, 80,184, 0,248, 0, 0, 0, + 0, 0,224, 0, 2, 0, 1,128, 0, 0, 48, 0,224, 0, 0, 24, + 0, 0, 33, 0, 0, 0, 1, 32, 0, 0,128, 2, 0,224, 0, 0, + 0,240, 3,192, 0, 64,254, 7, 0,224,255,255, 63, 0, 0, 0, + 254,255, 0, 4, 0,128,252,247, 0,254,255,255,255,255,255, 7, + 255,255,255, 63,192,255,255,255,255,255, 0, 0, 0, 0,240,255, + 0, 0,224,255, 0,240, 0, 0, 0,255, 0,252, 0,255, 0, 0, + 0,192,255,255, 0,240,255,255,255,255,255,247,191,255,255,255, }; static inline unsigned @@ -75,7 +70,7 @@ _hb_emoji_b1 (const uint8_t* a, unsigned i) static inline uint_fast8_t _hb_emoji_is_Extended_Pictographic (unsigned u) { - return u<131070u?_hb_emoji_b1(224+_hb_emoji_u8,((_hb_emoji_u8[64+(((_hb_emoji_b4(_hb_emoji_u8,u>>6>>4))<<4)+((u>>6)&15u))])<<6)+((u)&63u)):0; + return u<131070u?_hb_emoji_b1(264+_hb_emoji_u8,((_hb_emoji_u8[144+(((_hb_emoji_u8[64+(((_hb_emoji_b4(_hb_emoji_u8,u>>5>>2>>3))<<3)+((u>>5>>2)&7u))])<<2)+((u>>5)&3u))])<<5)+((u)&31u)):0; } diff --git a/thirdparty/harfbuzz/src/hb-unicode.cc b/thirdparty/harfbuzz/src/hb-unicode.cc index 9899e01a41..c1795dc7f2 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.cc +++ b/thirdparty/harfbuzz/src/hb-unicode.cc @@ -308,8 +308,8 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, * Since: 0.9.2 **/ void * -hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, - hb_user_data_key_t *key) +hb_unicode_funcs_get_user_data (const hb_unicode_funcs_t *ufuncs, + hb_user_data_key_t *key) { return hb_object_get_user_data (ufuncs, key); } diff --git a/thirdparty/harfbuzz/src/hb-unicode.h b/thirdparty/harfbuzz/src/hb-unicode.h index a500384575..faa8d67924 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.h +++ b/thirdparty/harfbuzz/src/hb-unicode.h @@ -317,8 +317,8 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, HB_EXTERN void * -hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, - hb_user_data_key_t *key); +hb_unicode_funcs_get_user_data (const hb_unicode_funcs_t *ufuncs, + hb_user_data_key_t *key); HB_EXTERN void diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index 40ea3eb017..a1586a58b6 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -47,20 +47,20 @@ HB_BEGIN_DECLS * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 0 +#define HB_VERSION_MINOR 1 /** * HB_VERSION_MICRO: * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 1 +#define HB_VERSION_MICRO 0 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "5.0.1" +#define HB_VERSION_STRING "5.1.0" /** * HB_VERSION_ATLEAST: diff --git a/thirdparty/icu4c/godot_data.json b/thirdparty/icu4c/godot_data.json index 3a9c28af4c..e36e2b078b 100644 --- a/thirdparty/icu4c/godot_data.json +++ b/thirdparty/icu4c/godot_data.json @@ -6,5 +6,6 @@ brkitr_tree: include misc: include normalization: include + confusables: include } -}
\ No newline at end of file +} diff --git a/thirdparty/icu4c/i18n/scriptset.cpp b/thirdparty/icu4c/i18n/scriptset.cpp new file mode 100644 index 0000000000..6a1db8c01c --- /dev/null +++ b/thirdparty/icu4c/i18n/scriptset.cpp @@ -0,0 +1,313 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +********************************************************************** +* Copyright (C) 2014, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* +* scriptset.cpp +* +* created on: 2013 Jan 7 +* created by: Andy Heninger +*/ + +#include "unicode/utypes.h" + +#include "unicode/uchar.h" +#include "unicode/unistr.h" + +#include "scriptset.h" +#include "uassert.h" +#include "cmemory.h" + +U_NAMESPACE_BEGIN + +//---------------------------------------------------------------------------- +// +// ScriptSet implementation +// +//---------------------------------------------------------------------------- +ScriptSet::ScriptSet() { + uprv_memset(bits, 0, sizeof(bits)); +} + +ScriptSet::~ScriptSet() { +} + +ScriptSet::ScriptSet(const ScriptSet &other) { + *this = other; +} + +ScriptSet & ScriptSet::operator =(const ScriptSet &other) { + uprv_memcpy(bits, other.bits, sizeof(bits)); + return *this; +} + +bool ScriptSet::operator == (const ScriptSet &other) const { + for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) { + if (bits[i] != other.bits[i]) { + return false; + } + } + return true; +} + +UBool ScriptSet::test(UScriptCode script, UErrorCode &status) const { + if (U_FAILURE(status)) { + return FALSE; + } + if (script < 0 || (int32_t)script >= SCRIPT_LIMIT) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return FALSE; + } + uint32_t index = script / 32; + uint32_t bit = 1 << (script & 31); + return ((bits[index] & bit) != 0); +} + + +ScriptSet &ScriptSet::set(UScriptCode script, UErrorCode &status) { + if (U_FAILURE(status)) { + return *this; + } + if (script < 0 || (int32_t)script >= SCRIPT_LIMIT) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return *this; + } + uint32_t index = script / 32; + uint32_t bit = 1 << (script & 31); + bits[index] |= bit; + return *this; +} + +ScriptSet &ScriptSet::reset(UScriptCode script, UErrorCode &status) { + if (U_FAILURE(status)) { + return *this; + } + if (script < 0 || (int32_t)script >= SCRIPT_LIMIT) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return *this; + } + uint32_t index = script / 32; + uint32_t bit = 1 << (script & 31); + bits[index] &= ~bit; + return *this; +} + + + +ScriptSet &ScriptSet::Union(const ScriptSet &other) { + for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) { + bits[i] |= other.bits[i]; + } + return *this; +} + +ScriptSet &ScriptSet::intersect(const ScriptSet &other) { + for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) { + bits[i] &= other.bits[i]; + } + return *this; +} + +ScriptSet &ScriptSet::intersect(UScriptCode script, UErrorCode &status) { + ScriptSet t; + t.set(script, status); + if (U_SUCCESS(status)) { + this->intersect(t); + } + return *this; +} + +UBool ScriptSet::intersects(const ScriptSet &other) const { + for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) { + if ((bits[i] & other.bits[i]) != 0) { + return true; + } + } + return false; +} + +UBool ScriptSet::contains(const ScriptSet &other) const { + ScriptSet t(*this); + t.intersect(other); + return (t == other); +} + + +ScriptSet &ScriptSet::setAll() { + for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) { + bits[i] = 0xffffffffu; + } + return *this; +} + + +ScriptSet &ScriptSet::resetAll() { + uprv_memset(bits, 0, sizeof(bits)); + return *this; +} + +int32_t ScriptSet::countMembers() const { + // This bit counter is good for sparse numbers of '1's, which is + // very much the case that we will usually have. + int32_t count = 0; + for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) { + uint32_t x = bits[i]; + while (x > 0) { + count++; + x &= (x - 1); // and off the least significant one bit. + } + } + return count; +} + +int32_t ScriptSet::hashCode() const { + int32_t hash = 0; + for (int32_t i=0; i<UPRV_LENGTHOF(bits); i++) { + hash ^= bits[i]; + } + return hash; +} + +int32_t ScriptSet::nextSetBit(int32_t fromIndex) const { + // TODO: Wants a better implementation. + if (fromIndex < 0) { + return -1; + } + UErrorCode status = U_ZERO_ERROR; + for (int32_t scriptIndex = fromIndex; scriptIndex < SCRIPT_LIMIT; scriptIndex++) { + if (test((UScriptCode)scriptIndex, status)) { + return scriptIndex; + } + } + return -1; +} + +UBool ScriptSet::isEmpty() const { + for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) { + if (bits[i] != 0) { + return FALSE; + } + } + return TRUE; +} + +UnicodeString &ScriptSet::displayScripts(UnicodeString &dest) const { + UBool firstTime = TRUE; + for (int32_t i = nextSetBit(0); i >= 0; i = nextSetBit(i + 1)) { + if (!firstTime) { + dest.append((UChar)0x20); + } + firstTime = FALSE; + const char *scriptName = uscript_getShortName((UScriptCode(i))); + dest.append(UnicodeString(scriptName, -1, US_INV)); + } + return dest; +} + +ScriptSet &ScriptSet::parseScripts(const UnicodeString &scriptString, UErrorCode &status) { + resetAll(); + if (U_FAILURE(status)) { + return *this; + } + UnicodeString oneScriptName; + for (int32_t i=0; i<scriptString.length();) { + UChar32 c = scriptString.char32At(i); + i = scriptString.moveIndex32(i, 1); + if (!u_isUWhiteSpace(c)) { + oneScriptName.append(c); + if (i < scriptString.length()) { + continue; + } + } + if (oneScriptName.length() > 0) { + char buf[40]; + oneScriptName.extract(0, oneScriptName.length(), buf, sizeof(buf)-1, US_INV); + buf[sizeof(buf)-1] = 0; + int32_t sc = u_getPropertyValueEnum(UCHAR_SCRIPT, buf); + if (sc == UCHAR_INVALID_CODE) { + status = U_ILLEGAL_ARGUMENT_ERROR; + } else { + this->set((UScriptCode)sc, status); + } + if (U_FAILURE(status)) { + return *this; + } + oneScriptName.remove(); + } + } + return *this; +} + +void ScriptSet::setScriptExtensions(UChar32 codePoint, UErrorCode& status) { + if (U_FAILURE(status)) { return; } + static const int32_t FIRST_GUESS_SCRIPT_CAPACITY = 20; + MaybeStackArray<UScriptCode,FIRST_GUESS_SCRIPT_CAPACITY> scripts; + UErrorCode internalStatus = U_ZERO_ERROR; + int32_t script_count = -1; + + while (TRUE) { + script_count = uscript_getScriptExtensions( + codePoint, scripts.getAlias(), scripts.getCapacity(), &internalStatus); + if (internalStatus == U_BUFFER_OVERFLOW_ERROR) { + // Need to allocate more space + if (scripts.resize(script_count) == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + internalStatus = U_ZERO_ERROR; + } else { + break; + } + } + + // Check if we failed for some reason other than buffer overflow + if (U_FAILURE(internalStatus)) { + status = internalStatus; + return; + } + + // Load the scripts into the ScriptSet and return + for (int32_t i = 0; i < script_count; i++) { + this->set(scripts[i], status); + if (U_FAILURE(status)) { return; } + } +} + +U_NAMESPACE_END + +U_CAPI UBool U_EXPORT2 +uhash_equalsScriptSet(const UElement key1, const UElement key2) { + icu::ScriptSet *s1 = static_cast<icu::ScriptSet *>(key1.pointer); + icu::ScriptSet *s2 = static_cast<icu::ScriptSet *>(key2.pointer); + return (*s1 == *s2); +} + +U_CAPI int8_t U_EXPORT2 +uhash_compareScriptSet(UElement key0, UElement key1) { + icu::ScriptSet *s0 = static_cast<icu::ScriptSet *>(key0.pointer); + icu::ScriptSet *s1 = static_cast<icu::ScriptSet *>(key1.pointer); + int32_t diff = s0->countMembers() - s1->countMembers(); + if (diff != 0) return static_cast<UBool>(diff); + int32_t i0 = s0->nextSetBit(0); + int32_t i1 = s1->nextSetBit(0); + while ((diff = i0-i1) == 0 && i0 > 0) { + i0 = s0->nextSetBit(i0+1); + i1 = s1->nextSetBit(i1+1); + } + return (int8_t)diff; +} + +U_CAPI int32_t U_EXPORT2 +uhash_hashScriptSet(const UElement key) { + icu::ScriptSet *s = static_cast<icu::ScriptSet *>(key.pointer); + return s->hashCode(); +} + +U_CAPI void U_EXPORT2 +uhash_deleteScriptSet(void *obj) { + icu::ScriptSet *s = static_cast<icu::ScriptSet *>(obj); + delete s; +} diff --git a/thirdparty/icu4c/i18n/scriptset.h b/thirdparty/icu4c/i18n/scriptset.h new file mode 100644 index 0000000000..51980ab7b3 --- /dev/null +++ b/thirdparty/icu4c/i18n/scriptset.h @@ -0,0 +1,86 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +********************************************************************** +* Copyright (C) 2013, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* +* scriptset.h +* +* created on: 2013 Jan 7 +* created by: Andy Heninger +*/ + +#ifndef __SCRIPTSET_H__ +#define __SCRIPTSET_H__ + +#include "unicode/utypes.h" +#include "unicode/uobject.h" +#include "unicode/uscript.h" + +#include "uelement.h" + +U_NAMESPACE_BEGIN + +//------------------------------------------------------------------------------- +// +// ScriptSet - A bit set representing a set of scripts. +// +// This class was originally used exclusively with script sets appearing +// as part of the spoof check whole script confusable binary data. Its +// use has since become more general, but the continued use to wrap +// prebuilt binary data does constrain the design. +// +//------------------------------------------------------------------------------- +class U_I18N_API ScriptSet: public UMemory { + public: + static constexpr int32_t SCRIPT_LIMIT = 224; // multiple of 32! + + ScriptSet(); + ScriptSet(const ScriptSet &other); + ~ScriptSet(); + + bool operator == (const ScriptSet &other) const; + bool operator != (const ScriptSet &other) const {return !(*this == other);} + ScriptSet & operator = (const ScriptSet &other); + + UBool test(UScriptCode script, UErrorCode &status) const; + ScriptSet &Union(const ScriptSet &other); + ScriptSet &set(UScriptCode script, UErrorCode &status); + ScriptSet &reset(UScriptCode script, UErrorCode &status); + ScriptSet &intersect(const ScriptSet &other); + ScriptSet &intersect(UScriptCode script, UErrorCode &status); + UBool intersects(const ScriptSet &other) const; // Sets contain at least one script in common. + UBool contains(const ScriptSet &other) const; // All set bits in other are also set in this. + + ScriptSet &setAll(); + ScriptSet &resetAll(); + int32_t countMembers() const; + int32_t hashCode() const; + int32_t nextSetBit(int32_t script) const; + + UBool isEmpty() const; + + UnicodeString &displayScripts(UnicodeString &dest) const; // append script names to dest string. + ScriptSet & parseScripts(const UnicodeString &scriptsString, UErrorCode &status); // Replaces ScriptSet contents. + + // Wraps around UScript::getScriptExtensions() and adds the corresponding scripts to this instance. + void setScriptExtensions(UChar32 codePoint, UErrorCode& status); + + private: + uint32_t bits[SCRIPT_LIMIT / 32]; +}; + +U_NAMESPACE_END + +U_CAPI UBool U_EXPORT2 +uhash_compareScriptSet(const UElement key1, const UElement key2); + +U_CAPI int32_t U_EXPORT2 +uhash_hashScriptSet(const UElement key); + +U_CAPI void U_EXPORT2 +uhash_deleteScriptSet(void *obj); + +#endif // __SCRIPTSET_H__ diff --git a/thirdparty/icu4c/i18n/ucln_in.cpp b/thirdparty/icu4c/i18n/ucln_in.cpp new file mode 100644 index 0000000000..f29cbe41dd --- /dev/null +++ b/thirdparty/icu4c/i18n/ucln_in.cpp @@ -0,0 +1,65 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +****************************************************************************** +* * +* Copyright (C) 2001-2014, International Business Machines * +* Corporation and others. All Rights Reserved. * +* * +****************************************************************************** +* file name: ucln_in.cpp +* encoding: UTF-8 +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2001July05 +* created by: George Rhoten +*/ + +#include "ucln.h" +#include "ucln_in.h" +#include "mutex.h" +#include "uassert.h" + +/** Auto-client for UCLN_I18N **/ +#define UCLN_TYPE UCLN_I18N +#include "ucln_imp.h" + +/* Leave this copyright notice here! It needs to go somewhere in this library. */ +static const char copyright[] = U_COPYRIGHT_STRING; + +static cleanupFunc *gCleanupFunctions[UCLN_I18N_COUNT]; + +static UBool U_CALLCONV i18n_cleanup(void) +{ + int32_t libType = UCLN_I18N_START; + (void)copyright; /* Suppress unused variable warning with clang. */ + + while (++libType<UCLN_I18N_COUNT) { + if (gCleanupFunctions[libType]) + { + gCleanupFunctions[libType](); + gCleanupFunctions[libType] = NULL; + } + } +#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL)) + ucln_unRegisterAutomaticCleanup(); +#endif + return TRUE; +} + +void ucln_i18n_registerCleanup(ECleanupI18NType type, + cleanupFunc *func) { + U_ASSERT(UCLN_I18N_START < type && type < UCLN_I18N_COUNT); + { + icu::Mutex m; // See ticket 10295 for discussion. + ucln_registerCleanup(UCLN_I18N, i18n_cleanup); + if (UCLN_I18N_START < type && type < UCLN_I18N_COUNT) { + gCleanupFunctions[type] = func; + } + } +#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL)) + ucln_registerAutomaticCleanup(); +#endif +} + diff --git a/thirdparty/icu4c/i18n/ucln_in.h b/thirdparty/icu4c/i18n/ucln_in.h new file mode 100644 index 0000000000..765cdd559f --- /dev/null +++ b/thirdparty/icu4c/i18n/ucln_in.h @@ -0,0 +1,74 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +****************************************************************************** +* Copyright (C) 2001-2016, International Business Machines +* Corporation and others. All Rights Reserved. +****************************************************************************** +* file name: ucln_in.h +* encoding: UTF-8 +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2001July05 +* created by: George Rhoten +*/ + +#ifndef __UCLN_IN_H__ +#define __UCLN_IN_H__ + +#include "unicode/utypes.h" +#include "ucln.h" + +/* +Please keep the order of enums declared in same order +as the functions are suppose to be called. +It's usually best to have child dependencies called first. */ +typedef enum ECleanupI18NType { + UCLN_I18N_START = -1, + UCLN_I18N_UNIT_EXTRAS, + UCLN_I18N_NUMBER_SKELETONS, + UCLN_I18N_CURRENCY_SPACING, + UCLN_I18N_SPOOF, + UCLN_I18N_SPOOFDATA, + UCLN_I18N_TRANSLITERATOR, + UCLN_I18N_REGEX, + UCLN_I18N_JAPANESE_CALENDAR, + UCLN_I18N_ISLAMIC_CALENDAR, + UCLN_I18N_CHINESE_CALENDAR, + UCLN_I18N_HEBREW_CALENDAR, + UCLN_I18N_ASTRO_CALENDAR, + UCLN_I18N_DANGI_CALENDAR, + UCLN_I18N_CALENDAR, + UCLN_I18N_TIMEZONEFORMAT, + UCLN_I18N_TZDBTIMEZONENAMES, + UCLN_I18N_TIMEZONEGENERICNAMES, + UCLN_I18N_TIMEZONENAMES, + UCLN_I18N_ZONEMETA, + UCLN_I18N_TIMEZONE, + UCLN_I18N_DIGITLIST, + UCLN_I18N_DECFMT, + UCLN_I18N_NUMFMT, + UCLN_I18N_ALLOWED_HOUR_FORMATS, + UCLN_I18N_DAYPERIODRULES, + UCLN_I18N_SMPDTFMT, + UCLN_I18N_USEARCH, + UCLN_I18N_COLLATOR, + UCLN_I18N_UCOL_RES, + UCLN_I18N_CSDET, + UCLN_I18N_COLLATION_ROOT, + UCLN_I18N_GENDERINFO, + UCLN_I18N_CDFINFO, + UCLN_I18N_REGION, + UCLN_I18N_LIST_FORMATTER, + UCLN_I18N_NUMSYS, + UCLN_I18N_COUNT /* This must be last */ +} ECleanupI18NType; + +/* Main library cleanup registration function. */ +/* See common/ucln.h for details on adding a cleanup function. */ +/* Note: the global mutex must not be held when calling this function. */ +U_CFUNC void U_EXPORT2 ucln_i18n_registerCleanup(ECleanupI18NType type, + cleanupFunc *func); + +#endif diff --git a/thirdparty/icu4c/i18n/unicode/uspoof.h b/thirdparty/icu4c/i18n/unicode/uspoof.h new file mode 100644 index 0000000000..b674c91b2c --- /dev/null +++ b/thirdparty/icu4c/i18n/unicode/uspoof.h @@ -0,0 +1,1577 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +*************************************************************************** +* Copyright (C) 2008-2016, International Business Machines Corporation +* and others. All Rights Reserved. +*************************************************************************** +* file name: uspoof.h +* encoding: UTF-8 +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2008Feb13 +* created by: Andy Heninger +* +* Unicode Spoof Detection +*/ + +#ifndef USPOOF_H +#define USPOOF_H + +#include "unicode/utypes.h" +#include "unicode/uset.h" +#include "unicode/parseerr.h" + +#if !UCONFIG_NO_NORMALIZATION + + +#if U_SHOW_CPLUSPLUS_API +#include "unicode/localpointer.h" +#include "unicode/unistr.h" +#include "unicode/uniset.h" +#endif + + +/** + * \file + * \brief Unicode Security and Spoofing Detection, C API. + * + * <p> + * This class, based on <a href="http://unicode.org/reports/tr36">Unicode Technical Report #36</a> and + * <a href="http://unicode.org/reports/tr39">Unicode Technical Standard #39</a>, has two main functions: + * + * <ol> + * <li>Checking whether two strings are visually <em>confusable</em> with each other, such as "Harvest" and + * "Ηarvest", where the second string starts with the Greek capital letter Eta.</li> + * <li>Checking whether an individual string is likely to be an attempt at confusing the reader (<em>spoof + * detection</em>), such as "paypal" with some Latin characters substituted with Cyrillic look-alikes.</li> + * </ol> + * + * <p> + * Although originally designed as a method for flagging suspicious identifier strings such as URLs, + * <code>USpoofChecker</code> has a number of other practical use cases, such as preventing attempts to evade bad-word + * content filters. + * + * <p> + * The functions of this class are exposed as C API, with a handful of syntactical conveniences for C++. + * + * <h2>Confusables</h2> + * + * <p> + * The following example shows how to use <code>USpoofChecker</code> to check for confusability between two strings: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * UChar* str1 = (UChar*) u"Harvest"; + * UChar* str2 = (UChar*) u"\u0397arvest"; // with U+0397 GREEK CAPITAL LETTER ETA + * + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setChecks(sc, USPOOF_CONFUSABLE, &status); + * + * int32_t bitmask = uspoof_areConfusable(sc, str1, -1, str2, -1, &status); + * UBool result = bitmask != 0; + * // areConfusable: 1 (status: U_ZERO_ERROR) + * printf("areConfusable: %d (status: %s)\n", result, u_errorName(status)); + * uspoof_close(sc); + * \endcode + * + * <p> + * The call to {@link uspoof_open} creates a <code>USpoofChecker</code> object; the call to {@link uspoof_setChecks} + * enables confusable checking and disables all other checks; the call to {@link uspoof_areConfusable} performs the + * confusability test; and the following line extracts the result out of the return value. For best performance, + * the instance should be created once (e.g., upon application startup), and the efficient + * {@link uspoof_areConfusable} method can be used at runtime. + * + * <p> + * The type {@link LocalUSpoofCheckerPointer} is exposed for C++ programmers. It will automatically call + * {@link uspoof_close} when the object goes out of scope: + * + * \code{.cpp} + * UErrorCode status = U_ZERO_ERROR; + * LocalUSpoofCheckerPointer sc(uspoof_open(&status)); + * uspoof_setChecks(sc.getAlias(), USPOOF_CONFUSABLE, &status); + * // ... + * \endcode + * + * UTS 39 defines two strings to be <em>confusable</em> if they map to the same <em>skeleton string</em>. A skeleton can + * be thought of as a "hash code". {@link uspoof_getSkeleton} computes the skeleton for a particular string, so + * the following snippet is equivalent to the example above: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * UChar* str1 = (UChar*) u"Harvest"; + * UChar* str2 = (UChar*) u"\u0397arvest"; // with U+0397 GREEK CAPITAL LETTER ETA + * + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setChecks(sc, USPOOF_CONFUSABLE, &status); + * + * // Get skeleton 1 + * int32_t skel1Len = uspoof_getSkeleton(sc, 0, str1, -1, NULL, 0, &status); + * UChar* skel1 = (UChar*) malloc(++skel1Len * sizeof(UChar)); + * status = U_ZERO_ERROR; + * uspoof_getSkeleton(sc, 0, str1, -1, skel1, skel1Len, &status); + * + * // Get skeleton 2 + * int32_t skel2Len = uspoof_getSkeleton(sc, 0, str2, -1, NULL, 0, &status); + * UChar* skel2 = (UChar*) malloc(++skel2Len * sizeof(UChar)); + * status = U_ZERO_ERROR; + * uspoof_getSkeleton(sc, 0, str2, -1, skel2, skel2Len, &status); + * + * // Are the skeletons the same? + * UBool result = u_strcmp(skel1, skel2) == 0; + * // areConfusable: 1 (status: U_ZERO_ERROR) + * printf("areConfusable: %d (status: %s)\n", result, u_errorName(status)); + * uspoof_close(sc); + * free(skel1); + * free(skel2); + * \endcode + * + * If you need to check if a string is confusable with any string in a dictionary of many strings, rather than calling + * {@link uspoof_areConfusable} many times in a loop, {@link uspoof_getSkeleton} can be used instead, as shown below: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * #define DICTIONARY_LENGTH 2 + * UChar* dictionary[DICTIONARY_LENGTH] = { (UChar*) u"lorem", (UChar*) u"ipsum" }; + * UChar* skeletons[DICTIONARY_LENGTH]; + * UChar* str = (UChar*) u"1orern"; + * + * // Setup: + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setChecks(sc, USPOOF_CONFUSABLE, &status); + * for (size_t i=0; i<DICTIONARY_LENGTH; i++) { + * UChar* word = dictionary[i]; + * int32_t len = uspoof_getSkeleton(sc, 0, word, -1, NULL, 0, &status); + * skeletons[i] = (UChar*) malloc(++len * sizeof(UChar)); + * status = U_ZERO_ERROR; + * uspoof_getSkeleton(sc, 0, word, -1, skeletons[i], len, &status); + * } + * + * // Live Check: + * { + * int32_t len = uspoof_getSkeleton(sc, 0, str, -1, NULL, 0, &status); + * UChar* skel = (UChar*) malloc(++len * sizeof(UChar)); + * status = U_ZERO_ERROR; + * uspoof_getSkeleton(sc, 0, str, -1, skel, len, &status); + * UBool result = false; + * for (size_t i=0; i<DICTIONARY_LENGTH; i++) { + * result = u_strcmp(skel, skeletons[i]) == 0; + * if (result == true) { break; } + * } + * // Has confusable in dictionary: 1 (status: U_ZERO_ERROR) + * printf("Has confusable in dictionary: %d (status: %s)\n", result, u_errorName(status)); + * free(skel); + * } + * + * for (size_t i=0; i<DICTIONARY_LENGTH; i++) { + * free(skeletons[i]); + * } + * uspoof_close(sc); + * \endcode + * + * <b>Note:</b> Since the Unicode confusables mapping table is frequently updated, confusable skeletons are <em>not</em> + * guaranteed to be the same between ICU releases. We therefore recommend that you always compute confusable skeletons + * at runtime and do not rely on creating a permanent, or difficult to update, database of skeletons. + * + * <h2>Spoof Detection</h2> + * + * The following snippet shows a minimal example of using <code>USpoofChecker</code> to perform spoof detection on a + * string: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * UChar* str = (UChar*) u"p\u0430ypal"; // with U+0430 CYRILLIC SMALL LETTER A + * + * // Get the default set of allowable characters: + * USet* allowed = uset_openEmpty(); + * uset_addAll(allowed, uspoof_getRecommendedSet(&status)); + * uset_addAll(allowed, uspoof_getInclusionSet(&status)); + * + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setAllowedChars(sc, allowed, &status); + * uspoof_setRestrictionLevel(sc, USPOOF_MODERATELY_RESTRICTIVE); + * + * int32_t bitmask = uspoof_check(sc, str, -1, NULL, &status); + * UBool result = bitmask != 0; + * // fails checks: 1 (status: U_ZERO_ERROR) + * printf("fails checks: %d (status: %s)\n", result, u_errorName(status)); + * uspoof_close(sc); + * uset_close(allowed); + * \endcode + * + * As in the case for confusability checking, it is good practice to create one <code>USpoofChecker</code> instance at + * startup, and call the cheaper {@link uspoof_check} online. We specify the set of + * allowed characters to be those with type RECOMMENDED or INCLUSION, according to the recommendation in UTS 39. + * + * In addition to {@link uspoof_check}, the function {@link uspoof_checkUTF8} is exposed for UTF8-encoded char* strings, + * and {@link uspoof_checkUnicodeString} is exposed for C++ programmers. + * + * If the {@link USPOOF_AUX_INFO} check is enabled, a limited amount of information on why a string failed the checks + * is available in the returned bitmask. For complete information, use the {@link uspoof_check2} class of functions + * with a {@link USpoofCheckResult} parameter: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * UChar* str = (UChar*) u"p\u0430ypal"; // with U+0430 CYRILLIC SMALL LETTER A + * + * // Get the default set of allowable characters: + * USet* allowed = uset_openEmpty(); + * uset_addAll(allowed, uspoof_getRecommendedSet(&status)); + * uset_addAll(allowed, uspoof_getInclusionSet(&status)); + * + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setAllowedChars(sc, allowed, &status); + * uspoof_setRestrictionLevel(sc, USPOOF_MODERATELY_RESTRICTIVE); + * + * USpoofCheckResult* checkResult = uspoof_openCheckResult(&status); + * int32_t bitmask = uspoof_check2(sc, str, -1, checkResult, &status); + * + * int32_t failures1 = bitmask; + * int32_t failures2 = uspoof_getCheckResultChecks(checkResult, &status); + * assert(failures1 == failures2); + * // checks that failed: 0x00000010 (status: U_ZERO_ERROR) + * printf("checks that failed: %#010x (status: %s)\n", failures1, u_errorName(status)); + * + * // Cleanup: + * uspoof_close(sc); + * uset_close(allowed); + * uspoof_closeCheckResult(checkResult); + * \endcode + * + * C++ users can take advantage of a few syntactical conveniences. The following snippet is functionally + * equivalent to the one above: + * + * \code{.cpp} + * UErrorCode status = U_ZERO_ERROR; + * UnicodeString str((UChar*) u"p\u0430ypal"); // with U+0430 CYRILLIC SMALL LETTER A + * + * // Get the default set of allowable characters: + * UnicodeSet allowed; + * allowed.addAll(*uspoof_getRecommendedUnicodeSet(&status)); + * allowed.addAll(*uspoof_getInclusionUnicodeSet(&status)); + * + * LocalUSpoofCheckerPointer sc(uspoof_open(&status)); + * uspoof_setAllowedChars(sc.getAlias(), allowed.toUSet(), &status); + * uspoof_setRestrictionLevel(sc.getAlias(), USPOOF_MODERATELY_RESTRICTIVE); + * + * LocalUSpoofCheckResultPointer checkResult(uspoof_openCheckResult(&status)); + * int32_t bitmask = uspoof_check2UnicodeString(sc.getAlias(), str, checkResult.getAlias(), &status); + * + * int32_t failures1 = bitmask; + * int32_t failures2 = uspoof_getCheckResultChecks(checkResult.getAlias(), &status); + * assert(failures1 == failures2); + * // checks that failed: 0x00000010 (status: U_ZERO_ERROR) + * printf("checks that failed: %#010x (status: %s)\n", failures1, u_errorName(status)); + * + * // Explicit cleanup not necessary. + * \endcode + * + * The return value is a bitmask of the checks that failed. In this case, there was one check that failed: + * {@link USPOOF_RESTRICTION_LEVEL}, corresponding to the fifth bit (16). The possible checks are: + * + * <ul> + * <li><code>RESTRICTION_LEVEL</code>: flags strings that violate the + * <a href="http://unicode.org/reports/tr39/#Restriction_Level_Detection">Restriction Level</a> test as specified in UTS + * 39; in most cases, this means flagging strings that contain characters from multiple different scripts.</li> + * <li><code>INVISIBLE</code>: flags strings that contain invisible characters, such as zero-width spaces, or character + * sequences that are likely not to display, such as multiple occurrences of the same non-spacing mark.</li> + * <li><code>CHAR_LIMIT</code>: flags strings that contain characters outside of a specified set of acceptable + * characters. See {@link uspoof_setAllowedChars} and {@link uspoof_setAllowedLocales}.</li> + * <li><code>MIXED_NUMBERS</code>: flags strings that contain digits from multiple different numbering systems.</li> + * </ul> + * + * <p> + * These checks can be enabled independently of each other. For example, if you were interested in checking for only the + * INVISIBLE and MIXED_NUMBERS conditions, you could do: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * UChar* str = (UChar*) u"8\u09EA"; // 8 mixed with U+09EA BENGALI DIGIT FOUR + * + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setChecks(sc, USPOOF_INVISIBLE | USPOOF_MIXED_NUMBERS, &status); + * + * int32_t bitmask = uspoof_check2(sc, str, -1, NULL, &status); + * UBool result = bitmask != 0; + * // fails checks: 1 (status: U_ZERO_ERROR) + * printf("fails checks: %d (status: %s)\n", result, u_errorName(status)); + * uspoof_close(sc); + * \endcode + * + * Here is an example in C++ showing how to compute the restriction level of a string: + * + * \code{.cpp} + * UErrorCode status = U_ZERO_ERROR; + * UnicodeString str((UChar*) u"p\u0430ypal"); // with U+0430 CYRILLIC SMALL LETTER A + * + * // Get the default set of allowable characters: + * UnicodeSet allowed; + * allowed.addAll(*uspoof_getRecommendedUnicodeSet(&status)); + * allowed.addAll(*uspoof_getInclusionUnicodeSet(&status)); + * + * LocalUSpoofCheckerPointer sc(uspoof_open(&status)); + * uspoof_setAllowedChars(sc.getAlias(), allowed.toUSet(), &status); + * uspoof_setRestrictionLevel(sc.getAlias(), USPOOF_MODERATELY_RESTRICTIVE); + * uspoof_setChecks(sc.getAlias(), USPOOF_RESTRICTION_LEVEL | USPOOF_AUX_INFO, &status); + * + * LocalUSpoofCheckResultPointer checkResult(uspoof_openCheckResult(&status)); + * int32_t bitmask = uspoof_check2UnicodeString(sc.getAlias(), str, checkResult.getAlias(), &status); + * + * URestrictionLevel restrictionLevel = uspoof_getCheckResultRestrictionLevel(checkResult.getAlias(), &status); + * // Since USPOOF_AUX_INFO was enabled, the restriction level is also available in the upper bits of the bitmask: + * assert((restrictionLevel & bitmask) == restrictionLevel); + * // Restriction level: 0x50000000 (status: U_ZERO_ERROR) + * printf("Restriction level: %#010x (status: %s)\n", restrictionLevel, u_errorName(status)); + * \endcode + * + * The code '0x50000000' corresponds to the restriction level USPOOF_MINIMALLY_RESTRICTIVE. Since + * USPOOF_MINIMALLY_RESTRICTIVE is weaker than USPOOF_MODERATELY_RESTRICTIVE, the string fails the check. + * + * <b>Note:</b> The Restriction Level is the most powerful of the checks. The full logic is documented in + * <a href="http://unicode.org/reports/tr39/#Restriction_Level_Detection">UTS 39</a>, but the basic idea is that strings + * are restricted to contain characters from only a single script, <em>except</em> that most scripts are allowed to have + * Latin characters interspersed. Although the default restriction level is <code>HIGHLY_RESTRICTIVE</code>, it is + * recommended that users set their restriction level to <code>MODERATELY_RESTRICTIVE</code>, which allows Latin mixed + * with all other scripts except Cyrillic, Greek, and Cherokee, with which it is often confusable. For more details on + * the levels, see UTS 39 or {@link URestrictionLevel}. The Restriction Level test is aware of the set of + * allowed characters set in {@link uspoof_setAllowedChars}. Note that characters which have script code + * COMMON or INHERITED, such as numbers and punctuation, are ignored when computing whether a string has multiple + * scripts. + * + * <h2>Additional Information</h2> + * + * A <code>USpoofChecker</code> instance may be used repeatedly to perform checks on any number of identifiers. + * + * <b>Thread Safety:</b> The test functions for checking a single identifier, or for testing whether + * two identifiers are possible confusable, are thread safe. They may called concurrently, from multiple threads, + * using the same USpoofChecker instance. + * + * More generally, the standard ICU thread safety rules apply: functions that take a const USpoofChecker parameter are + * thread safe. Those that take a non-const USpoofChecker are not thread safe.. + * + * @stable ICU 4.6 + */ + +U_CDECL_BEGIN + +struct USpoofChecker; +/** + * @stable ICU 4.2 + */ +typedef struct USpoofChecker USpoofChecker; /**< typedef for C of USpoofChecker */ + +struct USpoofCheckResult; +/** + * @see uspoof_openCheckResult + * @stable ICU 58 + */ +typedef struct USpoofCheckResult USpoofCheckResult; + +/** + * Enum for the kinds of checks that USpoofChecker can perform. + * These enum values are used both to select the set of checks that + * will be performed, and to report results from the check function. + * + * @stable ICU 4.2 + */ +typedef enum USpoofChecks { + /** + * When performing the two-string {@link uspoof_areConfusable} test, this flag in the return value indicates + * that the two strings are visually confusable and that they are from the same script, according to UTS 39 section + * 4. + * + * @see uspoof_areConfusable + * @stable ICU 4.2 + */ + USPOOF_SINGLE_SCRIPT_CONFUSABLE = 1, + + /** + * When performing the two-string {@link uspoof_areConfusable} test, this flag in the return value indicates + * that the two strings are visually confusable and that they are <b>not</b> from the same script, according to UTS + * 39 section 4. + * + * @see uspoof_areConfusable + * @stable ICU 4.2 + */ + USPOOF_MIXED_SCRIPT_CONFUSABLE = 2, + + /** + * When performing the two-string {@link uspoof_areConfusable} test, this flag in the return value indicates + * that the two strings are visually confusable and that they are not from the same script but both of them are + * single-script strings, according to UTS 39 section 4. + * + * @see uspoof_areConfusable + * @stable ICU 4.2 + */ + USPOOF_WHOLE_SCRIPT_CONFUSABLE = 4, + + /** + * Enable this flag in {@link uspoof_setChecks} to turn on all types of confusables. You may set + * the checks to some subset of SINGLE_SCRIPT_CONFUSABLE, MIXED_SCRIPT_CONFUSABLE, or WHOLE_SCRIPT_CONFUSABLE to + * make {@link uspoof_areConfusable} return only those types of confusables. + * + * @see uspoof_areConfusable + * @see uspoof_getSkeleton + * @stable ICU 58 + */ + USPOOF_CONFUSABLE = USPOOF_SINGLE_SCRIPT_CONFUSABLE | USPOOF_MIXED_SCRIPT_CONFUSABLE | USPOOF_WHOLE_SCRIPT_CONFUSABLE, + +#ifndef U_HIDE_DEPRECATED_API + /** + * This flag is deprecated and no longer affects the behavior of SpoofChecker. + * + * @deprecated ICU 58 Any case confusable mappings were removed from UTS 39; the corresponding ICU API was deprecated. + */ + USPOOF_ANY_CASE = 8, +#endif /* U_HIDE_DEPRECATED_API */ + + /** + * Check that an identifier is no looser than the specified RestrictionLevel. + * The default if {@link uspoof_setRestrictionLevel} is not called is HIGHLY_RESTRICTIVE. + * + * If USPOOF_AUX_INFO is enabled the actual restriction level of the + * identifier being tested will also be returned by uspoof_check(). + * + * @see URestrictionLevel + * @see uspoof_setRestrictionLevel + * @see USPOOF_AUX_INFO + * + * @stable ICU 51 + */ + USPOOF_RESTRICTION_LEVEL = 16, + +#ifndef U_HIDE_DEPRECATED_API + /** Check that an identifier contains only characters from a + * single script (plus chars from the common and inherited scripts.) + * Applies to checks of a single identifier check only. + * @deprecated ICU 51 Use RESTRICTION_LEVEL instead. + */ + USPOOF_SINGLE_SCRIPT = USPOOF_RESTRICTION_LEVEL, +#endif /* U_HIDE_DEPRECATED_API */ + + /** Check an identifier for the presence of invisible characters, + * such as zero-width spaces, or character sequences that are + * likely not to display, such as multiple occurrences of the same + * non-spacing mark. This check does not test the input string as a whole + * for conformance to any particular syntax for identifiers. + */ + USPOOF_INVISIBLE = 32, + + /** Check that an identifier contains only characters from a specified set + * of acceptable characters. See {@link uspoof_setAllowedChars} and + * {@link uspoof_setAllowedLocales}. Note that a string that fails this check + * will also fail the {@link USPOOF_RESTRICTION_LEVEL} check. + */ + USPOOF_CHAR_LIMIT = 64, + + /** + * Check that an identifier does not mix numbers from different numbering systems. + * For more information, see UTS 39 section 5.3. + * + * @stable ICU 51 + */ + USPOOF_MIXED_NUMBERS = 128, + + /** + * Check that an identifier does not have a combining character following a character in which that + * combining character would be hidden; for example 'i' followed by a U+0307 combining dot. + * + * More specifically, the following characters are forbidden from preceding a U+0307: + * <ul> + * <li>Those with the Soft_Dotted Unicode property (which includes 'i' and 'j')</li> + * <li>Latin lowercase letter 'l'</li> + * <li>Dotless 'i' and 'j' ('ı' and 'ȷ', U+0131 and U+0237)</li> + * <li>Any character whose confusable prototype ends with such a character + * (Soft_Dotted, 'l', 'ı', or 'ȷ')</li> + * </ul> + * In addition, combining characters are allowed between the above characters and U+0307 except those + * with combining class 0 or combining class "Above" (230, same class as U+0307). + * + * This list and the number of combing characters considered by this check may grow over time. + * + * @stable ICU 62 + */ + USPOOF_HIDDEN_OVERLAY = 256, + + /** + * Enable all spoof checks. + * + * @stable ICU 4.6 + */ + USPOOF_ALL_CHECKS = 0xFFFF, + + /** + * Enable the return of auxiliary (non-error) information in the + * upper bits of the check results value. + * + * If this "check" is not enabled, the results of {@link uspoof_check} will be + * zero when an identifier passes all of the enabled checks. + * + * If this "check" is enabled, (uspoof_check() & {@link USPOOF_ALL_CHECKS}) will + * be zero when an identifier passes all checks. + * + * @stable ICU 51 + */ + USPOOF_AUX_INFO = 0x40000000 + + } USpoofChecks; + + + /** + * Constants from UAX #39 for use in {@link uspoof_setRestrictionLevel}, and + * for returned identifier restriction levels in check results. + * + * @stable ICU 51 + * + * @see uspoof_setRestrictionLevel + * @see uspoof_check + */ + typedef enum URestrictionLevel { + /** + * All characters in the string are in the identifier profile and all characters in the string are in the + * ASCII range. + * + * @stable ICU 51 + */ + USPOOF_ASCII = 0x10000000, + /** + * The string classifies as ASCII-Only, or all characters in the string are in the identifier profile and + * the string is single-script, according to the definition in UTS 39 section 5.1. + * + * @stable ICU 53 + */ + USPOOF_SINGLE_SCRIPT_RESTRICTIVE = 0x20000000, + /** + * The string classifies as Single Script, or all characters in the string are in the identifier profile and + * the string is covered by any of the following sets of scripts, according to the definition in UTS 39 + * section 5.1: + * <ul> + * <li>Latin + Han + Bopomofo (or equivalently: Latn + Hanb)</li> + * <li>Latin + Han + Hiragana + Katakana (or equivalently: Latn + Jpan)</li> + * <li>Latin + Han + Hangul (or equivalently: Latn +Kore)</li> + * </ul> + * This is the default restriction in ICU. + * + * @stable ICU 51 + */ + USPOOF_HIGHLY_RESTRICTIVE = 0x30000000, + /** + * The string classifies as Highly Restrictive, or all characters in the string are in the identifier profile + * and the string is covered by Latin and any one other Recommended or Aspirational script, except Cyrillic, + * Greek, and Cherokee. + * + * @stable ICU 51 + */ + USPOOF_MODERATELY_RESTRICTIVE = 0x40000000, + /** + * All characters in the string are in the identifier profile. Allow arbitrary mixtures of scripts. + * + * @stable ICU 51 + */ + USPOOF_MINIMALLY_RESTRICTIVE = 0x50000000, + /** + * Any valid identifiers, including characters outside of the Identifier Profile. + * + * @stable ICU 51 + */ + USPOOF_UNRESTRICTIVE = 0x60000000, + /** + * Mask for selecting the Restriction Level bits from the return value of {@link uspoof_check}. + * + * @stable ICU 53 + */ + USPOOF_RESTRICTION_LEVEL_MASK = 0x7F000000, +#ifndef U_HIDE_INTERNAL_API + /** + * An undefined restriction level. + * @internal + */ + USPOOF_UNDEFINED_RESTRICTIVE = -1 +#endif /* U_HIDE_INTERNAL_API */ + } URestrictionLevel; + +/** + * Create a Unicode Spoof Checker, configured to perform all + * checks except for USPOOF_LOCALE_LIMIT and USPOOF_CHAR_LIMIT. + * Note that additional checks may be added in the future, + * resulting in the changes to the default checking behavior. + * + * @param status The error code, set if this function encounters a problem. + * @return the newly created Spoof Checker + * @stable ICU 4.2 + */ +U_CAPI USpoofChecker * U_EXPORT2 +uspoof_open(UErrorCode *status); + + +/** + * Open a Spoof checker from its serialized form, stored in 32-bit-aligned memory. + * Inverse of uspoof_serialize(). + * The memory containing the serialized data must remain valid and unchanged + * as long as the spoof checker, or any cloned copies of the spoof checker, + * are in use. Ownership of the memory remains with the caller. + * The spoof checker (and any clones) must be closed prior to deleting the + * serialized data. + * + * @param data a pointer to 32-bit-aligned memory containing the serialized form of spoof data + * @param length the number of bytes available at data; + * can be more than necessary + * @param pActualLength receives the actual number of bytes at data taken up by the data; + * can be NULL + * @param pErrorCode ICU error code + * @return the spoof checker. + * + * @see uspoof_open + * @see uspoof_serialize + * @stable ICU 4.2 + */ +U_CAPI USpoofChecker * U_EXPORT2 +uspoof_openFromSerialized(const void *data, int32_t length, int32_t *pActualLength, + UErrorCode *pErrorCode); + +/** + * Open a Spoof Checker from the source form of the spoof data. + * The input corresponds to the Unicode data file confusables.txt + * as described in Unicode UAX #39. The syntax of the source data + * is as described in UAX #39 for this file, and the content of + * this file is acceptable input. + * + * The character encoding of the (char *) input text is UTF-8. + * + * @param confusables a pointer to the confusable characters definitions, + * as found in file confusables.txt from unicode.org. + * @param confusablesLen The length of the confusables text, or -1 if the + * input string is zero terminated. + * @param confusablesWholeScript + * Deprecated in ICU 58. No longer used. + * @param confusablesWholeScriptLen + * Deprecated in ICU 58. No longer used. + * @param errType In the event of an error in the input, indicates + * which of the input files contains the error. + * The value is one of USPOOF_SINGLE_SCRIPT_CONFUSABLE or + * USPOOF_WHOLE_SCRIPT_CONFUSABLE, or + * zero if no errors are found. + * @param pe In the event of an error in the input, receives the position + * in the input text (line, offset) of the error. + * @param status an in/out ICU UErrorCode. Among the possible errors is + * U_PARSE_ERROR, which is used to report syntax errors + * in the input. + * @return A spoof checker that uses the rules from the input files. + * @stable ICU 4.2 + */ +U_CAPI USpoofChecker * U_EXPORT2 +uspoof_openFromSource(const char *confusables, int32_t confusablesLen, + const char *confusablesWholeScript, int32_t confusablesWholeScriptLen, + int32_t *errType, UParseError *pe, UErrorCode *status); + + +/** + * Close a Spoof Checker, freeing any memory that was being held by + * its implementation. + * @stable ICU 4.2 + */ +U_CAPI void U_EXPORT2 +uspoof_close(USpoofChecker *sc); + +/** + * Clone a Spoof Checker. The clone will be set to perform the same checks + * as the original source. + * + * @param sc The source USpoofChecker + * @param status The error code, set if this function encounters a problem. + * @return + * @stable ICU 4.2 + */ +U_CAPI USpoofChecker * U_EXPORT2 +uspoof_clone(const USpoofChecker *sc, UErrorCode *status); + + +/** + * Specify the bitmask of checks that will be performed by {@link uspoof_check}. Calling this method + * overwrites any checks that may have already been enabled. By default, all checks are enabled. + * + * To enable specific checks and disable all others, + * OR together only the bit constants for the desired checks. + * For example, to fail strings containing characters outside of + * the set specified by {@link uspoof_setAllowedChars} and + * also strings that contain digits from mixed numbering systems: + * + * <pre> + * {@code + * uspoof_setChecks(USPOOF_CHAR_LIMIT | USPOOF_MIXED_NUMBERS); + * } + * </pre> + * + * To disable specific checks and enable all others, + * start with ALL_CHECKS and "AND away" the not-desired checks. + * For example, if you are not planning to use the {@link uspoof_areConfusable} functionality, + * it is good practice to disable the CONFUSABLE check: + * + * <pre> + * {@code + * uspoof_setChecks(USPOOF_ALL_CHECKS & ~USPOOF_CONFUSABLE); + * } + * </pre> + * + * Note that methods such as {@link uspoof_setAllowedChars}, {@link uspoof_setAllowedLocales}, and + * {@link uspoof_setRestrictionLevel} will enable certain checks when called. Those methods will OR the check they + * enable onto the existing bitmask specified by this method. For more details, see the documentation of those + * methods. + * + * @param sc The USpoofChecker + * @param checks The set of checks that this spoof checker will perform. + * The value is a bit set, obtained by OR-ing together + * values from enum USpoofChecks. + * @param status The error code, set if this function encounters a problem. + * @stable ICU 4.2 + * + */ +U_CAPI void U_EXPORT2 +uspoof_setChecks(USpoofChecker *sc, int32_t checks, UErrorCode *status); + +/** + * Get the set of checks that this Spoof Checker has been configured to perform. + * + * @param sc The USpoofChecker + * @param status The error code, set if this function encounters a problem. + * @return The set of checks that this spoof checker will perform. + * The value is a bit set, obtained by OR-ing together + * values from enum USpoofChecks. + * @stable ICU 4.2 + * + */ +U_CAPI int32_t U_EXPORT2 +uspoof_getChecks(const USpoofChecker *sc, UErrorCode *status); + +/** + * Set the loosest restriction level allowed for strings. The default if this is not called is + * {@link USPOOF_HIGHLY_RESTRICTIVE}. Calling this method enables the {@link USPOOF_RESTRICTION_LEVEL} and + * {@link USPOOF_MIXED_NUMBERS} checks, corresponding to Sections 5.1 and 5.2 of UTS 39. To customize which checks are + * to be performed by {@link uspoof_check}, see {@link uspoof_setChecks}. + * + * @param sc The USpoofChecker + * @param restrictionLevel The loosest restriction level allowed. + * @see URestrictionLevel + * @stable ICU 51 + */ +U_CAPI void U_EXPORT2 +uspoof_setRestrictionLevel(USpoofChecker *sc, URestrictionLevel restrictionLevel); + + +/** + * Get the Restriction Level that will be tested if the checks include {@link USPOOF_RESTRICTION_LEVEL}. + * + * @return The restriction level + * @see URestrictionLevel + * @stable ICU 51 + */ +U_CAPI URestrictionLevel U_EXPORT2 +uspoof_getRestrictionLevel(const USpoofChecker *sc); + +/** + * Limit characters that are acceptable in identifiers being checked to those + * normally used with the languages associated with the specified locales. + * Any previously specified list of locales is replaced by the new settings. + * + * A set of languages is determined from the locale(s), and + * from those a set of acceptable Unicode scripts is determined. + * Characters from this set of scripts, along with characters from + * the "common" and "inherited" Unicode Script categories + * will be permitted. + * + * Supplying an empty string removes all restrictions; + * characters from any script will be allowed. + * + * The {@link USPOOF_CHAR_LIMIT} test is automatically enabled for this + * USpoofChecker when calling this function with a non-empty list + * of locales. + * + * The Unicode Set of characters that will be allowed is accessible + * via the uspoof_getAllowedChars() function. uspoof_setAllowedLocales() + * will <i>replace</i> any previously applied set of allowed characters. + * + * Adjustments, such as additions or deletions of certain classes of characters, + * can be made to the result of uspoof_setAllowedLocales() by + * fetching the resulting set with uspoof_getAllowedChars(), + * manipulating it with the Unicode Set API, then resetting the + * spoof detectors limits with uspoof_setAllowedChars(). + * + * @param sc The USpoofChecker + * @param localesList A list list of locales, from which the language + * and associated script are extracted. The locales + * are comma-separated if there is more than one. + * White space may not appear within an individual locale, + * but is ignored otherwise. + * The locales are syntactically like those from the + * HTTP Accept-Language header. + * If the localesList is empty, no restrictions will be placed on + * the allowed characters. + * + * @param status The error code, set if this function encounters a problem. + * @stable ICU 4.2 + */ +U_CAPI void U_EXPORT2 +uspoof_setAllowedLocales(USpoofChecker *sc, const char *localesList, UErrorCode *status); + +/** + * Get a list of locales for the scripts that are acceptable in strings + * to be checked. If no limitations on scripts have been specified, + * an empty string will be returned. + * + * uspoof_setAllowedChars() will reset the list of allowed to be empty. + * + * The format of the returned list is the same as that supplied to + * uspoof_setAllowedLocales(), but returned list may not be identical + * to the originally specified string; the string may be reformatted, + * and information other than languages from + * the originally specified locales may be omitted. + * + * @param sc The USpoofChecker + * @param status The error code, set if this function encounters a problem. + * @return A string containing a list of locales corresponding + * to the acceptable scripts, formatted like an + * HTTP Accept Language value. + * + * @stable ICU 4.2 + */ +U_CAPI const char * U_EXPORT2 +uspoof_getAllowedLocales(USpoofChecker *sc, UErrorCode *status); + + +/** + * Limit the acceptable characters to those specified by a Unicode Set. + * Any previously specified character limit is + * is replaced by the new settings. This includes limits on + * characters that were set with the uspoof_setAllowedLocales() function. + * + * The USPOOF_CHAR_LIMIT test is automatically enabled for this + * USpoofChecker by this function. + * + * @param sc The USpoofChecker + * @param chars A Unicode Set containing the list of + * characters that are permitted. Ownership of the set + * remains with the caller. The incoming set is cloned by + * this function, so there are no restrictions on modifying + * or deleting the USet after calling this function. + * @param status The error code, set if this function encounters a problem. + * @stable ICU 4.2 + */ +U_CAPI void U_EXPORT2 +uspoof_setAllowedChars(USpoofChecker *sc, const USet *chars, UErrorCode *status); + + +/** + * Get a USet for the characters permitted in an identifier. + * This corresponds to the limits imposed by the Set Allowed Characters + * functions. Limitations imposed by other checks will not be + * reflected in the set returned by this function. + * + * The returned set will be frozen, meaning that it cannot be modified + * by the caller. + * + * Ownership of the returned set remains with the Spoof Detector. The + * returned set will become invalid if the spoof detector is closed, + * or if a new set of allowed characters is specified. + * + * + * @param sc The USpoofChecker + * @param status The error code, set if this function encounters a problem. + * @return A USet containing the characters that are permitted by + * the USPOOF_CHAR_LIMIT test. + * @stable ICU 4.2 + */ +U_CAPI const USet * U_EXPORT2 +uspoof_getAllowedChars(const USpoofChecker *sc, UErrorCode *status); + + +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * \note + * Consider using the newer API, {@link uspoof_check2}, instead. + * The newer API exposes additional information from the check procedure + * and is otherwise identical to this method. + * + * @param sc The USpoofChecker + * @param id The identifier to be checked for possible security issues, + * in UTF-16 format. + * @param length the length of the string to be checked, expressed in + * 16 bit UTF-16 code units, or -1 if the string is + * zero terminated. + * @param position Deprecated in ICU 51. Always returns zero. + * Originally, an out parameter for the index of the first + * string position that failed a check. + * This parameter may be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. + * @see uspoof_check2 + * @stable ICU 4.2 + */ +U_CAPI int32_t U_EXPORT2 +uspoof_check(const USpoofChecker *sc, + const UChar *id, int32_t length, + int32_t *position, + UErrorCode *status); + + +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * \note + * Consider using the newer API, {@link uspoof_check2UTF8}, instead. + * The newer API exposes additional information from the check procedure + * and is otherwise identical to this method. + * + * @param sc The USpoofChecker + * @param id A identifier to be checked for possible security issues, in UTF8 format. + * @param length the length of the string to be checked, or -1 if the string is + * zero terminated. + * @param position Deprecated in ICU 51. Always returns zero. + * Originally, an out parameter for the index of the first + * string position that failed a check. + * This parameter may be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * If the input contains invalid UTF-8 sequences, + * a status of U_INVALID_CHAR_FOUND will be returned. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. + * @see uspoof_check2UTF8 + * @stable ICU 4.2 + */ +U_CAPI int32_t U_EXPORT2 +uspoof_checkUTF8(const USpoofChecker *sc, + const char *id, int32_t length, + int32_t *position, + UErrorCode *status); + + +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * @param sc The USpoofChecker + * @param id The identifier to be checked for possible security issues, + * in UTF-16 format. + * @param length the length of the string to be checked, or -1 if the string is + * zero terminated. + * @param checkResult An instance of USpoofCheckResult to be filled with + * details about the identifier. Can be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. Any information in this bitmask will be + * consistent with the information saved in the optional + * checkResult parameter. + * @see uspoof_openCheckResult + * @see uspoof_check2UTF8 + * @see uspoof_check2UnicodeString + * @stable ICU 58 + */ +U_CAPI int32_t U_EXPORT2 +uspoof_check2(const USpoofChecker *sc, + const UChar* id, int32_t length, + USpoofCheckResult* checkResult, + UErrorCode *status); + +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * This version of {@link uspoof_check} accepts a USpoofCheckResult, which + * returns additional information about the identifier. For more + * information, see {@link uspoof_openCheckResult}. + * + * @param sc The USpoofChecker + * @param id A identifier to be checked for possible security issues, in UTF8 format. + * @param length the length of the string to be checked, or -1 if the string is + * zero terminated. + * @param checkResult An instance of USpoofCheckResult to be filled with + * details about the identifier. Can be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. Any information in this bitmask will be + * consistent with the information saved in the optional + * checkResult parameter. + * @see uspoof_openCheckResult + * @see uspoof_check2 + * @see uspoof_check2UnicodeString + * @stable ICU 58 + */ +U_CAPI int32_t U_EXPORT2 +uspoof_check2UTF8(const USpoofChecker *sc, + const char *id, int32_t length, + USpoofCheckResult* checkResult, + UErrorCode *status); + +/** + * Create a USpoofCheckResult, used by the {@link uspoof_check2} class of functions to return + * information about the identifier. Information includes: + * <ul> + * <li>A bitmask of the checks that failed</li> + * <li>The identifier's restriction level (UTS 39 section 5.2)</li> + * <li>The set of numerics in the string (UTS 39 section 5.3)</li> + * </ul> + * The data held in a USpoofCheckResult is cleared whenever it is passed into a new call + * of {@link uspoof_check2}. + * + * @param status The error code, set if this function encounters a problem. + * @return the newly created USpoofCheckResult + * @see uspoof_check2 + * @see uspoof_check2UTF8 + * @see uspoof_check2UnicodeString + * @stable ICU 58 + */ +U_CAPI USpoofCheckResult* U_EXPORT2 +uspoof_openCheckResult(UErrorCode *status); + +/** + * Close a USpoofCheckResult, freeing any memory that was being held by + * its implementation. + * + * @param checkResult The instance of USpoofCheckResult to close + * @stable ICU 58 + */ +U_CAPI void U_EXPORT2 +uspoof_closeCheckResult(USpoofCheckResult *checkResult); + +/** + * Indicates which of the spoof check(s) have failed. The value is a bitwise OR of the constants for the tests + * in question: USPOOF_RESTRICTION_LEVEL, USPOOF_CHAR_LIMIT, and so on. + * + * @param checkResult The instance of USpoofCheckResult created by {@link uspoof_openCheckResult} + * @param status The error code, set if an error occurred. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. + * @see uspoof_setChecks + * @stable ICU 58 + */ +U_CAPI int32_t U_EXPORT2 +uspoof_getCheckResultChecks(const USpoofCheckResult *checkResult, UErrorCode *status); + +/** + * Gets the restriction level that the text meets, if the USPOOF_RESTRICTION_LEVEL check + * was enabled; otherwise, undefined. + * + * @param checkResult The instance of USpoofCheckResult created by {@link uspoof_openCheckResult} + * @param status The error code, set if an error occurred. + * @return The restriction level contained in the USpoofCheckResult + * @see uspoof_setRestrictionLevel + * @stable ICU 58 + */ +U_CAPI URestrictionLevel U_EXPORT2 +uspoof_getCheckResultRestrictionLevel(const USpoofCheckResult *checkResult, UErrorCode *status); + +/** + * Gets the set of numerics found in the string, if the USPOOF_MIXED_NUMBERS check was enabled; + * otherwise, undefined. The set will contain the zero digit from each decimal number system found + * in the input string. Ownership of the returned USet remains with the USpoofCheckResult. + * The USet will be free'd when {@link uspoof_closeCheckResult} is called. + * + * @param checkResult The instance of USpoofCheckResult created by {@link uspoof_openCheckResult} + * @return The set of numerics contained in the USpoofCheckResult + * @param status The error code, set if an error occurred. + * @stable ICU 58 + */ +U_CAPI const USet* U_EXPORT2 +uspoof_getCheckResultNumerics(const USpoofCheckResult *checkResult, UErrorCode *status); + + +/** + * Check the whether two specified strings are visually confusable. + * + * If the strings are confusable, the return value will be nonzero, as long as + * {@link USPOOF_CONFUSABLE} was enabled in uspoof_setChecks(). + * + * The bits in the return value correspond to flags for each of the classes of + * confusables applicable to the two input strings. According to UTS 39 + * section 4, the possible flags are: + * + * <ul> + * <li>{@link USPOOF_SINGLE_SCRIPT_CONFUSABLE}</li> + * <li>{@link USPOOF_MIXED_SCRIPT_CONFUSABLE}</li> + * <li>{@link USPOOF_WHOLE_SCRIPT_CONFUSABLE}</li> + * </ul> + * + * If one or more of the above flags were not listed in uspoof_setChecks(), this + * function will never report that class of confusable. The check + * {@link USPOOF_CONFUSABLE} enables all three flags. + * + * + * @param sc The USpoofChecker + * @param id1 The first of the two identifiers to be compared for + * confusability. The strings are in UTF-16 format. + * @param length1 the length of the first identifier, expressed in + * 16 bit UTF-16 code units, or -1 if the string is + * nul terminated. + * @param id2 The second of the two identifiers to be compared for + * confusability. The identifiers are in UTF-16 format. + * @param length2 The length of the second identifiers, expressed in + * 16 bit UTF-16 code units, or -1 if the string is + * nul terminated. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Confusability of the identifiers is not reported here, + * but through this function's return value. + * @return An integer value with bit(s) set corresponding to + * the type of confusability found, as defined by + * enum USpoofChecks. Zero is returned if the identifiers + * are not confusable. + * + * @stable ICU 4.2 + */ +U_CAPI int32_t U_EXPORT2 +uspoof_areConfusable(const USpoofChecker *sc, + const UChar *id1, int32_t length1, + const UChar *id2, int32_t length2, + UErrorCode *status); + + + +/** + * A version of {@link uspoof_areConfusable} accepting strings in UTF-8 format. + * + * @param sc The USpoofChecker + * @param id1 The first of the two identifiers to be compared for + * confusability. The strings are in UTF-8 format. + * @param length1 the length of the first identifiers, in bytes, or -1 + * if the string is nul terminated. + * @param id2 The second of the two identifiers to be compared for + * confusability. The strings are in UTF-8 format. + * @param length2 The length of the second string in bytes, or -1 + * if the string is nul terminated. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Confusability of the strings is not reported here, + * but through this function's return value. + * @return An integer value with bit(s) set corresponding to + * the type of confusability found, as defined by + * enum USpoofChecks. Zero is returned if the strings + * are not confusable. + * + * @stable ICU 4.2 + * + * @see uspoof_areConfusable + */ +U_CAPI int32_t U_EXPORT2 +uspoof_areConfusableUTF8(const USpoofChecker *sc, + const char *id1, int32_t length1, + const char *id2, int32_t length2, + UErrorCode *status); + + + + +/** + * Get the "skeleton" for an identifier. + * Skeletons are a transformation of the input identifier; + * Two identifiers are confusable if their skeletons are identical. + * See Unicode UAX #39 for additional information. + * + * Using skeletons directly makes it possible to quickly check + * whether an identifier is confusable with any of some large + * set of existing identifiers, by creating an efficiently + * searchable collection of the skeletons. + * + * @param sc The USpoofChecker + * @param type Deprecated in ICU 58. You may pass any number. + * Originally, controlled which of the Unicode confusable data + * tables to use. + * @param id The input identifier whose skeleton will be computed. + * @param length The length of the input identifier, expressed in 16 bit + * UTF-16 code units, or -1 if the string is zero terminated. + * @param dest The output buffer, to receive the skeleton string. + * @param destCapacity The length of the output buffer, in 16 bit units. + * The destCapacity may be zero, in which case the function will + * return the actual length of the skeleton. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * @return The length of the skeleton string. The returned length + * is always that of the complete skeleton, even when the + * supplied buffer is too small (or of zero length) + * + * @stable ICU 4.2 + * @see uspoof_areConfusable + */ +U_CAPI int32_t U_EXPORT2 +uspoof_getSkeleton(const USpoofChecker *sc, + uint32_t type, + const UChar *id, int32_t length, + UChar *dest, int32_t destCapacity, + UErrorCode *status); + +/** + * Get the "skeleton" for an identifier. + * Skeletons are a transformation of the input identifier; + * Two identifiers are confusable if their skeletons are identical. + * See Unicode UAX #39 for additional information. + * + * Using skeletons directly makes it possible to quickly check + * whether an identifier is confusable with any of some large + * set of existing identifiers, by creating an efficiently + * searchable collection of the skeletons. + * + * @param sc The USpoofChecker + * @param type Deprecated in ICU 58. You may pass any number. + * Originally, controlled which of the Unicode confusable data + * tables to use. + * @param id The UTF-8 format identifier whose skeleton will be computed. + * @param length The length of the input string, in bytes, + * or -1 if the string is zero terminated. + * @param dest The output buffer, to receive the skeleton string. + * @param destCapacity The length of the output buffer, in bytes. + * The destCapacity may be zero, in which case the function will + * return the actual length of the skeleton. + * @param status The error code, set if an error occurred while attempting to + * perform the check. Possible Errors include U_INVALID_CHAR_FOUND + * for invalid UTF-8 sequences, and + * U_BUFFER_OVERFLOW_ERROR if the destination buffer is too small + * to hold the complete skeleton. + * @return The length of the skeleton string, in bytes. The returned length + * is always that of the complete skeleton, even when the + * supplied buffer is too small (or of zero length) + * + * @stable ICU 4.2 + */ +U_CAPI int32_t U_EXPORT2 +uspoof_getSkeletonUTF8(const USpoofChecker *sc, + uint32_t type, + const char *id, int32_t length, + char *dest, int32_t destCapacity, + UErrorCode *status); + +/** + * Get the set of Candidate Characters for Inclusion in Identifiers, as defined + * in http://unicode.org/Public/security/latest/xidmodifications.txt + * and documented in http://www.unicode.org/reports/tr39/, Unicode Security Mechanisms. + * + * The returned set is frozen. Ownership of the set remains with the ICU library; it must not + * be deleted by the caller. + * + * @param status The error code, set if a problem occurs while creating the set. + * + * @stable ICU 51 + */ +U_CAPI const USet * U_EXPORT2 +uspoof_getInclusionSet(UErrorCode *status); + +/** + * Get the set of characters from Recommended Scripts for Inclusion in Identifiers, as defined + * in http://unicode.org/Public/security/latest/xidmodifications.txt + * and documented in http://www.unicode.org/reports/tr39/, Unicode Security Mechanisms. + * + * The returned set is frozen. Ownership of the set remains with the ICU library; it must not + * be deleted by the caller. + * + * @param status The error code, set if a problem occurs while creating the set. + * + * @stable ICU 51 + */ +U_CAPI const USet * U_EXPORT2 +uspoof_getRecommendedSet(UErrorCode *status); + +/** + * Serialize the data for a spoof detector into a chunk of memory. + * The flattened spoof detection tables can later be used to efficiently + * instantiate a new Spoof Detector. + * + * The serialized spoof checker includes only the data compiled from the + * Unicode data tables by uspoof_openFromSource(); it does not include + * include any other state or configuration that may have been set. + * + * @param sc the Spoof Detector whose data is to be serialized. + * @param data a pointer to 32-bit-aligned memory to be filled with the data, + * can be NULL if capacity==0 + * @param capacity the number of bytes available at data, + * or 0 for preflighting + * @param status an in/out ICU UErrorCode; possible errors include: + * - U_BUFFER_OVERFLOW_ERROR if the data storage block is too small for serialization + * - U_ILLEGAL_ARGUMENT_ERROR the data or capacity parameters are bad + * @return the number of bytes written or needed for the spoof data + * + * @see utrie2_openFromSerialized() + * @stable ICU 4.2 + */ +U_CAPI int32_t U_EXPORT2 +uspoof_serialize(USpoofChecker *sc, + void *data, int32_t capacity, + UErrorCode *status); + +U_CDECL_END + +#if U_SHOW_CPLUSPLUS_API + +U_NAMESPACE_BEGIN + +/** + * \class LocalUSpoofCheckerPointer + * "Smart pointer" class, closes a USpoofChecker via uspoof_close(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 4.4 + */ +/** + * \cond + * Note: Doxygen is giving a bogus warning on this U_DEFINE_LOCAL_OPEN_POINTER. + * For now, suppress with a Doxygen cond + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckerPointer, USpoofChecker, uspoof_close); +/** \endcond */ + +/** + * \class LocalUSpoofCheckResultPointer + * "Smart pointer" class, closes a USpoofCheckResult via `uspoof_closeCheckResult()`. + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 58 + */ + +/** + * \cond + * Note: Doxygen is giving a bogus warning on this U_DEFINE_LOCAL_OPEN_POINTER. + * For now, suppress with a Doxygen cond + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckResultPointer, USpoofCheckResult, uspoof_closeCheckResult); +/** \endcond */ + +U_NAMESPACE_END + +/** + * Limit the acceptable characters to those specified by a Unicode Set. + * Any previously specified character limit is + * is replaced by the new settings. This includes limits on + * characters that were set with the uspoof_setAllowedLocales() function. + * + * The USPOOF_CHAR_LIMIT test is automatically enabled for this + * USoofChecker by this function. + * + * @param sc The USpoofChecker + * @param chars A Unicode Set containing the list of + * characters that are permitted. Ownership of the set + * remains with the caller. The incoming set is cloned by + * this function, so there are no restrictions on modifying + * or deleting the UnicodeSet after calling this function. + * @param status The error code, set if this function encounters a problem. + * @stable ICU 4.2 + */ +U_CAPI void U_EXPORT2 +uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const icu::UnicodeSet *chars, UErrorCode *status); + + +/** + * Get a UnicodeSet for the characters permitted in an identifier. + * This corresponds to the limits imposed by the Set Allowed Characters / + * UnicodeSet functions. Limitations imposed by other checks will not be + * reflected in the set returned by this function. + * + * The returned set will be frozen, meaning that it cannot be modified + * by the caller. + * + * Ownership of the returned set remains with the Spoof Detector. The + * returned set will become invalid if the spoof detector is closed, + * or if a new set of allowed characters is specified. + * + * + * @param sc The USpoofChecker + * @param status The error code, set if this function encounters a problem. + * @return A UnicodeSet containing the characters that are permitted by + * the USPOOF_CHAR_LIMIT test. + * @stable ICU 4.2 + */ +U_CAPI const icu::UnicodeSet * U_EXPORT2 +uspoof_getAllowedUnicodeSet(const USpoofChecker *sc, UErrorCode *status); + +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * \note + * Consider using the newer API, {@link uspoof_check2UnicodeString}, instead. + * The newer API exposes additional information from the check procedure + * and is otherwise identical to this method. + * + * @param sc The USpoofChecker + * @param id A identifier to be checked for possible security issues. + * @param position Deprecated in ICU 51. Always returns zero. + * Originally, an out parameter for the index of the first + * string position that failed a check. + * This parameter may be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. + * @see uspoof_check2UnicodeString + * @stable ICU 4.2 + */ +U_CAPI int32_t U_EXPORT2 +uspoof_checkUnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &id, + int32_t *position, + UErrorCode *status); + +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * @param sc The USpoofChecker + * @param id A identifier to be checked for possible security issues. + * @param checkResult An instance of USpoofCheckResult to be filled with + * details about the identifier. Can be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. Any information in this bitmask will be + * consistent with the information saved in the optional + * checkResult parameter. + * @see uspoof_openCheckResult + * @see uspoof_check2 + * @see uspoof_check2UTF8 + * @stable ICU 58 + */ +U_CAPI int32_t U_EXPORT2 +uspoof_check2UnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &id, + USpoofCheckResult* checkResult, + UErrorCode *status); + +/** + * A version of {@link uspoof_areConfusable} accepting UnicodeStrings. + * + * @param sc The USpoofChecker + * @param s1 The first of the two identifiers to be compared for + * confusability. The strings are in UTF-8 format. + * @param s2 The second of the two identifiers to be compared for + * confusability. The strings are in UTF-8 format. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Confusability of the identifiers is not reported here, + * but through this function's return value. + * @return An integer value with bit(s) set corresponding to + * the type of confusability found, as defined by + * enum USpoofChecks. Zero is returned if the identifiers + * are not confusable. + * + * @stable ICU 4.2 + * + * @see uspoof_areConfusable + */ +U_CAPI int32_t U_EXPORT2 +uspoof_areConfusableUnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &s1, + const icu::UnicodeString &s2, + UErrorCode *status); + +/** + * Get the "skeleton" for an identifier. + * Skeletons are a transformation of the input identifier; + * Two identifiers are confusable if their skeletons are identical. + * See Unicode UAX #39 for additional information. + * + * Using skeletons directly makes it possible to quickly check + * whether an identifier is confusable with any of some large + * set of existing identifiers, by creating an efficiently + * searchable collection of the skeletons. + * + * @param sc The USpoofChecker. + * @param type Deprecated in ICU 58. You may pass any number. + * Originally, controlled which of the Unicode confusable data + * tables to use. + * @param id The input identifier whose skeleton will be computed. + * @param dest The output identifier, to receive the skeleton string. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * @return A reference to the destination (skeleton) string. + * + * @stable ICU 4.2 + */ +U_I18N_API icu::UnicodeString & U_EXPORT2 +uspoof_getSkeletonUnicodeString(const USpoofChecker *sc, + uint32_t type, + const icu::UnicodeString &id, + icu::UnicodeString &dest, + UErrorCode *status); + +/** + * Get the set of Candidate Characters for Inclusion in Identifiers, as defined + * in http://unicode.org/Public/security/latest/xidmodifications.txt + * and documented in http://www.unicode.org/reports/tr39/, Unicode Security Mechanisms. + * + * The returned set is frozen. Ownership of the set remains with the ICU library; it must not + * be deleted by the caller. + * + * @param status The error code, set if a problem occurs while creating the set. + * + * @stable ICU 51 + */ +U_CAPI const icu::UnicodeSet * U_EXPORT2 +uspoof_getInclusionUnicodeSet(UErrorCode *status); + +/** + * Get the set of characters from Recommended Scripts for Inclusion in Identifiers, as defined + * in http://unicode.org/Public/security/latest/xidmodifications.txt + * and documented in http://www.unicode.org/reports/tr39/, Unicode Security Mechanisms. + * + * The returned set is frozen. Ownership of the set remains with the ICU library; it must not + * be deleted by the caller. + * + * @param status The error code, set if a problem occurs while creating the set. + * + * @stable ICU 51 + */ +U_CAPI const icu::UnicodeSet * U_EXPORT2 +uspoof_getRecommendedUnicodeSet(UErrorCode *status); + +#endif /* U_SHOW_CPLUSPLUS_API */ + +#endif /* UCONFIG_NO_NORMALIZATION */ + +#endif /* USPOOF_H */ diff --git a/thirdparty/icu4c/i18n/uspoof.cpp b/thirdparty/icu4c/i18n/uspoof.cpp new file mode 100644 index 0000000000..dd4618baa7 --- /dev/null +++ b/thirdparty/icu4c/i18n/uspoof.cpp @@ -0,0 +1,839 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +*************************************************************************** +* Copyright (C) 2008-2015, International Business Machines Corporation +* and others. All Rights Reserved. +*************************************************************************** +* file name: uspoof.cpp +* encoding: UTF-8 +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2008Feb13 +* created by: Andy Heninger +* +* Unicode Spoof Detection +*/ +#include "unicode/utypes.h" +#include "unicode/normalizer2.h" +#include "unicode/uspoof.h" +#include "unicode/ustring.h" +#include "unicode/utf16.h" +#include "cmemory.h" +#include "cstring.h" +#include "mutex.h" +#include "scriptset.h" +#include "uassert.h" +#include "ucln_in.h" +#include "uspoof_impl.h" +#include "umutex.h" + + +#if !UCONFIG_NO_NORMALIZATION + +U_NAMESPACE_USE + + +// +// Static Objects used by the spoof impl, their thread safe initialization and their cleanup. +// +static UnicodeSet *gInclusionSet = NULL; +static UnicodeSet *gRecommendedSet = NULL; +static const Normalizer2 *gNfdNormalizer = NULL; +static UInitOnce gSpoofInitStaticsOnce = U_INITONCE_INITIALIZER; + +namespace { + +UBool U_CALLCONV +uspoof_cleanup(void) { + delete gInclusionSet; + gInclusionSet = NULL; + delete gRecommendedSet; + gRecommendedSet = NULL; + gNfdNormalizer = NULL; + gSpoofInitStaticsOnce.reset(); + return TRUE; +} + +void U_CALLCONV initializeStatics(UErrorCode &status) { + static const char16_t *inclusionPat = + u"['\\-.\\:\\u00B7\\u0375\\u058A\\u05F3\\u05F4\\u06FD\\u06FE\\u0F0B\\u200C" + u"\\u200D\\u2010\\u2019\\u2027\\u30A0\\u30FB]"; + gInclusionSet = new UnicodeSet(UnicodeString(inclusionPat), status); + if (gInclusionSet == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + gInclusionSet->freeze(); + + // Note: data from IdentifierStatus.txt & IdentifierType.txt + // There is tooling to generate this constant in the unicodetools project: + // org.unicode.text.tools.RecommendedSetGenerator + // It will print the Java and C++ code to the console for easy copy-paste into this file. + static const char16_t *recommendedPat = + u"[0-9A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u0131\\u0134-\\u013E" + u"\\u0141-\\u0148\\u014A-\\u017E\\u018F\\u01A0\\u01A1\\u01AF\\u01B0\\u01CD-" + u"\\u01DC\\u01DE-\\u01E3\\u01E6-\\u01F0\\u01F4\\u01F5\\u01F8-\\u021B\\u021E" + u"\\u021F\\u0226-\\u0233\\u0259\\u02BB\\u02BC\\u02EC\\u0300-\\u0304\\u0306-" + u"\\u030C\\u030F-\\u0311\\u0313\\u0314\\u031B\\u0323-\\u0328\\u032D\\u032E" + u"\\u0330\\u0331\\u0335\\u0338\\u0339\\u0342\\u0345\\u037B-\\u037D\\u0386" + u"\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03CE\\u03FC-\\u045F\\u048A-" + u"\\u04FF\\u0510-\\u0529\\u052E\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0586" + u"\\u05B4\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u063F\\u0641-\\u0655\\u0660-" + u"\\u0669\\u0670-\\u0672\\u0674\\u0679-\\u068D\\u068F-\\u06A0\\u06A2-\\u06D3" + u"\\u06D5\\u06E5\\u06E6\\u06EE-\\u06FC\\u06FF\\u0750-\\u07B1\\u0870-\\u0887" + u"\\u0889-\\u088E\\u08A0-\\u08AC\\u08B2\\u08B5-\\u08C9\\u0901-\\u094D\\u094F" + u"\\u0950\\u0956\\u0957\\u0960-\\u0963\\u0966-\\u096F\\u0971-\\u0977\\u0979-" + u"\\u097F\\u0981-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-" + u"\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE" + u"\\u09D7\\u09E0-\\u09E3\\u09E6-\\u09F1\\u09FE\\u0A01-\\u0A03\\u0A05-\\u0A0A" + u"\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A35\\u0A38\\u0A39" + u"\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A5C\\u0A66-\\u0A74" + u"\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0" + u"\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD" + u"\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0AFA-\\u0AFF\\u0B01-\\u0B03\\u0B05-" + u"\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-" + u"\\u0B39\\u0B3C-\\u0B43\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B55-\\u0B57\\u0B5F-" + u"\\u0B61\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90" + u"\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-" + u"\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0" + u"\\u0BD7\\u0BE6-\\u0BEF\\u0C01-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-" + u"\\u0C33\\u0C35-\\u0C39\\u0C3C-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55" + u"\\u0C56\\u0C5D\\u0C60\\u0C61\\u0C66-\\u0C6F\\u0C80\\u0C82\\u0C83\\u0C85-" + u"\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-" + u"\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CDD\\u0CE0-\\u0CE3" + u"\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D00\\u0D02\\u0D03\\u0D05-\\u0D0C\\u0D0E-" + u"\\u0D10\\u0D12-\\u0D3A\\u0D3D-\\u0D43\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D54-" + u"\\u0D57\\u0D60\\u0D61\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-" + u"\\u0D8E\\u0D91-\\u0D96\\u0D9A-\\u0DA5\\u0DA7-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD" + u"\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDE\\u0DF2\\u0E01-" + u"\\u0E32\\u0E34-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59\\u0E81\\u0E82\\u0E84" + u"\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB2\\u0EB4-\\u0EBD\\u0EC0-" + u"\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDE\\u0EDF\\u0F00\\u0F20-" + u"\\u0F29\\u0F35\\u0F37\\u0F3E-\\u0F42\\u0F44-\\u0F47\\u0F49-\\u0F4C\\u0F4E-" + u"\\u0F51\\u0F53-\\u0F56\\u0F58-\\u0F5B\\u0F5D-\\u0F68\\u0F6A-\\u0F6C\\u0F71" + u"\\u0F72\\u0F74\\u0F7A-\\u0F80\\u0F82-\\u0F84\\u0F86-\\u0F92\\u0F94-\\u0F97" + u"\\u0F99-\\u0F9C\\u0F9E-\\u0FA1\\u0FA3-\\u0FA6\\u0FA8-\\u0FAB\\u0FAD-\\u0FB8" + u"\\u0FBA-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10C7\\u10CD\\u10D0-" + u"\\u10F0\\u10F7-\\u10FA\\u10FD-\\u10FF\\u1200-\\u1248\\u124A-\\u124D\\u1250-" + u"\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0" + u"\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-" + u"\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u1780-" + u"\\u17A2\\u17A5-\\u17A7\\u17A9-\\u17B3\\u17B6-\\u17CD\\u17D0\\u17D2\\u17D7" + u"\\u17DC\\u17E0-\\u17E9\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1E00-\\u1E99\\u1E9E" + u"\\u1EA0-\\u1EF9\\u1F00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D" + u"\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F70\\u1F72\\u1F74\\u1F76" + u"\\u1F78\\u1F7A\\u1F7C\\u1F80-\\u1FB4\\u1FB6-\\u1FBA\\u1FBC\\u1FC2-\\u1FC4" + u"\\u1FC6-\\u1FC8\\u1FCA\\u1FCC\\u1FD0-\\u1FD2\\u1FD6-\\u1FDA\\u1FE0-\\u1FE2" + u"\\u1FE4-\\u1FEA\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FF8\\u1FFA\\u1FFC\\u2D27" + u"\\u2D2D\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-" + u"\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u3005-" + u"\\u3007\\u3041-\\u3096\\u3099\\u309A\\u309D\\u309E\\u30A1-\\u30FA\\u30FC-" + u"\\u30FE\\u3105-\\u312D\\u312F\\u31A0-\\u31BF\\u3400-\\u4DBF\\u4E00-\\u9FFF" + u"\\uA67F\\uA717-\\uA71F\\uA788\\uA78D\\uA792\\uA793\\uA7AA\\uA7AE\\uA7B8" + u"\\uA7B9\\uA7C0-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA9E7-\\uA9FE" + u"\\uAA60-\\uAA76\\uAA7A-\\uAA7F\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16" + u"\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB66\\uAB67\\uAC00-\\uD7A3\\uFA0E\\uFA0F" + u"\\uFA11\\uFA13\\uFA14\\uFA1F\\uFA21\\uFA23\\uFA24\\uFA27-\\uFA29\\U00011301" + u"\\U00011303\\U0001133B\\U0001133C\\U00016FF0\\U00016FF1\\U0001B11F-" + u"\\U0001B122\\U0001B150-\\U0001B152\\U0001B164-\\U0001B167\\U0001DF00-" + u"\\U0001DF1E\\U0001E7E0-\\U0001E7E6\\U0001E7E8-\\U0001E7EB\\U0001E7ED" + u"\\U0001E7EE\\U0001E7F0-\\U0001E7FE\\U00020000-\\U0002A6DF\\U0002A700-" + u"\\U0002B738\\U0002B740-\\U0002B81D\\U0002B820-\\U0002CEA1\\U0002CEB0-" + u"\\U0002EBE0\\U00030000-\\U0003134A]"; + + gRecommendedSet = new UnicodeSet(UnicodeString(recommendedPat), status); + if (gRecommendedSet == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + delete gInclusionSet; + return; + } + gRecommendedSet->freeze(); + gNfdNormalizer = Normalizer2::getNFDInstance(status); + ucln_i18n_registerCleanup(UCLN_I18N_SPOOF, uspoof_cleanup); +} + +} // namespace + +U_CFUNC void uspoof_internalInitStatics(UErrorCode *status) { + umtx_initOnce(gSpoofInitStaticsOnce, &initializeStatics, *status); +} + +U_CAPI USpoofChecker * U_EXPORT2 +uspoof_open(UErrorCode *status) { + umtx_initOnce(gSpoofInitStaticsOnce, &initializeStatics, *status); + if (U_FAILURE(*status)) { + return NULL; + } + SpoofImpl *si = new SpoofImpl(*status); + if (si == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + if (U_FAILURE(*status)) { + delete si; + return NULL; + } + return si->asUSpoofChecker(); +} + + +U_CAPI USpoofChecker * U_EXPORT2 +uspoof_openFromSerialized(const void *data, int32_t length, int32_t *pActualLength, + UErrorCode *status) { + if (U_FAILURE(*status)) { + return NULL; + } + + if (data == NULL) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return NULL; + } + + umtx_initOnce(gSpoofInitStaticsOnce, &initializeStatics, *status); + if (U_FAILURE(*status)) + { + return NULL; + } + + SpoofData *sd = new SpoofData(data, length, *status); + if (sd == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + + if (U_FAILURE(*status)) { + delete sd; + return NULL; + } + + SpoofImpl *si = new SpoofImpl(sd, *status); + if (si == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + delete sd; // explicit delete as the destructor for si won't be called. + return NULL; + } + + if (U_FAILURE(*status)) { + delete si; // no delete for sd, as the si destructor will delete it. + return NULL; + } + + if (pActualLength != NULL) { + *pActualLength = sd->size(); + } + return si->asUSpoofChecker(); +} + + +U_CAPI USpoofChecker * U_EXPORT2 +uspoof_clone(const USpoofChecker *sc, UErrorCode *status) { + const SpoofImpl *src = SpoofImpl::validateThis(sc, *status); + if (src == NULL) { + return NULL; + } + SpoofImpl *result = new SpoofImpl(*src, *status); // copy constructor + if (result == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + if (U_FAILURE(*status)) { + delete result; + result = NULL; + } + return result->asUSpoofChecker(); +} + + +U_CAPI void U_EXPORT2 +uspoof_close(USpoofChecker *sc) { + UErrorCode status = U_ZERO_ERROR; + SpoofImpl *This = SpoofImpl::validateThis(sc, status); + delete This; +} + + +U_CAPI void U_EXPORT2 +uspoof_setChecks(USpoofChecker *sc, int32_t checks, UErrorCode *status) { + SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (This == NULL) { + return; + } + + // Verify that the requested checks are all ones (bits) that + // are acceptable, known values. + if (checks & ~(USPOOF_ALL_CHECKS | USPOOF_AUX_INFO)) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } + + This->fChecks = checks; +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_getChecks(const USpoofChecker *sc, UErrorCode *status) { + const SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (This == NULL) { + return 0; + } + return This->fChecks; +} + +U_CAPI void U_EXPORT2 +uspoof_setRestrictionLevel(USpoofChecker *sc, URestrictionLevel restrictionLevel) { + UErrorCode status = U_ZERO_ERROR; + SpoofImpl *This = SpoofImpl::validateThis(sc, status); + if (This != NULL) { + This->fRestrictionLevel = restrictionLevel; + This->fChecks |= USPOOF_RESTRICTION_LEVEL; + } +} + +U_CAPI URestrictionLevel U_EXPORT2 +uspoof_getRestrictionLevel(const USpoofChecker *sc) { + UErrorCode status = U_ZERO_ERROR; + const SpoofImpl *This = SpoofImpl::validateThis(sc, status); + if (This == NULL) { + return USPOOF_UNRESTRICTIVE; + } + return This->fRestrictionLevel; +} + +U_CAPI void U_EXPORT2 +uspoof_setAllowedLocales(USpoofChecker *sc, const char *localesList, UErrorCode *status) { + SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (This == NULL) { + return; + } + This->setAllowedLocales(localesList, *status); +} + +U_CAPI const char * U_EXPORT2 +uspoof_getAllowedLocales(USpoofChecker *sc, UErrorCode *status) { + SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (This == NULL) { + return NULL; + } + return This->getAllowedLocales(*status); +} + + +U_CAPI const USet * U_EXPORT2 +uspoof_getAllowedChars(const USpoofChecker *sc, UErrorCode *status) { + const UnicodeSet *result = uspoof_getAllowedUnicodeSet(sc, status); + return result->toUSet(); +} + +U_CAPI const UnicodeSet * U_EXPORT2 +uspoof_getAllowedUnicodeSet(const USpoofChecker *sc, UErrorCode *status) { + const SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (This == NULL) { + return NULL; + } + return This->fAllowedCharsSet; +} + + +U_CAPI void U_EXPORT2 +uspoof_setAllowedChars(USpoofChecker *sc, const USet *chars, UErrorCode *status) { + const UnicodeSet *set = UnicodeSet::fromUSet(chars); + uspoof_setAllowedUnicodeSet(sc, set, status); +} + + +U_CAPI void U_EXPORT2 +uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const UnicodeSet *chars, UErrorCode *status) { + SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (This == NULL) { + return; + } + if (chars->isBogus()) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } + UnicodeSet *clonedSet = chars->clone(); + if (clonedSet == NULL || clonedSet->isBogus()) { + *status = U_MEMORY_ALLOCATION_ERROR; + return; + } + clonedSet->freeze(); + delete This->fAllowedCharsSet; + This->fAllowedCharsSet = clonedSet; + This->fChecks |= USPOOF_CHAR_LIMIT; +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_check(const USpoofChecker *sc, + const UChar *id, int32_t length, + int32_t *position, + UErrorCode *status) { + + // Backwards compatibility: + if (position != NULL) { + *position = 0; + } + + // Delegate to uspoof_check2 + return uspoof_check2(sc, id, length, NULL, status); +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_check2(const USpoofChecker *sc, + const UChar* id, int32_t length, + USpoofCheckResult* checkResult, + UErrorCode *status) { + + const SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (This == NULL) { + return 0; + } + if (length < -1) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + UnicodeString idStr((length == -1), id, length); // Aliasing constructor. + int32_t result = uspoof_check2UnicodeString(sc, idStr, checkResult, status); + return result; +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_checkUTF8(const USpoofChecker *sc, + const char *id, int32_t length, + int32_t *position, + UErrorCode *status) { + + // Backwards compatibility: + if (position != NULL) { + *position = 0; + } + + // Delegate to uspoof_check2 + return uspoof_check2UTF8(sc, id, length, NULL, status); +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_check2UTF8(const USpoofChecker *sc, + const char *id, int32_t length, + USpoofCheckResult* checkResult, + UErrorCode *status) { + + if (U_FAILURE(*status)) { + return 0; + } + UnicodeString idStr = UnicodeString::fromUTF8(StringPiece(id, length>=0 ? length : static_cast<int32_t>(uprv_strlen(id)))); + int32_t result = uspoof_check2UnicodeString(sc, idStr, checkResult, status); + return result; +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_areConfusable(const USpoofChecker *sc, + const UChar *id1, int32_t length1, + const UChar *id2, int32_t length2, + UErrorCode *status) { + SpoofImpl::validateThis(sc, *status); + if (U_FAILURE(*status)) { + return 0; + } + if (length1 < -1 || length2 < -1) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + UnicodeString id1Str((length1==-1), id1, length1); // Aliasing constructor + UnicodeString id2Str((length2==-1), id2, length2); // Aliasing constructor + return uspoof_areConfusableUnicodeString(sc, id1Str, id2Str, status); +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_areConfusableUTF8(const USpoofChecker *sc, + const char *id1, int32_t length1, + const char *id2, int32_t length2, + UErrorCode *status) { + SpoofImpl::validateThis(sc, *status); + if (U_FAILURE(*status)) { + return 0; + } + if (length1 < -1 || length2 < -1) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + UnicodeString id1Str = UnicodeString::fromUTF8(StringPiece(id1, length1>=0? length1 : static_cast<int32_t>(uprv_strlen(id1)))); + UnicodeString id2Str = UnicodeString::fromUTF8(StringPiece(id2, length2>=0? length2 : static_cast<int32_t>(uprv_strlen(id2)))); + int32_t results = uspoof_areConfusableUnicodeString(sc, id1Str, id2Str, status); + return results; +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_areConfusableUnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &id1, + const icu::UnicodeString &id2, + UErrorCode *status) { + const SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (U_FAILURE(*status)) { + return 0; + } + // + // See section 4 of UAX 39 for the algorithm for checking whether two strings are confusable, + // and for definitions of the types (single, whole, mixed-script) of confusables. + + // We only care about a few of the check flags. Ignore the others. + // If no tests relevant to this function have been specified, return an error. + // TODO: is this really the right thing to do? It's probably an error on the caller's part, + // but logically we would just return 0 (no error). + if ((This->fChecks & USPOOF_CONFUSABLE) == 0) { + *status = U_INVALID_STATE_ERROR; + return 0; + } + + // Compute the skeletons and check for confusability. + UnicodeString id1Skeleton; + uspoof_getSkeletonUnicodeString(sc, 0 /* deprecated */, id1, id1Skeleton, status); + UnicodeString id2Skeleton; + uspoof_getSkeletonUnicodeString(sc, 0 /* deprecated */, id2, id2Skeleton, status); + if (U_FAILURE(*status)) { return 0; } + if (id1Skeleton != id2Skeleton) { + return 0; + } + + // If we get here, the strings are confusable. Now we just need to set the flags for the appropriate classes + // of confusables according to UTS 39 section 4. + // Start by computing the resolved script sets of id1 and id2. + ScriptSet id1RSS; + This->getResolvedScriptSet(id1, id1RSS, *status); + ScriptSet id2RSS; + This->getResolvedScriptSet(id2, id2RSS, *status); + + // Turn on all applicable flags + int32_t result = 0; + if (id1RSS.intersects(id2RSS)) { + result |= USPOOF_SINGLE_SCRIPT_CONFUSABLE; + } else { + result |= USPOOF_MIXED_SCRIPT_CONFUSABLE; + if (!id1RSS.isEmpty() && !id2RSS.isEmpty()) { + result |= USPOOF_WHOLE_SCRIPT_CONFUSABLE; + } + } + + // Turn off flags that the user doesn't want + if ((This->fChecks & USPOOF_SINGLE_SCRIPT_CONFUSABLE) == 0) { + result &= ~USPOOF_SINGLE_SCRIPT_CONFUSABLE; + } + if ((This->fChecks & USPOOF_MIXED_SCRIPT_CONFUSABLE) == 0) { + result &= ~USPOOF_MIXED_SCRIPT_CONFUSABLE; + } + if ((This->fChecks & USPOOF_WHOLE_SCRIPT_CONFUSABLE) == 0) { + result &= ~USPOOF_WHOLE_SCRIPT_CONFUSABLE; + } + + return result; +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_checkUnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &id, + int32_t *position, + UErrorCode *status) { + + // Backwards compatibility: + if (position != NULL) { + *position = 0; + } + + // Delegate to uspoof_check2 + return uspoof_check2UnicodeString(sc, id, NULL, status); +} + +namespace { + +int32_t checkImpl(const SpoofImpl* This, const UnicodeString& id, CheckResult* checkResult, UErrorCode* status) { + U_ASSERT(This != NULL); + U_ASSERT(checkResult != NULL); + checkResult->clear(); + int32_t result = 0; + + if (0 != (This->fChecks & USPOOF_RESTRICTION_LEVEL)) { + URestrictionLevel idRestrictionLevel = This->getRestrictionLevel(id, *status); + if (idRestrictionLevel > This->fRestrictionLevel) { + result |= USPOOF_RESTRICTION_LEVEL; + } + checkResult->fRestrictionLevel = idRestrictionLevel; + } + + if (0 != (This->fChecks & USPOOF_MIXED_NUMBERS)) { + UnicodeSet numerics; + This->getNumerics(id, numerics, *status); + if (numerics.size() > 1) { + result |= USPOOF_MIXED_NUMBERS; + } + checkResult->fNumerics = numerics; // UnicodeSet::operator= + } + + if (0 != (This->fChecks & USPOOF_HIDDEN_OVERLAY)) { + int32_t index = This->findHiddenOverlay(id, *status); + if (index != -1) { + result |= USPOOF_HIDDEN_OVERLAY; + } + } + + + if (0 != (This->fChecks & USPOOF_CHAR_LIMIT)) { + int32_t i; + UChar32 c; + int32_t length = id.length(); + for (i=0; i<length ;) { + c = id.char32At(i); + i += U16_LENGTH(c); + if (!This->fAllowedCharsSet->contains(c)) { + result |= USPOOF_CHAR_LIMIT; + break; + } + } + } + + if (0 != (This->fChecks & USPOOF_INVISIBLE)) { + // This check needs to be done on NFD input + UnicodeString nfdText; + gNfdNormalizer->normalize(id, nfdText, *status); + int32_t nfdLength = nfdText.length(); + + // scan for more than one occurrence of the same non-spacing mark + // in a sequence of non-spacing marks. + int32_t i; + UChar32 c; + UChar32 firstNonspacingMark = 0; + UBool haveMultipleMarks = FALSE; + UnicodeSet marksSeenSoFar; // Set of combining marks in a single combining sequence. + + for (i=0; i<nfdLength ;) { + c = nfdText.char32At(i); + i += U16_LENGTH(c); + if (u_charType(c) != U_NON_SPACING_MARK) { + firstNonspacingMark = 0; + if (haveMultipleMarks) { + marksSeenSoFar.clear(); + haveMultipleMarks = FALSE; + } + continue; + } + if (firstNonspacingMark == 0) { + firstNonspacingMark = c; + continue; + } + if (!haveMultipleMarks) { + marksSeenSoFar.add(firstNonspacingMark); + haveMultipleMarks = TRUE; + } + if (marksSeenSoFar.contains(c)) { + // report the error, and stop scanning. + // No need to find more than the first failure. + result |= USPOOF_INVISIBLE; + break; + } + marksSeenSoFar.add(c); + } + } + + checkResult->fChecks = result; + return checkResult->toCombinedBitmask(This->fChecks); +} + +} // namespace + +U_CAPI int32_t U_EXPORT2 +uspoof_check2UnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &id, + USpoofCheckResult* checkResult, + UErrorCode *status) { + const SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (This == NULL) { + return FALSE; + } + + if (checkResult != NULL) { + CheckResult* ThisCheckResult = CheckResult::validateThis(checkResult, *status); + if (ThisCheckResult == NULL) { + return FALSE; + } + return checkImpl(This, id, ThisCheckResult, status); + } else { + // Stack-allocate the checkResult since this method doesn't return it + CheckResult stackCheckResult; + return checkImpl(This, id, &stackCheckResult, status); + } +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_getSkeleton(const USpoofChecker *sc, + uint32_t type, + const UChar *id, int32_t length, + UChar *dest, int32_t destCapacity, + UErrorCode *status) { + + SpoofImpl::validateThis(sc, *status); + if (U_FAILURE(*status)) { + return 0; + } + if (length<-1 || destCapacity<0 || (destCapacity==0 && dest!=NULL)) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + UnicodeString idStr((length==-1), id, length); // Aliasing constructor + UnicodeString destStr; + uspoof_getSkeletonUnicodeString(sc, type, idStr, destStr, status); + destStr.extract(dest, destCapacity, *status); + return destStr.length(); +} + + + +U_I18N_API UnicodeString & U_EXPORT2 +uspoof_getSkeletonUnicodeString(const USpoofChecker *sc, + uint32_t /*type*/, + const UnicodeString &id, + UnicodeString &dest, + UErrorCode *status) { + const SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (U_FAILURE(*status)) { + return dest; + } + + UnicodeString nfdId; + gNfdNormalizer->normalize(id, nfdId, *status); + + // Apply the skeleton mapping to the NFD normalized input string + // Accumulate the skeleton, possibly unnormalized, in a UnicodeString. + int32_t inputIndex = 0; + UnicodeString skelStr; + int32_t normalizedLen = nfdId.length(); + for (inputIndex=0; inputIndex < normalizedLen; ) { + UChar32 c = nfdId.char32At(inputIndex); + inputIndex += U16_LENGTH(c); + This->fSpoofData->confusableLookup(c, skelStr); + } + + gNfdNormalizer->normalize(skelStr, dest, *status); + return dest; +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_getSkeletonUTF8(const USpoofChecker *sc, + uint32_t type, + const char *id, int32_t length, + char *dest, int32_t destCapacity, + UErrorCode *status) { + SpoofImpl::validateThis(sc, *status); + if (U_FAILURE(*status)) { + return 0; + } + if (length<-1 || destCapacity<0 || (destCapacity==0 && dest!=NULL)) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + UnicodeString srcStr = UnicodeString::fromUTF8(StringPiece(id, length>=0 ? length : static_cast<int32_t>(uprv_strlen(id)))); + UnicodeString destStr; + uspoof_getSkeletonUnicodeString(sc, type, srcStr, destStr, status); + if (U_FAILURE(*status)) { + return 0; + } + + int32_t lengthInUTF8 = 0; + u_strToUTF8(dest, destCapacity, &lengthInUTF8, + destStr.getBuffer(), destStr.length(), status); + return lengthInUTF8; +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_serialize(USpoofChecker *sc,void *buf, int32_t capacity, UErrorCode *status) { + SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (This == NULL) { + U_ASSERT(U_FAILURE(*status)); + return 0; + } + + return This->fSpoofData->serialize(buf, capacity, *status); +} + +U_CAPI const USet * U_EXPORT2 +uspoof_getInclusionSet(UErrorCode *status) { + umtx_initOnce(gSpoofInitStaticsOnce, &initializeStatics, *status); + return gInclusionSet->toUSet(); +} + +U_CAPI const USet * U_EXPORT2 +uspoof_getRecommendedSet(UErrorCode *status) { + umtx_initOnce(gSpoofInitStaticsOnce, &initializeStatics, *status); + return gRecommendedSet->toUSet(); +} + +U_I18N_API const UnicodeSet * U_EXPORT2 +uspoof_getInclusionUnicodeSet(UErrorCode *status) { + umtx_initOnce(gSpoofInitStaticsOnce, &initializeStatics, *status); + return gInclusionSet; +} + +U_I18N_API const UnicodeSet * U_EXPORT2 +uspoof_getRecommendedUnicodeSet(UErrorCode *status) { + umtx_initOnce(gSpoofInitStaticsOnce, &initializeStatics, *status); + return gRecommendedSet; +} + +//------------------ +// CheckResult APIs +//------------------ + +U_CAPI USpoofCheckResult* U_EXPORT2 +uspoof_openCheckResult(UErrorCode *status) { + CheckResult* checkResult = new CheckResult(); + if (checkResult == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + return checkResult->asUSpoofCheckResult(); +} + +U_CAPI void U_EXPORT2 +uspoof_closeCheckResult(USpoofCheckResult* checkResult) { + UErrorCode status = U_ZERO_ERROR; + CheckResult* This = CheckResult::validateThis(checkResult, status); + delete This; +} + +U_CAPI int32_t U_EXPORT2 +uspoof_getCheckResultChecks(const USpoofCheckResult *checkResult, UErrorCode *status) { + const CheckResult* This = CheckResult::validateThis(checkResult, *status); + if (U_FAILURE(*status)) { return 0; } + return This->fChecks; +} + +U_CAPI URestrictionLevel U_EXPORT2 +uspoof_getCheckResultRestrictionLevel(const USpoofCheckResult *checkResult, UErrorCode *status) { + const CheckResult* This = CheckResult::validateThis(checkResult, *status); + if (U_FAILURE(*status)) { return USPOOF_UNRESTRICTIVE; } + return This->fRestrictionLevel; +} + +U_CAPI const USet* U_EXPORT2 +uspoof_getCheckResultNumerics(const USpoofCheckResult *checkResult, UErrorCode *status) { + const CheckResult* This = CheckResult::validateThis(checkResult, *status); + if (U_FAILURE(*status)) { return NULL; } + return This->fNumerics.toUSet(); +} + + + +#endif // !UCONFIG_NO_NORMALIZATION diff --git a/thirdparty/icu4c/i18n/uspoof_impl.cpp b/thirdparty/icu4c/i18n/uspoof_impl.cpp new file mode 100644 index 0000000000..b283d81321 --- /dev/null +++ b/thirdparty/icu4c/i18n/uspoof_impl.cpp @@ -0,0 +1,959 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +********************************************************************** +* Copyright (C) 2008-2016, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +*/ + +#include "unicode/utypes.h" +#include "unicode/uspoof.h" +#include "unicode/uchar.h" +#include "unicode/uniset.h" +#include "unicode/utf16.h" +#include "utrie2.h" +#include "cmemory.h" +#include "cstring.h" +#include "scriptset.h" +#include "umutex.h" +#include "udataswp.h" +#include "uassert.h" +#include "ucln_in.h" +#include "uspoof_impl.h" + +#if !UCONFIG_NO_NORMALIZATION + + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SpoofImpl) + +SpoofImpl::SpoofImpl(SpoofData *data, UErrorCode& status) { + construct(status); + fSpoofData = data; +} + +SpoofImpl::SpoofImpl(UErrorCode& status) { + construct(status); + + // TODO: Call this method where it is actually needed, instead of in the + // constructor, to allow for lazy data loading. See #12696. + fSpoofData = SpoofData::getDefault(status); +} + +SpoofImpl::SpoofImpl() { + UErrorCode status = U_ZERO_ERROR; + construct(status); + + // TODO: Call this method where it is actually needed, instead of in the + // constructor, to allow for lazy data loading. See #12696. + fSpoofData = SpoofData::getDefault(status); +} + +void SpoofImpl::construct(UErrorCode& status) { + fChecks = USPOOF_ALL_CHECKS; + fSpoofData = NULL; + fAllowedCharsSet = NULL; + fAllowedLocales = NULL; + fRestrictionLevel = USPOOF_HIGHLY_RESTRICTIVE; + + if (U_FAILURE(status)) { return; } + + UnicodeSet *allowedCharsSet = new UnicodeSet(0, 0x10ffff); + fAllowedCharsSet = allowedCharsSet; + fAllowedLocales = uprv_strdup(""); + if (fAllowedCharsSet == NULL || fAllowedLocales == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + allowedCharsSet->freeze(); +} + + +// Copy Constructor, used by the user level clone() function. +SpoofImpl::SpoofImpl(const SpoofImpl &src, UErrorCode &status) : + fChecks(USPOOF_ALL_CHECKS), fSpoofData(NULL), fAllowedCharsSet(NULL) , + fAllowedLocales(NULL) { + if (U_FAILURE(status)) { + return; + } + fChecks = src.fChecks; + if (src.fSpoofData != NULL) { + fSpoofData = src.fSpoofData->addReference(); + } + fAllowedCharsSet = src.fAllowedCharsSet->clone(); + fAllowedLocales = uprv_strdup(src.fAllowedLocales); + if (fAllowedCharsSet == NULL || fAllowedLocales == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + } + fRestrictionLevel = src.fRestrictionLevel; +} + +SpoofImpl::~SpoofImpl() { + if (fSpoofData != NULL) { + fSpoofData->removeReference(); // Will delete if refCount goes to zero. + } + delete fAllowedCharsSet; + uprv_free((void *)fAllowedLocales); +} + +// Cast this instance as a USpoofChecker for the C API. +USpoofChecker *SpoofImpl::asUSpoofChecker() { + return exportForC(); +} + +// +// Incoming parameter check on Status and the SpoofChecker object +// received from the C API. +// +const SpoofImpl *SpoofImpl::validateThis(const USpoofChecker *sc, UErrorCode &status) { + auto* This = validate(sc, status); + if (U_FAILURE(status)) { + return NULL; + } + if (This->fSpoofData != NULL && !This->fSpoofData->validateDataVersion(status)) { + return NULL; + } + return This; +} + +SpoofImpl *SpoofImpl::validateThis(USpoofChecker *sc, UErrorCode &status) { + return const_cast<SpoofImpl *> + (SpoofImpl::validateThis(const_cast<const USpoofChecker *>(sc), status)); +} + + +void SpoofImpl::setAllowedLocales(const char *localesList, UErrorCode &status) { + UnicodeSet allowedChars; + UnicodeSet *tmpSet = NULL; + const char *locStart = localesList; + const char *locEnd = NULL; + const char *localesListEnd = localesList + uprv_strlen(localesList); + int32_t localeListCount = 0; // Number of locales provided by caller. + + // Loop runs once per locale from the localesList, a comma separated list of locales. + do { + locEnd = uprv_strchr(locStart, ','); + if (locEnd == NULL) { + locEnd = localesListEnd; + } + while (*locStart == ' ') { + locStart++; + } + const char *trimmedEnd = locEnd-1; + while (trimmedEnd > locStart && *trimmedEnd == ' ') { + trimmedEnd--; + } + if (trimmedEnd <= locStart) { + break; + } + const char *locale = uprv_strndup(locStart, (int32_t)(trimmedEnd + 1 - locStart)); + localeListCount++; + + // We have one locale from the locales list. + // Add the script chars for this locale to the accumulating set of allowed chars. + // If the locale is no good, we will be notified back via status. + addScriptChars(locale, &allowedChars, status); + uprv_free((void *)locale); + if (U_FAILURE(status)) { + break; + } + locStart = locEnd + 1; + } while (locStart < localesListEnd); + + // If our caller provided an empty list of locales, we disable the allowed characters checking + if (localeListCount == 0) { + uprv_free((void *)fAllowedLocales); + fAllowedLocales = uprv_strdup(""); + tmpSet = new UnicodeSet(0, 0x10ffff); + if (fAllowedLocales == NULL || tmpSet == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + tmpSet->freeze(); + delete fAllowedCharsSet; + fAllowedCharsSet = tmpSet; + fChecks &= ~USPOOF_CHAR_LIMIT; + return; + } + + + // Add all common and inherited characters to the set of allowed chars. + UnicodeSet tempSet; + tempSet.applyIntPropertyValue(UCHAR_SCRIPT, USCRIPT_COMMON, status); + allowedChars.addAll(tempSet); + tempSet.applyIntPropertyValue(UCHAR_SCRIPT, USCRIPT_INHERITED, status); + allowedChars.addAll(tempSet); + + // If anything went wrong, we bail out without changing + // the state of the spoof checker. + if (U_FAILURE(status)) { + return; + } + + // Store the updated spoof checker state. + tmpSet = allowedChars.clone(); + const char *tmpLocalesList = uprv_strdup(localesList); + if (tmpSet == NULL || tmpLocalesList == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + uprv_free((void *)fAllowedLocales); + fAllowedLocales = tmpLocalesList; + tmpSet->freeze(); + delete fAllowedCharsSet; + fAllowedCharsSet = tmpSet; + fChecks |= USPOOF_CHAR_LIMIT; +} + + +const char * SpoofImpl::getAllowedLocales(UErrorCode &/*status*/) { + return fAllowedLocales; +} + + +// Given a locale (a language), add all the characters from all of the scripts used with that language +// to the allowedChars UnicodeSet + +void SpoofImpl::addScriptChars(const char *locale, UnicodeSet *allowedChars, UErrorCode &status) { + UScriptCode scripts[30]; + + int32_t numScripts = uscript_getCode(locale, scripts, UPRV_LENGTHOF(scripts), &status); + if (U_FAILURE(status)) { + return; + } + if (status == U_USING_DEFAULT_WARNING) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } + UnicodeSet tmpSet; + int32_t i; + for (i=0; i<numScripts; i++) { + tmpSet.applyIntPropertyValue(UCHAR_SCRIPT, scripts[i], status); + allowedChars->addAll(tmpSet); + } +} + +// Computes the augmented script set for a code point, according to UTS 39 section 5.1. +void SpoofImpl::getAugmentedScriptSet(UChar32 codePoint, ScriptSet& result, UErrorCode& status) { + result.resetAll(); + result.setScriptExtensions(codePoint, status); + if (U_FAILURE(status)) { return; } + + // Section 5.1 step 1 + if (result.test(USCRIPT_HAN, status)) { + result.set(USCRIPT_HAN_WITH_BOPOMOFO, status); + result.set(USCRIPT_JAPANESE, status); + result.set(USCRIPT_KOREAN, status); + } + if (result.test(USCRIPT_HIRAGANA, status)) { + result.set(USCRIPT_JAPANESE, status); + } + if (result.test(USCRIPT_KATAKANA, status)) { + result.set(USCRIPT_JAPANESE, status); + } + if (result.test(USCRIPT_HANGUL, status)) { + result.set(USCRIPT_KOREAN, status); + } + if (result.test(USCRIPT_BOPOMOFO, status)) { + result.set(USCRIPT_HAN_WITH_BOPOMOFO, status); + } + + // Section 5.1 step 2 + if (result.test(USCRIPT_COMMON, status) || result.test(USCRIPT_INHERITED, status)) { + result.setAll(); + } +} + +// Computes the resolved script set for a string, according to UTS 39 section 5.1. +void SpoofImpl::getResolvedScriptSet(const UnicodeString& input, ScriptSet& result, UErrorCode& status) const { + getResolvedScriptSetWithout(input, USCRIPT_CODE_LIMIT, result, status); +} + +// Computes the resolved script set for a string, omitting characters having the specified script. +// If USCRIPT_CODE_LIMIT is passed as the second argument, all characters are included. +void SpoofImpl::getResolvedScriptSetWithout(const UnicodeString& input, UScriptCode script, ScriptSet& result, UErrorCode& status) const { + result.setAll(); + + ScriptSet temp; + UChar32 codePoint; + for (int32_t i = 0; i < input.length(); i += U16_LENGTH(codePoint)) { + codePoint = input.char32At(i); + + // Compute the augmented script set for the character + getAugmentedScriptSet(codePoint, temp, status); + if (U_FAILURE(status)) { return; } + + // Intersect the augmented script set with the resolved script set, but only if the character doesn't + // have the script specified in the function call + if (script == USCRIPT_CODE_LIMIT || !temp.test(script, status)) { + result.intersect(temp); + } + } +} + +// Computes the set of numerics for a string, according to UTS 39 section 5.3. +void SpoofImpl::getNumerics(const UnicodeString& input, UnicodeSet& result, UErrorCode& /*status*/) const { + result.clear(); + + UChar32 codePoint; + for (int32_t i = 0; i < input.length(); i += U16_LENGTH(codePoint)) { + codePoint = input.char32At(i); + + // Store a representative character for each kind of decimal digit + if (u_charType(codePoint) == U_DECIMAL_DIGIT_NUMBER) { + // Store the zero character as a representative for comparison. + // Unicode guarantees it is codePoint - value + result.add(codePoint - (UChar32)u_getNumericValue(codePoint)); + } + } +} + +// Computes the restriction level of a string, according to UTS 39 section 5.2. +URestrictionLevel SpoofImpl::getRestrictionLevel(const UnicodeString& input, UErrorCode& status) const { + // Section 5.2 step 1: + if (!fAllowedCharsSet->containsAll(input)) { + return USPOOF_UNRESTRICTIVE; + } + + // Section 5.2 step 2 + // Java use a static UnicodeSet for this test. In C++, avoid the static variable + // and just do a simple for loop. + UBool allASCII = TRUE; + for (int32_t i=0, length=input.length(); i<length; i++) { + if (input.charAt(i) > 0x7f) { + allASCII = FALSE; + break; + } + } + if (allASCII) { + return USPOOF_ASCII; + } + + // Section 5.2 steps 3: + ScriptSet resolvedScriptSet; + getResolvedScriptSet(input, resolvedScriptSet, status); + if (U_FAILURE(status)) { return USPOOF_UNRESTRICTIVE; } + + // Section 5.2 step 4: + if (!resolvedScriptSet.isEmpty()) { + return USPOOF_SINGLE_SCRIPT_RESTRICTIVE; + } + + // Section 5.2 step 5: + ScriptSet resolvedNoLatn; + getResolvedScriptSetWithout(input, USCRIPT_LATIN, resolvedNoLatn, status); + if (U_FAILURE(status)) { return USPOOF_UNRESTRICTIVE; } + + // Section 5.2 step 6: + if (resolvedNoLatn.test(USCRIPT_HAN_WITH_BOPOMOFO, status) + || resolvedNoLatn.test(USCRIPT_JAPANESE, status) + || resolvedNoLatn.test(USCRIPT_KOREAN, status)) { + return USPOOF_HIGHLY_RESTRICTIVE; + } + + // Section 5.2 step 7: + if (!resolvedNoLatn.isEmpty() + && !resolvedNoLatn.test(USCRIPT_CYRILLIC, status) + && !resolvedNoLatn.test(USCRIPT_GREEK, status) + && !resolvedNoLatn.test(USCRIPT_CHEROKEE, status)) { + return USPOOF_MODERATELY_RESTRICTIVE; + } + + // Section 5.2 step 8: + return USPOOF_MINIMALLY_RESTRICTIVE; +} + +int32_t SpoofImpl::findHiddenOverlay(const UnicodeString& input, UErrorCode&) const { + bool sawLeadCharacter = false; + for (int32_t i=0; i<input.length();) { + UChar32 cp = input.char32At(i); + if (sawLeadCharacter && cp == 0x0307) { + return i; + } + uint8_t combiningClass = u_getCombiningClass(cp); + // Skip over characters except for those with combining class 0 (non-combining characters) or with + // combining class 230 (same class as U+0307) + U_ASSERT(u_getCombiningClass(0x0307) == 230); + if (combiningClass == 0 || combiningClass == 230) { + sawLeadCharacter = isIllegalCombiningDotLeadCharacter(cp); + } + i += U16_LENGTH(cp); + } + return -1; +} + +static inline bool isIllegalCombiningDotLeadCharacterNoLookup(UChar32 cp) { + return cp == u'i' || cp == u'j' || cp == u'ı' || cp == u'ȷ' || cp == u'l' || + u_hasBinaryProperty(cp, UCHAR_SOFT_DOTTED); +} + +bool SpoofImpl::isIllegalCombiningDotLeadCharacter(UChar32 cp) const { + if (isIllegalCombiningDotLeadCharacterNoLookup(cp)) { + return true; + } + UnicodeString skelStr; + fSpoofData->confusableLookup(cp, skelStr); + UChar32 finalCp = skelStr.char32At(skelStr.moveIndex32(skelStr.length(), -1)); + if (finalCp != cp && isIllegalCombiningDotLeadCharacterNoLookup(finalCp)) { + return true; + } + return false; +} + + + +// Convert a text format hex number. Utility function used by builder code. Static. +// Input: UChar *string text. Output: a UChar32 +// Input has been pre-checked, and will have no non-hex chars. +// The number must fall in the code point range of 0..0x10ffff +// Static Function. +UChar32 SpoofImpl::ScanHex(const UChar *s, int32_t start, int32_t limit, UErrorCode &status) { + if (U_FAILURE(status)) { + return 0; + } + U_ASSERT(limit-start > 0); + uint32_t val = 0; + int i; + for (i=start; i<limit; i++) { + int digitVal = s[i] - 0x30; + if (digitVal>9) { + digitVal = 0xa + (s[i] - 0x41); // Upper Case 'A' + } + if (digitVal>15) { + digitVal = 0xa + (s[i] - 0x61); // Lower Case 'a' + } + U_ASSERT(digitVal <= 0xf); + val <<= 4; + val += digitVal; + } + if (val > 0x10ffff) { + status = U_PARSE_ERROR; + val = 0; + } + return (UChar32)val; +} + + +//----------------------------------------- +// +// class CheckResult Implementation +// +//----------------------------------------- + +CheckResult::CheckResult() { + clear(); +} + +USpoofCheckResult* CheckResult::asUSpoofCheckResult() { + return exportForC(); +} + +// +// Incoming parameter check on Status and the CheckResult object +// received from the C API. +// +const CheckResult* CheckResult::validateThis(const USpoofCheckResult *ptr, UErrorCode &status) { + return validate(ptr, status); +} + +CheckResult* CheckResult::validateThis(USpoofCheckResult *ptr, UErrorCode &status) { + return validate(ptr, status); +} + +void CheckResult::clear() { + fChecks = 0; + fNumerics.clear(); + fRestrictionLevel = USPOOF_UNDEFINED_RESTRICTIVE; +} + +int32_t CheckResult::toCombinedBitmask(int32_t enabledChecks) { + if ((enabledChecks & USPOOF_AUX_INFO) != 0 && fRestrictionLevel != USPOOF_UNDEFINED_RESTRICTIVE) { + return fChecks | fRestrictionLevel; + } else { + return fChecks; + } +} + +CheckResult::~CheckResult() { +} + +//---------------------------------------------------------------------------------------------- +// +// class SpoofData Implementation +// +//---------------------------------------------------------------------------------------------- + + +UBool SpoofData::validateDataVersion(UErrorCode &status) const { + if (U_FAILURE(status) || + fRawData == NULL || + fRawData->fMagic != USPOOF_MAGIC || + fRawData->fFormatVersion[0] != USPOOF_CONFUSABLE_DATA_FORMAT_VERSION || + fRawData->fFormatVersion[1] != 0 || + fRawData->fFormatVersion[2] != 0 || + fRawData->fFormatVersion[3] != 0) { + status = U_INVALID_FORMAT_ERROR; + return FALSE; + } + return TRUE; +} + +static UBool U_CALLCONV +spoofDataIsAcceptable(void *context, + const char * /* type */, const char * /*name*/, + const UDataInfo *pInfo) { + if( + pInfo->size >= 20 && + pInfo->isBigEndian == U_IS_BIG_ENDIAN && + pInfo->charsetFamily == U_CHARSET_FAMILY && + pInfo->dataFormat[0] == 0x43 && // dataFormat="Cfu " + pInfo->dataFormat[1] == 0x66 && + pInfo->dataFormat[2] == 0x75 && + pInfo->dataFormat[3] == 0x20 && + pInfo->formatVersion[0] == USPOOF_CONFUSABLE_DATA_FORMAT_VERSION + ) { + UVersionInfo *version = static_cast<UVersionInfo *>(context); + if(version != NULL) { + uprv_memcpy(version, pInfo->dataVersion, 4); + } + return TRUE; + } else { + return FALSE; + } +} + +// Methods for the loading of the default confusables data file. The confusable +// data is loaded only when it is needed. +// +// SpoofData::getDefault() - Return the default confusables data, and call the +// initOnce() if it is not available. Adds a reference +// to the SpoofData that the caller is responsible for +// decrementing when they are done with the data. +// +// uspoof_loadDefaultData - Called once, from initOnce(). The resulting SpoofData +// is shared by all spoof checkers using the default data. +// +// uspoof_cleanupDefaultData - Called during cleanup. +// + +static UInitOnce gSpoofInitDefaultOnce = U_INITONCE_INITIALIZER; +static SpoofData* gDefaultSpoofData; + +static UBool U_CALLCONV +uspoof_cleanupDefaultData(void) { + if (gDefaultSpoofData) { + // Will delete, assuming all user-level spoof checkers were closed. + gDefaultSpoofData->removeReference(); + gDefaultSpoofData = nullptr; + gSpoofInitDefaultOnce.reset(); + } + return TRUE; +} + +static void U_CALLCONV uspoof_loadDefaultData(UErrorCode& status) { + UDataMemory *udm = udata_openChoice(nullptr, "cfu", "confusables", + spoofDataIsAcceptable, + nullptr, // context, would receive dataVersion if supplied. + &status); + if (U_FAILURE(status)) { return; } + gDefaultSpoofData = new SpoofData(udm, status); + if (U_FAILURE(status)) { + delete gDefaultSpoofData; + gDefaultSpoofData = nullptr; + return; + } + if (gDefaultSpoofData == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + ucln_i18n_registerCleanup(UCLN_I18N_SPOOFDATA, uspoof_cleanupDefaultData); +} + +SpoofData* SpoofData::getDefault(UErrorCode& status) { + umtx_initOnce(gSpoofInitDefaultOnce, &uspoof_loadDefaultData, status); + if (U_FAILURE(status)) { return NULL; } + gDefaultSpoofData->addReference(); + return gDefaultSpoofData; +} + + + +SpoofData::SpoofData(UDataMemory *udm, UErrorCode &status) +{ + reset(); + if (U_FAILURE(status)) { + return; + } + fUDM = udm; + // fRawData is non-const because it may be constructed by the data builder. + fRawData = reinterpret_cast<SpoofDataHeader *>( + const_cast<void *>(udata_getMemory(udm))); + validateDataVersion(status); + initPtrs(status); +} + + +SpoofData::SpoofData(const void *data, int32_t length, UErrorCode &status) +{ + reset(); + if (U_FAILURE(status)) { + return; + } + if ((size_t)length < sizeof(SpoofDataHeader)) { + status = U_INVALID_FORMAT_ERROR; + return; + } + if (data == NULL) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } + void *ncData = const_cast<void *>(data); + fRawData = static_cast<SpoofDataHeader *>(ncData); + if (length < fRawData->fLength) { + status = U_INVALID_FORMAT_ERROR; + return; + } + validateDataVersion(status); + initPtrs(status); +} + + +// Spoof Data constructor for use from data builder. +// Initializes a new, empty data area that will be populated later. +SpoofData::SpoofData(UErrorCode &status) { + reset(); + if (U_FAILURE(status)) { + return; + } + fDataOwned = true; + + // The spoof header should already be sized to be a multiple of 16 bytes. + // Just in case it's not, round it up. + uint32_t initialSize = (sizeof(SpoofDataHeader) + 15) & ~15; + U_ASSERT(initialSize == sizeof(SpoofDataHeader)); + + fRawData = static_cast<SpoofDataHeader *>(uprv_malloc(initialSize)); + fMemLimit = initialSize; + if (fRawData == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + uprv_memset(fRawData, 0, initialSize); + + fRawData->fMagic = USPOOF_MAGIC; + fRawData->fFormatVersion[0] = USPOOF_CONFUSABLE_DATA_FORMAT_VERSION; + fRawData->fFormatVersion[1] = 0; + fRawData->fFormatVersion[2] = 0; + fRawData->fFormatVersion[3] = 0; + initPtrs(status); +} + +// reset() - initialize all fields. +// Should be updated if any new fields are added. +// Called by constructors to put things in a known initial state. +void SpoofData::reset() { + fRawData = NULL; + fDataOwned = FALSE; + fUDM = NULL; + fMemLimit = 0; + fRefCount = 1; + fCFUKeys = NULL; + fCFUValues = NULL; + fCFUStrings = NULL; +} + + +// SpoofData::initPtrs() +// Initialize the pointers to the various sections of the raw data. +// +// This function is used both during the Trie building process (multiple +// times, as the individual data sections are added), and +// during the opening of a Spoof Checker from prebuilt data. +// +// The pointers for non-existent data sections (identified by an offset of 0) +// are set to NULL. +// +// Note: During building the data, adding each new data section +// reallocs the raw data area, which likely relocates it, which +// in turn requires reinitializing all of the pointers into it, hence +// multiple calls to this function during building. +// +void SpoofData::initPtrs(UErrorCode &status) { + fCFUKeys = NULL; + fCFUValues = NULL; + fCFUStrings = NULL; + if (U_FAILURE(status)) { + return; + } + if (fRawData->fCFUKeys != 0) { + fCFUKeys = (int32_t *)((char *)fRawData + fRawData->fCFUKeys); + } + if (fRawData->fCFUStringIndex != 0) { + fCFUValues = (uint16_t *)((char *)fRawData + fRawData->fCFUStringIndex); + } + if (fRawData->fCFUStringTable != 0) { + fCFUStrings = (UChar *)((char *)fRawData + fRawData->fCFUStringTable); + } +} + + +SpoofData::~SpoofData() { + if (fDataOwned) { + uprv_free(fRawData); + } + fRawData = NULL; + if (fUDM != NULL) { + udata_close(fUDM); + } + fUDM = NULL; +} + + +void SpoofData::removeReference() { + if (umtx_atomic_dec(&fRefCount) == 0) { + delete this; + } +} + + +SpoofData *SpoofData::addReference() { + umtx_atomic_inc(&fRefCount); + return this; +} + + +void *SpoofData::reserveSpace(int32_t numBytes, UErrorCode &status) { + if (U_FAILURE(status)) { + return NULL; + } + if (!fDataOwned) { + UPRV_UNREACHABLE_EXIT; + } + + numBytes = (numBytes + 15) & ~15; // Round up to a multiple of 16 + uint32_t returnOffset = fMemLimit; + fMemLimit += numBytes; + fRawData = static_cast<SpoofDataHeader *>(uprv_realloc(fRawData, fMemLimit)); + fRawData->fLength = fMemLimit; + uprv_memset((char *)fRawData + returnOffset, 0, numBytes); + initPtrs(status); + return (char *)fRawData + returnOffset; +} + +int32_t SpoofData::serialize(void *buf, int32_t capacity, UErrorCode &status) const { + int32_t dataSize = fRawData->fLength; + if (capacity < dataSize) { + status = U_BUFFER_OVERFLOW_ERROR; + return dataSize; + } + uprv_memcpy(buf, fRawData, dataSize); + return dataSize; +} + +int32_t SpoofData::size() const { + return fRawData->fLength; +} + +//------------------------------- +// +// Front-end APIs for SpoofData +// +//------------------------------- + +int32_t SpoofData::confusableLookup(UChar32 inChar, UnicodeString &dest) const { + // Perform a binary search. + // [lo, hi), i.e lo is inclusive, hi is exclusive. + // The result after the loop will be in lo. + int32_t lo = 0; + int32_t hi = length(); + do { + int32_t mid = (lo + hi) / 2; + if (codePointAt(mid) > inChar) { + hi = mid; + } else if (codePointAt(mid) < inChar) { + lo = mid; + } else { + // Found result. Break early. + lo = mid; + break; + } + } while (hi - lo > 1); + + // Did we find an entry? If not, the char maps to itself. + if (codePointAt(lo) != inChar) { + dest.append(inChar); + return 1; + } + + // Add the element to the string builder and return. + return appendValueTo(lo, dest); +} + +int32_t SpoofData::length() const { + return fRawData->fCFUKeysSize; +} + +UChar32 SpoofData::codePointAt(int32_t index) const { + return ConfusableDataUtils::keyToCodePoint(fCFUKeys[index]); +} + +int32_t SpoofData::appendValueTo(int32_t index, UnicodeString& dest) const { + int32_t stringLength = ConfusableDataUtils::keyToLength(fCFUKeys[index]); + + // Value is either a char (for strings of length 1) or + // an index into the string table (for longer strings) + uint16_t value = fCFUValues[index]; + if (stringLength == 1) { + dest.append((UChar)value); + } else { + dest.append(fCFUStrings + value, stringLength); + } + + return stringLength; +} + + +U_NAMESPACE_END + +U_NAMESPACE_USE + +//----------------------------------------------------------------------------- +// +// uspoof_swap - byte swap and char encoding swap of spoof data +// +//----------------------------------------------------------------------------- +U_CAPI int32_t U_EXPORT2 +uspoof_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, + UErrorCode *status) { + + if (status == NULL || U_FAILURE(*status)) { + return 0; + } + if(ds==NULL || inData==NULL || length<-1 || (length>0 && outData==NULL)) { + *status=U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + // + // Check that the data header is for spoof data. + // (Header contents are defined in gencfu.cpp) + // + const UDataInfo *pInfo = (const UDataInfo *)((const char *)inData+4); + if(!( pInfo->dataFormat[0]==0x43 && /* dataFormat="Cfu " */ + pInfo->dataFormat[1]==0x66 && + pInfo->dataFormat[2]==0x75 && + pInfo->dataFormat[3]==0x20 && + pInfo->formatVersion[0]==USPOOF_CONFUSABLE_DATA_FORMAT_VERSION && + pInfo->formatVersion[1]==0 && + pInfo->formatVersion[2]==0 && + pInfo->formatVersion[3]==0 )) { + udata_printError(ds, "uspoof_swap(): data format %02x.%02x.%02x.%02x " + "(format version %02x %02x %02x %02x) is not recognized\n", + pInfo->dataFormat[0], pInfo->dataFormat[1], + pInfo->dataFormat[2], pInfo->dataFormat[3], + pInfo->formatVersion[0], pInfo->formatVersion[1], + pInfo->formatVersion[2], pInfo->formatVersion[3]); + *status=U_UNSUPPORTED_ERROR; + return 0; + } + + // + // Swap the data header. (This is the generic ICU Data Header, not the uspoof Specific + // header). This swap also conveniently gets us + // the size of the ICU d.h., which lets us locate the start + // of the uspoof specific data. + // + int32_t headerSize=udata_swapDataHeader(ds, inData, length, outData, status); + + + // + // Get the Spoof Data Header, and check that it appears to be OK. + // + // + const uint8_t *inBytes =(const uint8_t *)inData+headerSize; + SpoofDataHeader *spoofDH = (SpoofDataHeader *)inBytes; + if (ds->readUInt32(spoofDH->fMagic) != USPOOF_MAGIC || + ds->readUInt32(spoofDH->fLength) < sizeof(SpoofDataHeader)) + { + udata_printError(ds, "uspoof_swap(): Spoof Data header is invalid.\n"); + *status=U_UNSUPPORTED_ERROR; + return 0; + } + + // + // Prefight operation? Just return the size + // + int32_t spoofDataLength = ds->readUInt32(spoofDH->fLength); + int32_t totalSize = headerSize + spoofDataLength; + if (length < 0) { + return totalSize; + } + + // + // Check that length passed in is consistent with length from Spoof data header. + // + if (length < totalSize) { + udata_printError(ds, "uspoof_swap(): too few bytes (%d after ICU Data header) for spoof data.\n", + spoofDataLength); + *status=U_INDEX_OUTOFBOUNDS_ERROR; + return 0; + } + + + // + // Swap the Data. Do the data itself first, then the Spoof Data Header, because + // we need to reference the header to locate the data, and an + // inplace swap of the header leaves it unusable. + // + uint8_t *outBytes = (uint8_t *)outData + headerSize; + SpoofDataHeader *outputDH = (SpoofDataHeader *)outBytes; + + int32_t sectionStart; + int32_t sectionLength; + + // + // If not swapping in place, zero out the output buffer before starting. + // Gaps may exist between the individual sections, and these must be zeroed in + // the output buffer. The simplest way to do that is to just zero the whole thing. + // + if (inBytes != outBytes) { + uprv_memset(outBytes, 0, spoofDataLength); + } + + // Confusables Keys Section (fCFUKeys) + sectionStart = ds->readUInt32(spoofDH->fCFUKeys); + sectionLength = ds->readUInt32(spoofDH->fCFUKeysSize) * 4; + ds->swapArray32(ds, inBytes+sectionStart, sectionLength, outBytes+sectionStart, status); + + // String Index Section + sectionStart = ds->readUInt32(spoofDH->fCFUStringIndex); + sectionLength = ds->readUInt32(spoofDH->fCFUStringIndexSize) * 2; + ds->swapArray16(ds, inBytes+sectionStart, sectionLength, outBytes+sectionStart, status); + + // String Table Section + sectionStart = ds->readUInt32(spoofDH->fCFUStringTable); + sectionLength = ds->readUInt32(spoofDH->fCFUStringTableLen) * 2; + ds->swapArray16(ds, inBytes+sectionStart, sectionLength, outBytes+sectionStart, status); + + // And, last, swap the header itself. + // int32_t fMagic // swap this + // uint8_t fFormatVersion[4] // Do not swap this, just copy + // int32_t fLength and all the rest // Swap the rest, all is 32 bit stuff. + // + uint32_t magic = ds->readUInt32(spoofDH->fMagic); + ds->writeUInt32((uint32_t *)&outputDH->fMagic, magic); + + if (outputDH->fFormatVersion != spoofDH->fFormatVersion) { + uprv_memcpy(outputDH->fFormatVersion, spoofDH->fFormatVersion, sizeof(spoofDH->fFormatVersion)); + } + // swap starting at fLength + ds->swapArray32(ds, &spoofDH->fLength, sizeof(SpoofDataHeader)-8 /* minus magic and fFormatVersion[4] */, &outputDH->fLength, status); + + return totalSize; +} + +#endif + + diff --git a/thirdparty/icu4c/i18n/uspoof_impl.h b/thirdparty/icu4c/i18n/uspoof_impl.h new file mode 100644 index 0000000000..e75ae262bd --- /dev/null +++ b/thirdparty/icu4c/i18n/uspoof_impl.h @@ -0,0 +1,343 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +*************************************************************************** +* Copyright (C) 2008-2013, International Business Machines Corporation +* and others. All Rights Reserved. +*************************************************************************** +* +* uspoof_impl.h +* +* Implementation header for spoof detection +* +*/ + +#ifndef USPOOFIM_H +#define USPOOFIM_H + +#include "uassert.h" +#include "unicode/utypes.h" +#include "unicode/uspoof.h" +#include "unicode/uscript.h" +#include "unicode/udata.h" +#include "udataswp.h" +#include "utrie2.h" + +#if !UCONFIG_NO_NORMALIZATION + +#ifdef __cplusplus + +#include "capi_helper.h" + +U_NAMESPACE_BEGIN + +// The maximum length (in UTF-16 UChars) of the skeleton replacement string resulting from +// a single input code point. This is function of the unicode.org data. +#define USPOOF_MAX_SKELETON_EXPANSION 20 + +// The default stack buffer size for copies or conversions or normalizations +// of input strings being checked. (Used in multiple places.) +#define USPOOF_STACK_BUFFER_SIZE 100 + +// Magic number for sanity checking spoof data. +#define USPOOF_MAGIC 0x3845fdef + +// Magic number for sanity checking spoof checkers. +#define USPOOF_CHECK_MAGIC 0x2734ecde + +class ScriptSet; +class SpoofData; +struct SpoofDataHeader; +class ConfusableDataUtils; + +/** + * Class SpoofImpl corresponds directly to the plain C API opaque type + * USpoofChecker. One can be cast to the other. + */ +class SpoofImpl : public UObject, + public IcuCApiHelper<USpoofChecker, SpoofImpl, USPOOF_MAGIC> { +public: + SpoofImpl(SpoofData *data, UErrorCode& status); + SpoofImpl(UErrorCode& status); + SpoofImpl(); + void construct(UErrorCode& status); + virtual ~SpoofImpl(); + + /** Copy constructor, used by the user level uspoof_clone() function. + */ + SpoofImpl(const SpoofImpl &src, UErrorCode &status); + + USpoofChecker *asUSpoofChecker(); + static SpoofImpl *validateThis(USpoofChecker *sc, UErrorCode &status); + static const SpoofImpl *validateThis(const USpoofChecker *sc, UErrorCode &status); + + /** Set and Get AllowedLocales, implementations of the corresponding API */ + void setAllowedLocales(const char *localesList, UErrorCode &status); + const char * getAllowedLocales(UErrorCode &status); + + // Add (union) to the UnicodeSet all of the characters for the scripts used for + // the specified locale. Part of the implementation of setAllowedLocales. + void addScriptChars(const char *locale, UnicodeSet *allowedChars, UErrorCode &status); + + // Functions implementing the features of UTS 39 section 5. + static void getAugmentedScriptSet(UChar32 codePoint, ScriptSet& result, UErrorCode& status); + void getResolvedScriptSet(const UnicodeString& input, ScriptSet& result, UErrorCode& status) const; + void getResolvedScriptSetWithout(const UnicodeString& input, UScriptCode script, ScriptSet& result, UErrorCode& status) const; + void getNumerics(const UnicodeString& input, UnicodeSet& result, UErrorCode& status) const; + URestrictionLevel getRestrictionLevel(const UnicodeString& input, UErrorCode& status) const; + + int32_t findHiddenOverlay(const UnicodeString& input, UErrorCode& status) const; + bool isIllegalCombiningDotLeadCharacter(UChar32 cp) const; + + /** parse a hex number. Untility used by the builders. */ + static UChar32 ScanHex(const UChar *s, int32_t start, int32_t limit, UErrorCode &status); + + static UClassID U_EXPORT2 getStaticClassID(void); + virtual UClassID getDynamicClassID(void) const override; + + // + // Data Members + // + + int32_t fChecks; // Bit vector of checks to perform. + + SpoofData *fSpoofData; + + const UnicodeSet *fAllowedCharsSet; // The UnicodeSet of allowed characters. + // for this Spoof Checker. Defaults to all chars. + + const char *fAllowedLocales; // The list of allowed locales. + URestrictionLevel fRestrictionLevel; // The maximum restriction level for an acceptable identifier. +}; + +/** + * Class CheckResult corresponds directly to the plain C API opaque type + * USpoofCheckResult. One can be cast to the other. + */ +class CheckResult : public UObject, + public IcuCApiHelper<USpoofCheckResult, CheckResult, USPOOF_CHECK_MAGIC> { +public: + CheckResult(); + virtual ~CheckResult(); + + USpoofCheckResult *asUSpoofCheckResult(); + static CheckResult *validateThis(USpoofCheckResult *ptr, UErrorCode &status); + static const CheckResult *validateThis(const USpoofCheckResult *ptr, UErrorCode &status); + + void clear(); + + // Used to convert this CheckResult to the older int32_t return value API + int32_t toCombinedBitmask(int32_t expectedChecks); + + // Data Members + int32_t fChecks; // Bit vector of checks that were failed. + UnicodeSet fNumerics; // Set of numerics found in the string. + URestrictionLevel fRestrictionLevel; // The restriction level of the string. +}; + + +// +// Confusable Mappings Data Structures, version 2.0 +// +// For the confusable data, we are essentially implementing a map, +// key: a code point +// value: a string. Most commonly one char in length, but can be more. +// +// The keys are stored as a sorted array of 32 bit ints. +// bits 0-23 a code point value +// bits 24-31 length of value string, in UChars (between 1 and 256 UChars). +// The key table is sorted in ascending code point order. (not on the +// 32 bit int value, the flag bits do not participate in the sorting.) +// +// Lookup is done by means of a binary search in the key table. +// +// The corresponding values are kept in a parallel array of 16 bit ints. +// If the value string is of length 1, it is literally in the value array. +// For longer strings, the value array contains an index into the strings table. +// +// String Table: +// The strings table contains all of the value strings (those of length two or greater) +// concatenated together into one long UChar (UTF-16) array. +// +// There is no nul character or other mark between adjacent strings. +// +//---------------------------------------------------------------------------- +// +// Changes from format version 1 to format version 2: +// 1) Removal of the whole-script confusable data tables. +// 2) Removal of the SL/SA/ML/MA and multi-table flags in the key bitmask. +// 3) Expansion of string length value in the key bitmask from 2 bits to 8 bits. +// 4) Removal of the string lengths table since 8 bits is sufficient for the +// lengths of all entries in confusables.txt. + + + +// Internal functions for manipulating confusable data table keys +#define USPOOF_CONFUSABLE_DATA_FORMAT_VERSION 2 // version for ICU 58 +class ConfusableDataUtils { +public: + inline static UChar32 keyToCodePoint(int32_t key) { + return key & 0x00ffffff; + } + inline static int32_t keyToLength(int32_t key) { + return ((key & 0xff000000) >> 24) + 1; + } + inline static int32_t codePointAndLengthToKey(UChar32 codePoint, int32_t length) { + U_ASSERT((codePoint & 0x00ffffff) == codePoint); + U_ASSERT(length <= 256); + return codePoint | ((length - 1) << 24); + } +}; + + +//------------------------------------------------------------------------------------- +// +// SpoofData +// +// A small class that wraps the raw (usually memory mapped) spoof data. +// Serves two primary functions: +// 1. Convenience. Contains real pointers to the data, to avoid dealing with +// the offsets in the raw data. +// 2. Reference counting. When a spoof checker is cloned, the raw data is shared +// and must be retained until all checkers using the data are closed. +// Nothing in this struct includes state that is specific to any particular +// USpoofDetector object. +// +//--------------------------------------------------------------------------------------- +class SpoofData: public UMemory { + public: + static SpoofData* getDefault(UErrorCode &status); // Get standard ICU spoof data. + static void releaseDefault(); // Cleanup reference to default spoof data. + + SpoofData(UErrorCode &status); // Create new spoof data wrapper. + // Only used when building new data from rules. + + // Constructor for use when creating from prebuilt default data. + // A UDataMemory is what the ICU internal data loading functions provide. + // The udm is adopted by the SpoofData. + SpoofData(UDataMemory *udm, UErrorCode &status); + + // Constructor for use when creating from serialized data. + // + SpoofData(const void *serializedData, int32_t length, UErrorCode &status); + + // Check raw Spoof Data Version compatibility. + // Return true it looks good. + UBool validateDataVersion(UErrorCode &status) const; + + ~SpoofData(); // Destructor not normally used. + // Use removeReference() instead. + // Reference Counting functions. + // Clone of a user-level spoof detector increments the ref count on the data. + // Close of a user-level spoof detector decrements the ref count. + // If the data is owned by us, it will be deleted when count goes to zero. + SpoofData *addReference(); + void removeReference(); + + // Reset all fields to an initial state. + // Called from the top of all constructors. + void reset(); + + // Copy this instance's raw data buffer to the specified address. + int32_t serialize(void *buf, int32_t capacity, UErrorCode &status) const; + + // Get the total number of bytes of data backed by this SpoofData. + // Not to be confused with length, which returns the number of confusable entries. + int32_t size() const; + + // Get the confusable skeleton transform for a single code point. + // The result is a string with a length between 1 and 18 as of Unicode 9. + // This is the main public endpoint for this class. + // @return The length in UTF-16 code units of the substitution string. + int32_t confusableLookup(UChar32 inChar, UnicodeString &dest) const; + + // Get the number of confusable entries in this SpoofData. + int32_t length() const; + + // Get the code point (key) at the specified index. + UChar32 codePointAt(int32_t index) const; + + // Get the confusable skeleton (value) at the specified index. + // Append it to the specified UnicodeString&. + // @return The length in UTF-16 code units of the skeleton string. + int32_t appendValueTo(int32_t index, UnicodeString& dest) const; + + private: + // Reserve space in the raw data. For use by builder when putting together a + // new set of data. Init the new storage to zero, to prevent inconsistent + // results if it is not all otherwise set by the requester. + // Return: + // pointer to the new space that was added by this function. + void *reserveSpace(int32_t numBytes, UErrorCode &status); + + // initialize the pointers from this object to the raw data. + void initPtrs(UErrorCode &status); + + SpoofDataHeader *fRawData; // Ptr to the raw memory-mapped data + UBool fDataOwned; // True if the raw data is owned, and needs + // to be deleted when refcount goes to zero. + UDataMemory *fUDM; // If not NULL, our data came from a + // UDataMemory, which we must close when + // we are done. + + uint32_t fMemLimit; // Limit of available raw data space + u_atomic_int32_t fRefCount; + + // Confusable data + int32_t *fCFUKeys; + uint16_t *fCFUValues; + UChar *fCFUStrings; + + friend class ConfusabledataBuilder; +}; + +//--------------------------------------------------------------------------------------- +// +// Raw Binary Data Formats, as loaded from the ICU data file, +// or as built by the builder. +// +//--------------------------------------------------------------------------------------- +struct SpoofDataHeader { + int32_t fMagic; // (0x3845fdef) + uint8_t fFormatVersion[4]; // Data Format. Same as the value in struct UDataInfo + // if there is one associated with this data. + int32_t fLength; // Total length in bytes of this spoof data, + // including all sections, not just the header. + + // The following four sections refer to data representing the confusable data + // from the Unicode.org data from "confusables.txt" + + int32_t fCFUKeys; // byte offset to Keys table (from SpoofDataHeader *) + int32_t fCFUKeysSize; // number of entries in keys table (32 bits each) + + // TODO: change name to fCFUValues, for consistency. + int32_t fCFUStringIndex; // byte offset to String Indexes table + int32_t fCFUStringIndexSize; // number of entries in String Indexes table (16 bits each) + // (number of entries must be same as in Keys table + + int32_t fCFUStringTable; // byte offset of String table + int32_t fCFUStringTableLen; // length of string table (in 16 bit UChars) + + // The following sections are for data from xidmodifications.txt + + int32_t unused[15]; // Padding, Room for Expansion +}; + + + +U_NAMESPACE_END +#endif /* __cplusplus */ + +/** + * Endianness swap function for binary spoof data. + * @internal + */ +U_CAPI int32_t U_EXPORT2 +uspoof_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, + UErrorCode *status); + + +#endif + +#endif /* USPOOFIM_H */ + diff --git a/thirdparty/icu4c/icudt71l.dat b/thirdparty/icu4c/icudt71l.dat Binary files differindex 4c2c1c4d16..3fa3af9c23 100644 --- a/thirdparty/icu4c/icudt71l.dat +++ b/thirdparty/icu4c/icudt71l.dat diff --git a/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h b/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h index c15736e255..ae81f141c4 100644 --- a/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h +++ b/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h @@ -70,6 +70,7 @@ typedef enum SpvSourceLanguage_ { SpvSourceLanguageOpenCL_CPP = 4, SpvSourceLanguageHLSL = 5, SpvSourceLanguageCPP_for_OpenCL = 6, + SpvSourceLanguageSYCL = 7, SpvSourceLanguageMax = 0x7fffffff, } SpvSourceLanguage; @@ -184,6 +185,7 @@ typedef enum SpvExecutionMode_ { SpvExecutionModeNoGlobalOffsetINTEL = 5895, SpvExecutionModeNumSIMDWorkitemsINTEL = 5896, SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, + SpvExecutionModeNamedBarrierCountINTEL = 6417, SpvExecutionModeMax = 0x7fffffff, } SpvExecutionMode; @@ -546,6 +548,8 @@ typedef enum SpvDecoration_ { SpvDecorationPrefetchINTEL = 5902, SpvDecorationStallEnableINTEL = 5905, SpvDecorationFuseLoopsInFunctionINTEL = 5907, + SpvDecorationAliasScopeINTEL = 5914, + SpvDecorationNoAliasINTEL = 5915, SpvDecorationBufferLocationINTEL = 5921, SpvDecorationIOPipeStorageINTEL = 5944, SpvDecorationFunctionFloatingPointModeINTEL = 6080, @@ -677,6 +681,7 @@ typedef enum SpvBuiltIn_ { SpvBuiltInSMCountNV = 5375, SpvBuiltInWarpIDNV = 5376, SpvBuiltInSMIDNV = 5377, + SpvBuiltInCullMaskKHR = 6021, SpvBuiltInMax = 0x7fffffff, } SpvBuiltIn; @@ -804,6 +809,8 @@ typedef enum SpvMemoryAccessShift_ { SpvMemoryAccessMakePointerVisibleKHRShift = 4, SpvMemoryAccessNonPrivatePointerShift = 5, SpvMemoryAccessNonPrivatePointerKHRShift = 5, + SpvMemoryAccessAliasScopeINTELMaskShift = 16, + SpvMemoryAccessNoAliasINTELMaskShift = 17, SpvMemoryAccessMax = 0x7fffffff, } SpvMemoryAccessShift; @@ -818,6 +825,8 @@ typedef enum SpvMemoryAccessMask_ { SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010, SpvMemoryAccessNonPrivatePointerMask = 0x00000020, SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020, + SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000, + SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000, } SpvMemoryAccessMask; typedef enum SpvScope_ { @@ -1059,6 +1068,7 @@ typedef enum SpvCapability_ { SpvCapabilityFPGAMemoryAccessesINTEL = 5898, SpvCapabilityFPGAClusterAttributesINTEL = 5904, SpvCapabilityLoopFuseINTEL = 5906, + SpvCapabilityMemoryAccessAliasingINTEL = 5910, SpvCapabilityFPGABufferLocationINTEL = 5920, SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922, SpvCapabilityUSMStorageClassesINTEL = 5935, @@ -1073,13 +1083,17 @@ typedef enum SpvCapability_ { SpvCapabilityDotProductInput4x8BitPackedKHR = 6018, SpvCapabilityDotProduct = 6019, SpvCapabilityDotProductKHR = 6019, + SpvCapabilityRayCullMaskKHR = 6020, SpvCapabilityBitInstructions = 6025, + SpvCapabilityGroupNonUniformRotateKHR = 6026, SpvCapabilityAtomicFloat32AddEXT = 6033, SpvCapabilityAtomicFloat64AddEXT = 6034, SpvCapabilityLongConstantCompositeINTEL = 6089, SpvCapabilityOptNoneINTEL = 6094, SpvCapabilityAtomicFloat16AddEXT = 6095, SpvCapabilityDebugInfoModuleINTEL = 6114, + SpvCapabilitySplitBarrierINTEL = 6141, + SpvCapabilityGroupUniformArithmeticKHR = 6400, SpvCapabilityMax = 0x7fffffff, } SpvCapability; @@ -1535,6 +1549,7 @@ typedef enum SpvOp_ { SpvOpSubgroupAllKHR = 4428, SpvOpSubgroupAnyKHR = 4429, SpvOpSubgroupAllEqualKHR = 4430, + SpvOpGroupNonUniformRotateKHR = 4431, SpvOpSubgroupReadInvocationKHR = 4432, SpvOpTraceRayKHR = 4445, SpvOpExecuteCallableKHR = 4446, @@ -1801,6 +1816,9 @@ typedef enum SpvOp_ { SpvOpArbitraryFloatPowRINTEL = 5881, SpvOpArbitraryFloatPowNINTEL = 5882, SpvOpLoopControlINTEL = 5887, + SpvOpAliasDomainDeclINTEL = 5911, + SpvOpAliasScopeDeclINTEL = 5912, + SpvOpAliasScopeListDeclINTEL = 5913, SpvOpFixedSqrtINTEL = 5923, SpvOpFixedRecipINTEL = 5924, SpvOpFixedRsqrtINTEL = 5925, @@ -1839,10 +1857,23 @@ typedef enum SpvOp_ { SpvOpTypeStructContinuedINTEL = 6090, SpvOpConstantCompositeContinuedINTEL = 6091, SpvOpSpecConstantCompositeContinuedINTEL = 6092, + SpvOpControlBarrierArriveINTEL = 6142, + SpvOpControlBarrierWaitINTEL = 6143, + SpvOpGroupIMulKHR = 6401, + SpvOpGroupFMulKHR = 6402, + SpvOpGroupBitwiseAndKHR = 6403, + SpvOpGroupBitwiseOrKHR = 6404, + SpvOpGroupBitwiseXorKHR = 6405, + SpvOpGroupLogicalAndKHR = 6406, + SpvOpGroupLogicalOrKHR = 6407, + SpvOpGroupLogicalXorKHR = 6408, SpvOpMax = 0x7fffffff, } SpvOp; #ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include <stdbool.h> +#endif inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) { *hasResult = *hasResultType = false; switch (opcode) { @@ -2197,6 +2228,7 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break; case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; @@ -2452,6 +2484,9 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; @@ -2490,9 +2525,18 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; } } #endif /* SPV_ENABLE_UTILITY_CODE */ #endif - diff --git a/thirdparty/spirv-reflect/patches/specialization-constants.patch b/thirdparty/spirv-reflect/patches/specialization-constants.patch index 9bb5f97cd3..99815c9162 100644 --- a/thirdparty/spirv-reflect/patches/specialization-constants.patch +++ b/thirdparty/spirv-reflect/patches/specialization-constants.patch @@ -1,8 +1,8 @@ diff --git a/thirdparty/spirv-reflect/spirv_reflect.c b/thirdparty/spirv-reflect/spirv_reflect.c -index e9b11bf495..f181df5fa2 100644 +index cdcf3ca663..c174ae1900 100644 --- a/thirdparty/spirv-reflect/spirv_reflect.c +++ b/thirdparty/spirv-reflect/spirv_reflect.c -@@ -125,6 +125,9 @@ typedef struct SpvReflectPrvDecorations { +@@ -126,6 +126,9 @@ typedef struct SpvReflectPrvDecorations { SpvReflectPrvNumberDecoration location; SpvReflectPrvNumberDecoration offset; SpvReflectPrvNumberDecoration uav_counter_buffer; @@ -12,7 +12,7 @@ index e9b11bf495..f181df5fa2 100644 SpvReflectPrvStringDecoration semantic; uint32_t array_stride; uint32_t matrix_stride; -@@ -631,6 +634,9 @@ static SpvReflectResult ParseNodes(SpvReflectPrvParser* p_parser) +@@ -639,6 +642,9 @@ static SpvReflectResult ParseNodes(SpvReflectPrvParser* p_parser) p_parser->nodes[i].decorations.offset.value = (uint32_t)INVALID_VALUE; p_parser->nodes[i].decorations.uav_counter_buffer.value = (uint32_t)INVALID_VALUE; p_parser->nodes[i].decorations.built_in = (SpvBuiltIn)INVALID_VALUE; @@ -22,7 +22,7 @@ index e9b11bf495..f181df5fa2 100644 } // Mark source file id node p_parser->source_file_id = (uint32_t)INVALID_VALUE; -@@ -821,10 +827,16 @@ static SpvReflectResult ParseNodes(SpvReflectPrvParser* p_parser) +@@ -829,10 +835,16 @@ static SpvReflectResult ParseNodes(SpvReflectPrvParser* p_parser) CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id); } break; @@ -41,7 +41,7 @@ index e9b11bf495..f181df5fa2 100644 case SpvOpSpecConstantComposite: case SpvOpSpecConstantOp: { CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id); -@@ -856,7 +868,7 @@ static SpvReflectResult ParseNodes(SpvReflectPrvParser* p_parser) +@@ -864,7 +876,7 @@ static SpvReflectResult ParseNodes(SpvReflectPrvParser* p_parser) CHECKED_READU32(p_parser, p_node->word_offset + 3, p_access_chain->base_id); // // SPIRV_ACCESS_CHAIN_INDEX_OFFSET (4) is the number of words up until the first index: @@ -50,7 +50,7 @@ index e9b11bf495..f181df5fa2 100644 // p_access_chain->index_count = (node_word_count - SPIRV_ACCESS_CHAIN_INDEX_OFFSET); if (p_access_chain->index_count > 0) { -@@ -1338,6 +1350,9 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) +@@ -1346,6 +1358,9 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) skip = true; } break; @@ -60,7 +60,7 @@ index e9b11bf495..f181df5fa2 100644 case SpvDecorationRelaxedPrecision: case SpvDecorationBlock: case SpvDecorationBufferBlock: -@@ -1481,7 +1496,14 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) +@@ -1495,7 +1510,14 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) p_target_decorations->input_attachment_index.word_offset = word_offset; } break; @@ -76,7 +76,7 @@ index e9b11bf495..f181df5fa2 100644 case SpvReflectDecorationHlslCounterBufferGOOGLE: { uint32_t word_offset = p_node->word_offset + member_offset+ 3; CHECKED_READU32(p_parser, word_offset, p_target_decorations->uav_counter_buffer.value); -@@ -1789,6 +1811,13 @@ static SpvReflectResult ParseType( +@@ -1803,6 +1825,13 @@ static SpvReflectResult ParseType( p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE; } break; @@ -90,7 +90,7 @@ index e9b11bf495..f181df5fa2 100644 } if (result == SPV_REFLECT_RESULT_SUCCESS) { -@@ -3269,6 +3298,69 @@ static SpvReflectResult ParseExecutionModes( +@@ -3332,6 +3361,69 @@ static SpvReflectResult ParseExecutionModes( return SPV_REFLECT_RESULT_SUCCESS; } @@ -160,7 +160,7 @@ index e9b11bf495..f181df5fa2 100644 static SpvReflectResult ParsePushConstantBlocks( SpvReflectPrvParser* p_parser, SpvReflectShaderModule* p_module) -@@ -3650,6 +3742,12 @@ static SpvReflectResult CreateShaderModule( +@@ -3717,6 +3809,12 @@ static SpvReflectResult CreateShaderModule( result = ParsePushConstantBlocks(&parser, p_module); SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } @@ -173,8 +173,8 @@ index e9b11bf495..f181df5fa2 100644 if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseEntryPoints(&parser, p_module); SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); -@@ -3807,6 +3905,9 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module) - SafeFree(p_entry->used_push_constants); +@@ -3875,6 +3973,9 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module) + SafeFree(p_entry->execution_modes); } SafeFree(p_module->entry_points); +// -- GODOT begin -- @@ -183,7 +183,7 @@ index e9b11bf495..f181df5fa2 100644 // Push constants for (size_t i = 0; i < p_module->push_constant_block_count; ++i) { -@@ -4077,6 +4178,38 @@ SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables( +@@ -4145,6 +4246,38 @@ SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables( return SPV_REFLECT_RESULT_SUCCESS; } @@ -223,10 +223,10 @@ index e9b11bf495..f181df5fa2 100644 const SpvReflectShaderModule* p_module, uint32_t* p_count, diff --git a/thirdparty/spirv-reflect/spirv_reflect.h b/thirdparty/spirv-reflect/spirv_reflect.h -index e9e4c40755..948533d3c0 100644 +index 02b81613a1..02850f8811 100644 --- a/thirdparty/spirv-reflect/spirv_reflect.h +++ b/thirdparty/spirv-reflect/spirv_reflect.h -@@ -323,6 +323,28 @@ typedef struct SpvReflectTypeDescription { +@@ -329,6 +329,28 @@ typedef struct SpvReflectTypeDescription { struct SpvReflectTypeDescription* members; } SpvReflectTypeDescription; @@ -255,7 +255,7 @@ index e9e4c40755..948533d3c0 100644 /*! @struct SpvReflectInterfaceVariable -@@ -472,6 +494,10 @@ typedef struct SpvReflectShaderModule { +@@ -483,6 +505,10 @@ typedef struct SpvReflectShaderModule { SpvReflectInterfaceVariable* interface_variables; // Uses value(s) from first entry point uint32_t push_constant_block_count; // Uses value(s) from first entry point SpvReflectBlockVariable* push_constant_blocks; // Uses value(s) from first entry point @@ -266,7 +266,7 @@ index e9e4c40755..948533d3c0 100644 struct Internal { SpvReflectModuleFlags module_flags; -@@ -744,6 +770,33 @@ SpvReflectResult spvReflectEnumerateInputVariables( +@@ -755,6 +781,33 @@ SpvReflectResult spvReflectEnumerateInputVariables( SpvReflectInterfaceVariable** pp_variables ); diff --git a/thirdparty/spirv-reflect/spirv_reflect.c b/thirdparty/spirv-reflect/spirv_reflect.c index f181df5fa2..c174ae1900 100644 --- a/thirdparty/spirv-reflect/spirv_reflect.c +++ b/thirdparty/spirv-reflect/spirv_reflect.c @@ -119,6 +119,7 @@ typedef struct SpvReflectPrvDecorations { bool is_noperspective; bool is_flat; bool is_non_writable; + bool is_non_readable; SpvReflectPrvNumberDecoration set; SpvReflectPrvNumberDecoration binding; SpvReflectPrvNumberDecoration input_attachment_index; @@ -306,7 +307,12 @@ static SpvReflectResult IntersectSortedUint32( size_t* res_size ) { + *pp_res = NULL; *res_size = 0; + if (IsNull(p_arr0) || IsNull(p_arr1)) { + return SPV_REFLECT_RESULT_SUCCESS; + } + const uint32_t* arr0_end = p_arr0 + arr0_size; const uint32_t* arr1_end = p_arr1 + arr1_size; @@ -324,7 +330,6 @@ static SpvReflectResult IntersectSortedUint32( } } - *pp_res = NULL; if (*res_size > 0) { *pp_res = (uint32_t*)calloc(*res_size, sizeof(**pp_res)); if (IsNull(*pp_res)) { @@ -488,6 +493,9 @@ static SpvReflectDecorationFlags ApplyDecorations(const SpvReflectPrvDecorations if (p_decoration_fields->is_non_writable) { decorations |= SPV_REFLECT_DECORATION_NON_WRITABLE; } + if (p_decoration_fields->is_non_readable) { + decorations |= SPV_REFLECT_DECORATION_NON_READABLE; + } return decorations; } @@ -1364,6 +1372,7 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) case SpvDecorationNoPerspective: case SpvDecorationFlat: case SpvDecorationNonWritable: + case SpvDecorationNonReadable: case SpvDecorationLocation: case SpvDecorationBinding: case SpvDecorationDescriptorSet: @@ -1462,6 +1471,11 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) } break; + case SpvDecorationNonReadable: { + p_target_decorations->is_non_readable = true; + } + break; + case SpvDecorationLocation: { uint32_t word_offset = p_node->word_offset + member_offset + 3; CHECKED_READU32(p_parser, word_offset, p_target_decorations->location.value); @@ -1970,6 +1984,7 @@ static SpvReflectResult ParseDescriptorBindings( p_descriptor->count = 1; p_descriptor->uav_counter_id = p_node->decorations.uav_counter_buffer.value; p_descriptor->type_description = p_type; + p_descriptor->decoration_flags = ApplyDecorations(&p_node->decorations); // If this is in the StorageBuffer storage class, it's for sure a storage // buffer descriptor. We need to handle this case earlier because in SPIR-V @@ -3208,8 +3223,8 @@ static SpvReflectResult ParseExecutionModes( // Read entry point id uint32_t entry_point_id = 0; CHECKED_READU32(p_parser, p_node->word_offset + 1, entry_point_id); - - // Find entry point + + // Find entry point SpvReflectEntryPoint* p_entry_point = NULL; for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) { if (p_module->entry_points[entry_point_idx].id == entry_point_id) { @@ -3221,7 +3236,7 @@ static SpvReflectResult ParseExecutionModes( if (IsNull(p_entry_point)) { return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT; } - + // Read execution mode uint32_t execution_mode = (uint32_t)INVALID_VALUE; CHECKED_READU32(p_parser, p_node->word_offset + 2, execution_mode); @@ -3288,12 +3303,60 @@ static SpvReflectResult ParseExecutionModes( case SpvExecutionModeLocalSizeId: case SpvExecutionModeLocalSizeHintId: case SpvExecutionModePostDepthCoverage: + case SpvExecutionModeDenormPreserve: + case SpvExecutionModeDenormFlushToZero: + case SpvExecutionModeSignedZeroInfNanPreserve: + case SpvExecutionModeRoundingModeRTE: + case SpvExecutionModeRoundingModeRTZ: case SpvExecutionModeStencilRefReplacingEXT: + case SpvExecutionModeOutputLinesNV: case SpvExecutionModeOutputPrimitivesNV: case SpvExecutionModeOutputTrianglesNV: break; } + p_entry_point->execution_mode_count++; + } + uint32_t* indices = (uint32_t*)calloc(p_module->entry_point_count, sizeof(indices)); + if (IsNull(indices)) { + return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; } + for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) { + SpvReflectEntryPoint* p_entry_point = &p_module->entry_points[entry_point_idx]; + p_entry_point->execution_modes = + (SpvExecutionMode*)calloc(p_entry_point->execution_mode_count, sizeof(*p_entry_point->execution_modes)); + if (IsNull(p_entry_point->execution_modes)) { + SafeFree(indices); + return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; + } + } + + for (size_t node_idx = 0; node_idx < p_parser->node_count; ++node_idx) { + SpvReflectPrvNode* p_node = &(p_parser->nodes[node_idx]); + if (p_node->op != SpvOpExecutionMode) { + continue; + } + + // Read entry point id + uint32_t entry_point_id = 0; + CHECKED_READU32(p_parser, p_node->word_offset + 1, entry_point_id); + + // Find entry point + SpvReflectEntryPoint* p_entry_point = NULL; + uint32_t* idx = NULL; + for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) { + if (p_module->entry_points[entry_point_idx].id == entry_point_id) { + p_entry_point = &p_module->entry_points[entry_point_idx]; + idx = &indices[entry_point_idx]; + break; + } + } + + // Read execution mode + uint32_t execution_mode = (uint32_t)INVALID_VALUE; + CHECKED_READU32(p_parser, p_node->word_offset + 2, execution_mode); + p_entry_point->execution_modes[(*idx)++] = (SpvExecutionMode)execution_mode; + } + SafeFree(indices); } return SPV_REFLECT_RESULT_SUCCESS; } @@ -3649,7 +3712,11 @@ static SpvReflectResult CreateShaderModule( if (flags & SPV_REFLECT_MODULE_FLAG_NO_COPY) { // Set internal size and pointer to args passed in p_module->_internal->spirv_size = size; +#if defined(__cplusplus) + p_module->_internal->spirv_code = const_cast<uint32_t*>(static_cast<const uint32_t*>(p_code)); // cast that const away +#else p_module->_internal->spirv_code = (void*)p_code; // cast that const away +#endif p_module->_internal->spirv_word_count = (uint32_t)(size / SPIRV_WORD_SIZE); } else { @@ -3903,6 +3970,7 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module) SafeFree(p_entry->interface_variables); SafeFree(p_entry->used_uniforms); SafeFree(p_entry->used_push_constants); + SafeFree(p_entry->execution_modes); } SafeFree(p_module->entry_points); // -- GODOT begin -- @@ -5093,6 +5161,7 @@ const char* spvReflectSourceLanguage(SpvSourceLanguage source_lang) case SpvSourceLanguageOpenCL_CPP : return "OpenCL_CPP"; case SpvSourceLanguageHLSL : return "HLSL"; case SpvSourceLanguageCPP_for_OpenCL : return "CPP_for_OpenCL"; + case SpvSourceLanguageSYCL : return "SYCL"; case SpvSourceLanguageMax: break; } diff --git a/thirdparty/spirv-reflect/spirv_reflect.h b/thirdparty/spirv-reflect/spirv_reflect.h index 948533d3c0..02850f8811 100644 --- a/thirdparty/spirv-reflect/spirv_reflect.h +++ b/thirdparty/spirv-reflect/spirv_reflect.h @@ -30,7 +30,12 @@ VERSION HISTORY #ifndef SPIRV_REFLECT_H #define SPIRV_REFLECT_H +#if defined(SPIRV_REFLECT_USE_SYSTEM_SPIRV_H) +#include <spirv/unified1/spirv.h> +#else #include "./include/spirv/unified1/spirv.h" +#endif + #include <stdint.h> #include <string.h> @@ -139,6 +144,7 @@ typedef enum SpvReflectDecorationFlagBits { SPV_REFLECT_DECORATION_FLAT = 0x00000040, SPV_REFLECT_DECORATION_NON_WRITABLE = 0x00000080, SPV_REFLECT_DECORATION_RELAXED_PRECISION = 0x00000100, + SPV_REFLECT_DECORATION_NON_READABLE = 0x00000200, } SpvReflectDecorationFlagBits; typedef uint32_t SpvReflectDecorationFlags; @@ -422,6 +428,8 @@ typedef struct SpvReflectDescriptorBinding { uint32_t binding; uint32_t set; } word_offset; + + SpvReflectDecorationFlags decoration_flags; } SpvReflectDescriptorBinding; /*! @struct SpvReflectDescriptorSet @@ -458,6 +466,9 @@ typedef struct SpvReflectEntryPoint { uint32_t used_push_constant_count; uint32_t* used_push_constants; + uint32_t execution_mode_count; + SpvExecutionMode* execution_modes; + struct LocalSize { uint32_t x; uint32_t y; |